Repository: surayashivji/PotterPics Branch: master Commit: ae306faf0e28 Files: 613 Total size: 39.1 MB Directory structure: gitextract_vs59aor5/ ├── .gitignore ├── Podfile ├── Pods/ │ ├── AFNetworking/ │ │ ├── AFNetworking/ │ │ │ ├── AFHTTPSessionManager.h │ │ │ ├── AFHTTPSessionManager.m │ │ │ ├── AFNetworkReachabilityManager.h │ │ │ ├── AFNetworkReachabilityManager.m │ │ │ ├── AFNetworking.h │ │ │ ├── AFSecurityPolicy.h │ │ │ ├── AFSecurityPolicy.m │ │ │ ├── AFURLRequestSerialization.h │ │ │ ├── AFURLRequestSerialization.m │ │ │ ├── AFURLResponseSerialization.h │ │ │ ├── AFURLResponseSerialization.m │ │ │ ├── AFURLSessionManager.h │ │ │ └── AFURLSessionManager.m │ │ ├── LICENSE │ │ ├── README.md │ │ └── UIKit+AFNetworking/ │ │ ├── AFAutoPurgingImageCache.h │ │ ├── AFAutoPurgingImageCache.m │ │ ├── AFImageDownloader.h │ │ ├── AFImageDownloader.m │ │ ├── AFNetworkActivityIndicatorManager.h │ │ ├── AFNetworkActivityIndicatorManager.m │ │ ├── UIActivityIndicatorView+AFNetworking.h │ │ ├── UIActivityIndicatorView+AFNetworking.m │ │ ├── UIButton+AFNetworking.h │ │ ├── UIButton+AFNetworking.m │ │ ├── UIImage+AFNetworking.h │ │ ├── UIImageView+AFNetworking.h │ │ ├── UIImageView+AFNetworking.m │ │ ├── UIKit+AFNetworking.h │ │ ├── UIProgressView+AFNetworking.h │ │ ├── UIProgressView+AFNetworking.m │ │ ├── UIRefreshControl+AFNetworking.h │ │ ├── UIRefreshControl+AFNetworking.m │ │ ├── UIWebView+AFNetworking.h │ │ └── UIWebView+AFNetworking.m │ ├── Bolts/ │ │ ├── Bolts/ │ │ │ ├── Common/ │ │ │ │ ├── BFCancellationToken.h │ │ │ │ ├── BFCancellationToken.m │ │ │ │ ├── BFCancellationTokenRegistration.h │ │ │ │ ├── BFCancellationTokenRegistration.m │ │ │ │ ├── BFCancellationTokenSource.h │ │ │ │ ├── BFCancellationTokenSource.m │ │ │ │ ├── BFExecutor.h │ │ │ │ ├── BFExecutor.m │ │ │ │ ├── BFTask+Exceptions.h │ │ │ │ ├── BFTask+Exceptions.m │ │ │ │ ├── BFTask.h │ │ │ │ ├── BFTask.m │ │ │ │ ├── BFTaskCompletionSource.h │ │ │ │ ├── BFTaskCompletionSource.m │ │ │ │ ├── Bolts.h │ │ │ │ └── Bolts.m │ │ │ └── iOS/ │ │ │ ├── BFAppLink.h │ │ │ ├── BFAppLink.m │ │ │ ├── BFAppLinkNavigation.h │ │ │ ├── BFAppLinkNavigation.m │ │ │ ├── BFAppLinkResolving.h │ │ │ ├── BFAppLinkReturnToRefererController.h │ │ │ ├── BFAppLinkReturnToRefererController.m │ │ │ ├── BFAppLinkReturnToRefererView.h │ │ │ ├── BFAppLinkReturnToRefererView.m │ │ │ ├── BFAppLinkTarget.h │ │ │ ├── BFAppLinkTarget.m │ │ │ ├── BFMeasurementEvent.h │ │ │ ├── BFMeasurementEvent.m │ │ │ ├── BFURL.h │ │ │ ├── BFURL.m │ │ │ ├── BFWebViewAppLinkResolver.h │ │ │ ├── BFWebViewAppLinkResolver.m │ │ │ └── Internal/ │ │ │ ├── BFAppLinkReturnToRefererView_Internal.h │ │ │ ├── BFAppLink_Internal.h │ │ │ ├── BFMeasurementEvent_Internal.h │ │ │ └── BFURL_Internal.h │ │ ├── LICENSE │ │ └── README.md │ ├── FBSDKCoreKit/ │ │ ├── FBSDKCoreKit/ │ │ │ └── FBSDKCoreKit/ │ │ │ ├── FBSDKAccessToken.h │ │ │ ├── FBSDKAccessToken.m │ │ │ ├── FBSDKAppEvents.h │ │ │ ├── FBSDKAppEvents.m │ │ │ ├── FBSDKAppLinkResolver.h │ │ │ ├── FBSDKAppLinkResolver.m │ │ │ ├── FBSDKAppLinkUtility.h │ │ │ ├── FBSDKAppLinkUtility.m │ │ │ ├── FBSDKApplicationDelegate.h │ │ │ ├── FBSDKApplicationDelegate.m │ │ │ ├── FBSDKButton.h │ │ │ ├── FBSDKButton.m │ │ │ ├── FBSDKConstants.h │ │ │ ├── FBSDKConstants.m │ │ │ ├── FBSDKCopying.h │ │ │ ├── FBSDKCoreKit.h │ │ │ ├── FBSDKGraphErrorRecoveryProcessor.h │ │ │ ├── FBSDKGraphErrorRecoveryProcessor.m │ │ │ ├── FBSDKGraphRequest.h │ │ │ ├── FBSDKGraphRequest.m │ │ │ ├── FBSDKGraphRequestConnection.h │ │ │ ├── FBSDKGraphRequestConnection.m │ │ │ ├── FBSDKGraphRequestDataAttachment.h │ │ │ ├── FBSDKGraphRequestDataAttachment.m │ │ │ ├── FBSDKMacros.h │ │ │ ├── FBSDKMutableCopying.h │ │ │ ├── FBSDKProfile.h │ │ │ ├── FBSDKProfile.m │ │ │ ├── FBSDKProfilePictureView.h │ │ │ ├── FBSDKProfilePictureView.m │ │ │ ├── FBSDKSettings.h │ │ │ ├── FBSDKSettings.m │ │ │ ├── FBSDKTestUsersManager.h │ │ │ ├── FBSDKTestUsersManager.m │ │ │ ├── FBSDKUtility.h │ │ │ ├── FBSDKUtility.m │ │ │ ├── Internal/ │ │ │ │ ├── AppEvents/ │ │ │ │ │ ├── FBSDKAppEvents+Internal.h │ │ │ │ │ ├── FBSDKAppEventsDeviceInfo.h │ │ │ │ │ ├── FBSDKAppEventsDeviceInfo.m │ │ │ │ │ ├── FBSDKAppEventsState.h │ │ │ │ │ ├── FBSDKAppEventsState.m │ │ │ │ │ ├── FBSDKAppEventsStateManager.h │ │ │ │ │ ├── FBSDKAppEventsStateManager.m │ │ │ │ │ ├── FBSDKAppEventsUtility.h │ │ │ │ │ ├── FBSDKAppEventsUtility.m │ │ │ │ │ ├── FBSDKPaymentObserver.h │ │ │ │ │ ├── FBSDKPaymentObserver.m │ │ │ │ │ ├── FBSDKTimeSpentData.h │ │ │ │ │ └── FBSDKTimeSpentData.m │ │ │ │ ├── AppLink/ │ │ │ │ │ ├── FBSDKBoltsMeasurementEventListener.h │ │ │ │ │ └── FBSDKBoltsMeasurementEventListener.m │ │ │ │ ├── Base64/ │ │ │ │ │ ├── FBSDKBase64.h │ │ │ │ │ └── FBSDKBase64.m │ │ │ │ ├── BridgeAPI/ │ │ │ │ │ ├── FBSDKBridgeAPICrypto.h │ │ │ │ │ ├── FBSDKBridgeAPICrypto.m │ │ │ │ │ ├── FBSDKBridgeAPIProtocol.h │ │ │ │ │ ├── FBSDKBridgeAPIProtocolType.h │ │ │ │ │ ├── FBSDKBridgeAPIRequest+Private.h │ │ │ │ │ ├── FBSDKBridgeAPIRequest.h │ │ │ │ │ ├── FBSDKBridgeAPIRequest.m │ │ │ │ │ ├── FBSDKBridgeAPIResponse.h │ │ │ │ │ ├── FBSDKBridgeAPIResponse.m │ │ │ │ │ ├── FBSDKURLOpening.h │ │ │ │ │ └── ProtocolVersions/ │ │ │ │ │ ├── FBSDKBridgeAPIProtocolNativeV1.h │ │ │ │ │ ├── FBSDKBridgeAPIProtocolNativeV1.m │ │ │ │ │ ├── FBSDKBridgeAPIProtocolWebV1.h │ │ │ │ │ ├── FBSDKBridgeAPIProtocolWebV1.m │ │ │ │ │ ├── FBSDKBridgeAPIProtocolWebV2.h │ │ │ │ │ └── FBSDKBridgeAPIProtocolWebV2.m │ │ │ │ ├── Cryptography/ │ │ │ │ │ ├── FBSDKCrypto.h │ │ │ │ │ └── FBSDKCrypto.m │ │ │ │ ├── ErrorRecovery/ │ │ │ │ │ ├── FBSDKErrorRecoveryAttempter.h │ │ │ │ │ ├── FBSDKErrorRecoveryAttempter.m │ │ │ │ │ ├── _FBSDKTemporaryErrorRecoveryAttempter.h │ │ │ │ │ └── _FBSDKTemporaryErrorRecoveryAttempter.m │ │ │ │ ├── FBSDKApplicationDelegate+Internal.h │ │ │ │ ├── FBSDKAudioResourceLoader.h │ │ │ │ ├── FBSDKAudioResourceLoader.m │ │ │ │ ├── FBSDKContainerViewController.h │ │ │ │ ├── FBSDKContainerViewController.m │ │ │ │ ├── FBSDKCoreKit+Internal.h │ │ │ │ ├── FBSDKDynamicFrameworkLoader.h │ │ │ │ ├── FBSDKError.h │ │ │ │ ├── FBSDKError.m │ │ │ │ ├── FBSDKInternalUtility.h │ │ │ │ ├── FBSDKInternalUtility.m │ │ │ │ ├── FBSDKLogger.h │ │ │ │ ├── FBSDKLogger.m │ │ │ │ ├── FBSDKMath.h │ │ │ │ ├── FBSDKMath.m │ │ │ │ ├── FBSDKMonotonicTime.h │ │ │ │ ├── FBSDKMonotonicTime.m │ │ │ │ ├── FBSDKProfile+Internal.h │ │ │ │ ├── FBSDKSettings+Internal.h │ │ │ │ ├── FBSDKSystemAccountStoreAdapter.h │ │ │ │ ├── FBSDKSystemAccountStoreAdapter.m │ │ │ │ ├── FBSDKTriStateBOOL.h │ │ │ │ ├── FBSDKTriStateBOOL.m │ │ │ │ ├── FBSDKTypeUtility.h │ │ │ │ ├── FBSDKTypeUtility.m │ │ │ │ ├── Network/ │ │ │ │ │ ├── FBSDKGraphRequest+Internal.h │ │ │ │ │ ├── FBSDKGraphRequestBody.h │ │ │ │ │ ├── FBSDKGraphRequestBody.m │ │ │ │ │ ├── FBSDKGraphRequestConnection+Internal.h │ │ │ │ │ ├── FBSDKGraphRequestMetadata.h │ │ │ │ │ ├── FBSDKGraphRequestMetadata.m │ │ │ │ │ ├── FBSDKGraphRequestPiggybackManager.h │ │ │ │ │ ├── FBSDKGraphRequestPiggybackManager.m │ │ │ │ │ ├── FBSDKURLConnection.h │ │ │ │ │ ├── FBSDKURLConnection.m │ │ │ │ │ ├── FBSDKURLSessionTask.h │ │ │ │ │ └── FBSDKURLSessionTask.m │ │ │ │ ├── ServerConfiguration/ │ │ │ │ │ ├── FBSDKDialogConfiguration.h │ │ │ │ │ ├── FBSDKDialogConfiguration.m │ │ │ │ │ ├── FBSDKErrorConfiguration.h │ │ │ │ │ ├── FBSDKErrorConfiguration.m │ │ │ │ │ ├── FBSDKErrorRecoveryConfiguration.h │ │ │ │ │ ├── FBSDKErrorRecoveryConfiguration.m │ │ │ │ │ ├── FBSDKServerConfiguration+Internal.h │ │ │ │ │ ├── FBSDKServerConfiguration.h │ │ │ │ │ ├── FBSDKServerConfiguration.m │ │ │ │ │ ├── FBSDKServerConfigurationManager+Internal.h │ │ │ │ │ ├── FBSDKServerConfigurationManager.h │ │ │ │ │ └── FBSDKServerConfigurationManager.m │ │ │ │ ├── TokenCaching/ │ │ │ │ │ ├── FBSDKAccessTokenCache.h │ │ │ │ │ ├── FBSDKAccessTokenCache.m │ │ │ │ │ ├── FBSDKAccessTokenCacheV3.h │ │ │ │ │ ├── FBSDKAccessTokenCacheV3.m │ │ │ │ │ ├── FBSDKAccessTokenCacheV3_17.h │ │ │ │ │ ├── FBSDKAccessTokenCacheV3_17.m │ │ │ │ │ ├── FBSDKAccessTokenCacheV3_21.h │ │ │ │ │ ├── FBSDKAccessTokenCacheV3_21.m │ │ │ │ │ ├── FBSDKAccessTokenCacheV4.h │ │ │ │ │ ├── FBSDKAccessTokenCacheV4.m │ │ │ │ │ ├── FBSDKAccessTokenCaching.h │ │ │ │ │ ├── FBSDKKeychainStore.h │ │ │ │ │ ├── FBSDKKeychainStore.m │ │ │ │ │ ├── FBSDKKeychainStoreViaBundleID.h │ │ │ │ │ └── FBSDKKeychainStoreViaBundleID.m │ │ │ │ ├── UI/ │ │ │ │ │ ├── FBSDKButton+Subclass.h │ │ │ │ │ ├── FBSDKCloseIcon.h │ │ │ │ │ ├── FBSDKCloseIcon.m │ │ │ │ │ ├── FBSDKColor.h │ │ │ │ │ ├── FBSDKColor.m │ │ │ │ │ ├── FBSDKIcon.h │ │ │ │ │ ├── FBSDKIcon.m │ │ │ │ │ ├── FBSDKLogo.h │ │ │ │ │ ├── FBSDKLogo.m │ │ │ │ │ ├── FBSDKMaleSilhouetteIcon.h │ │ │ │ │ ├── FBSDKMaleSilhouetteIcon.m │ │ │ │ │ ├── FBSDKUIUtility.h │ │ │ │ │ ├── FBSDKViewImpressionTracker.h │ │ │ │ │ └── FBSDKViewImpressionTracker.m │ │ │ │ └── WebDialog/ │ │ │ │ ├── FBSDKWebDialog.h │ │ │ │ ├── FBSDKWebDialog.m │ │ │ │ ├── FBSDKWebDialogView.h │ │ │ │ └── FBSDKWebDialogView.m │ │ │ └── Internal_NoARC/ │ │ │ └── FBSDKDynamicFrameworkLoader.m │ │ ├── FacebookSDKStrings.bundle/ │ │ │ └── Resources/ │ │ │ ├── af.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── ar.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── bn.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── cs.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── da.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── de.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── el.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── en.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── en_GB.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── es.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── es_ES.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── fi.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── fil.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── fr.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── gu.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── he.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── hi.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── hr.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── hu.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── id.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── it.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── ja.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── kn.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── ko.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── ml.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── mr.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── ms.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── nb.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── nl.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── pa.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── pl.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── pt.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── pt_PT.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── ru.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── sk.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── sv.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── ta.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── te.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── th.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── tr.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── vi.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── zh.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ ├── zh_Hant_HK.lproj/ │ │ │ │ └── FacebookSDK.strings │ │ │ └── zh_Hant_TW.lproj/ │ │ │ └── FacebookSDK.strings │ │ ├── LICENSE │ │ └── README.mdown │ ├── FBSDKLoginKit/ │ │ ├── FBSDKLoginKit/ │ │ │ └── FBSDKLoginKit/ │ │ │ ├── FBSDKLoginButton.h │ │ │ ├── FBSDKLoginButton.m │ │ │ ├── FBSDKLoginConstants.h │ │ │ ├── FBSDKLoginConstants.m │ │ │ ├── FBSDKLoginKit.h │ │ │ ├── FBSDKLoginManager.h │ │ │ ├── FBSDKLoginManager.m │ │ │ ├── FBSDKLoginManagerLoginResult.h │ │ │ ├── FBSDKLoginManagerLoginResult.m │ │ │ ├── FBSDKLoginTooltipView.h │ │ │ ├── FBSDKLoginTooltipView.m │ │ │ ├── FBSDKTooltipView.h │ │ │ ├── FBSDKTooltipView.m │ │ │ └── Internal/ │ │ │ ├── FBSDKLoginCompletion+Internal.h │ │ │ ├── FBSDKLoginCompletion.h │ │ │ ├── FBSDKLoginCompletion.m │ │ │ ├── FBSDKLoginError.h │ │ │ ├── FBSDKLoginError.m │ │ │ ├── FBSDKLoginKit+Internal.h │ │ │ ├── FBSDKLoginManager+Internal.h │ │ │ ├── FBSDKLoginManagerLogger.h │ │ │ ├── FBSDKLoginManagerLogger.m │ │ │ ├── FBSDKLoginManagerLoginResult+Internal.h │ │ │ ├── FBSDKLoginUtility.h │ │ │ ├── FBSDKLoginUtility.m │ │ │ ├── _FBSDKLoginRecoveryAttempter.h │ │ │ └── _FBSDKLoginRecoveryAttempter.m │ │ ├── LICENSE │ │ └── README.mdown │ ├── FBSDKShareKit/ │ │ ├── FBSDKShareKit/ │ │ │ └── FBSDKShareKit/ │ │ │ ├── FBSDKAppGroupAddDialog.h │ │ │ ├── FBSDKAppGroupAddDialog.m │ │ │ ├── FBSDKAppGroupContent.h │ │ │ ├── FBSDKAppGroupContent.m │ │ │ ├── FBSDKAppGroupJoinDialog.h │ │ │ ├── FBSDKAppGroupJoinDialog.m │ │ │ ├── FBSDKAppInviteContent.h │ │ │ ├── FBSDKAppInviteContent.m │ │ │ ├── FBSDKAppInviteDialog.h │ │ │ ├── FBSDKAppInviteDialog.m │ │ │ ├── FBSDKGameRequestContent.h │ │ │ ├── FBSDKGameRequestContent.m │ │ │ ├── FBSDKGameRequestDialog.h │ │ │ ├── FBSDKGameRequestDialog.m │ │ │ ├── FBSDKHashtag.h │ │ │ ├── FBSDKHashtag.m │ │ │ ├── FBSDKLikeButton.h │ │ │ ├── FBSDKLikeButton.m │ │ │ ├── FBSDKLikeControl.h │ │ │ ├── FBSDKLikeControl.m │ │ │ ├── FBSDKLikeObjectType.h │ │ │ ├── FBSDKLikeObjectType.m │ │ │ ├── FBSDKLiking.h │ │ │ ├── FBSDKMessageDialog.h │ │ │ ├── FBSDKMessageDialog.m │ │ │ ├── FBSDKSendButton.h │ │ │ ├── FBSDKSendButton.m │ │ │ ├── FBSDKShareAPI.h │ │ │ ├── FBSDKShareAPI.m │ │ │ ├── FBSDKShareButton.h │ │ │ ├── FBSDKShareButton.m │ │ │ ├── FBSDKShareConstants.h │ │ │ ├── FBSDKShareConstants.m │ │ │ ├── FBSDKShareDialog.h │ │ │ ├── FBSDKShareDialog.m │ │ │ ├── FBSDKShareDialogMode.h │ │ │ ├── FBSDKShareDialogMode.m │ │ │ ├── FBSDKShareKit.h │ │ │ ├── FBSDKShareLinkContent.h │ │ │ ├── FBSDKShareLinkContent.m │ │ │ ├── FBSDKShareMediaContent.h │ │ │ ├── FBSDKShareMediaContent.m │ │ │ ├── FBSDKShareOpenGraphAction.h │ │ │ ├── FBSDKShareOpenGraphAction.m │ │ │ ├── FBSDKShareOpenGraphContent.h │ │ │ ├── FBSDKShareOpenGraphContent.m │ │ │ ├── FBSDKShareOpenGraphObject.h │ │ │ ├── FBSDKShareOpenGraphObject.m │ │ │ ├── FBSDKShareOpenGraphValueContainer.h │ │ │ ├── FBSDKShareOpenGraphValueContainer.m │ │ │ ├── FBSDKSharePhoto.h │ │ │ ├── FBSDKSharePhoto.m │ │ │ ├── FBSDKSharePhotoContent.h │ │ │ ├── FBSDKSharePhotoContent.m │ │ │ ├── FBSDKShareVideo.h │ │ │ ├── FBSDKShareVideo.m │ │ │ ├── FBSDKShareVideoContent.h │ │ │ ├── FBSDKShareVideoContent.m │ │ │ ├── FBSDKSharing.h │ │ │ ├── FBSDKSharingButton.h │ │ │ ├── FBSDKSharingContent.h │ │ │ └── Internal/ │ │ │ ├── FBSDKCheckmarkIcon.h │ │ │ ├── FBSDKCheckmarkIcon.m │ │ │ ├── FBSDKGameRequestFrictionlessRecipientCache.h │ │ │ ├── FBSDKGameRequestFrictionlessRecipientCache.m │ │ │ ├── FBSDKLikeActionController.h │ │ │ ├── FBSDKLikeActionController.m │ │ │ ├── FBSDKLikeActionControllerCache.h │ │ │ ├── FBSDKLikeActionControllerCache.m │ │ │ ├── FBSDKLikeBoxBorderView.h │ │ │ ├── FBSDKLikeBoxBorderView.m │ │ │ ├── FBSDKLikeBoxView.h │ │ │ ├── FBSDKLikeBoxView.m │ │ │ ├── FBSDKLikeButton+Internal.h │ │ │ ├── FBSDKLikeButtonPopWAV.h │ │ │ ├── FBSDKLikeButtonPopWAV.m │ │ │ ├── FBSDKLikeControl+Internal.h │ │ │ ├── FBSDKLikeDialog.h │ │ │ ├── FBSDKLikeDialog.m │ │ │ ├── FBSDKMessengerIcon.h │ │ │ ├── FBSDKMessengerIcon.m │ │ │ ├── FBSDKShareDefines.h │ │ │ ├── FBSDKShareError.h │ │ │ ├── FBSDKShareError.m │ │ │ ├── FBSDKShareKit+Internal.h │ │ │ ├── FBSDKShareLinkContent+Internal.h │ │ │ ├── FBSDKShareOpenGraphValueContainer+Internal.h │ │ │ ├── FBSDKShareUtility.h │ │ │ ├── FBSDKShareUtility.m │ │ │ ├── FBSDKVideoUploader.h │ │ │ └── FBSDKVideoUploader.m │ │ ├── LICENSE │ │ └── README.mdown │ ├── Firebase/ │ │ ├── Core/ │ │ │ └── Sources/ │ │ │ ├── Firebase.h │ │ │ └── module.modulemap │ │ └── README.md │ ├── FirebaseAnalytics/ │ │ └── Frameworks/ │ │ └── frameworks/ │ │ └── FirebaseAnalytics.framework/ │ │ ├── FirebaseAnalytics │ │ ├── Headers/ │ │ │ ├── FIRAnalytics+AppDelegate.h │ │ │ ├── FIRAnalytics.h │ │ │ ├── FIRAnalyticsConfiguration.h │ │ │ ├── FIRApp.h │ │ │ ├── FIRConfiguration.h │ │ │ ├── FIREventNames.h │ │ │ ├── FIROptions.h │ │ │ ├── FIRParameterNames.h │ │ │ ├── FIRUserPropertyNames.h │ │ │ └── FirebaseAnalytics.h │ │ └── Modules/ │ │ └── module.modulemap │ ├── FirebaseAuth/ │ │ ├── CHANGELOG.md │ │ ├── Frameworks/ │ │ │ └── frameworks/ │ │ │ └── FirebaseAuth.framework/ │ │ │ ├── FirebaseAuth │ │ │ ├── Headers/ │ │ │ │ ├── FIRAuth.h │ │ │ │ ├── FIRAuthCredential.h │ │ │ │ ├── FIRAuthErrors.h │ │ │ │ ├── FIREmailPasswordAuthProvider.h │ │ │ │ ├── FIRFacebookAuthProvider.h │ │ │ │ ├── FIRGitHubAuthProvider.h │ │ │ │ ├── FIRGoogleAuthProvider.h │ │ │ │ ├── FIRTwitterAuthProvider.h │ │ │ │ ├── FIRUser.h │ │ │ │ ├── FIRUserInfo.h │ │ │ │ └── FirebaseAuth.h │ │ │ └── Modules/ │ │ │ └── module.modulemap │ │ └── README.md │ ├── FirebaseCore/ │ │ └── Frameworks/ │ │ └── frameworks/ │ │ └── FirebaseCore.framework/ │ │ ├── FirebaseCore │ │ ├── Headers/ │ │ │ ├── FIRAnalyticsConfiguration.h │ │ │ ├── FIRApp.h │ │ │ ├── FIRConfiguration.h │ │ │ ├── FIROptions.h │ │ │ └── FirebaseCore.h │ │ └── Modules/ │ │ └── module.modulemap │ ├── FirebaseDatabase/ │ │ └── Frameworks/ │ │ └── FirebaseDatabase.framework/ │ │ ├── FirebaseDatabase │ │ ├── Headers/ │ │ │ ├── FIRDataEventType.h │ │ │ ├── FIRDataSnapshot.h │ │ │ ├── FIRDatabase.h │ │ │ ├── FIRDatabaseQuery.h │ │ │ ├── FIRDatabaseReference.h │ │ │ ├── FIRMutableData.h │ │ │ ├── FIRServerValue.h │ │ │ ├── FIRTransactionResult.h │ │ │ └── FirebaseDatabase.h │ │ ├── Info.plist │ │ ├── Modules/ │ │ │ └── module.modulemap │ │ └── NOTICE │ ├── FirebaseInstanceID/ │ │ ├── Frameworks/ │ │ │ └── frameworks/ │ │ │ └── FirebaseInstanceID.framework/ │ │ │ ├── FirebaseInstanceID │ │ │ ├── Headers/ │ │ │ │ ├── FIRInstanceID.h │ │ │ │ └── FirebaseInstanceID.h │ │ │ └── Modules/ │ │ │ └── module.modulemap │ │ └── Sources/ │ │ └── FIRInstanceID.h │ ├── FirebaseStorage/ │ │ └── Frameworks/ │ │ └── frameworks/ │ │ └── FirebaseStorage.framework/ │ │ ├── FirebaseStorage │ │ ├── Headers/ │ │ │ ├── FIRStorage.h │ │ │ ├── FIRStorageConstants.h │ │ │ ├── FIRStorageDownloadTask.h │ │ │ ├── FIRStorageMetadata.h │ │ │ ├── FIRStorageObservableTask.h │ │ │ ├── FIRStorageReference.h │ │ │ ├── FIRStorageTask.h │ │ │ ├── FIRStorageTaskSnapshot.h │ │ │ ├── FIRStorageUploadTask.h │ │ │ └── FirebaseStorage.h │ │ └── Modules/ │ │ └── module.modulemap │ ├── GoogleInterchangeUtilities/ │ │ └── Frameworks/ │ │ └── frameworks/ │ │ └── GoogleInterchangeUtilities.framework/ │ │ └── GoogleInterchangeUtilities │ ├── GoogleNetworkingUtilities/ │ │ └── Frameworks/ │ │ └── frameworks/ │ │ └── GoogleNetworkingUtilities.framework/ │ │ └── GoogleNetworkingUtilities │ ├── GoogleSymbolUtilities/ │ │ └── Frameworks/ │ │ └── frameworks/ │ │ └── GoogleSymbolUtilities.framework/ │ │ └── GoogleSymbolUtilities │ ├── GoogleUtilities/ │ │ └── Frameworks/ │ │ └── frameworks/ │ │ └── GoogleUtilities.framework/ │ │ └── GoogleUtilities │ ├── MBProgressHUD/ │ │ ├── LICENSE │ │ ├── MBProgressHUD.h │ │ ├── MBProgressHUD.m │ │ └── README.mdown │ ├── Pods.xcodeproj/ │ │ └── project.pbxproj │ ├── SwiftyJSON/ │ │ ├── LICENSE │ │ ├── README.md │ │ └── Source/ │ │ └── SwiftyJSON.swift │ └── Target Support Files/ │ ├── AFNetworking/ │ │ ├── AFNetworking-dummy.m │ │ ├── AFNetworking-prefix.pch │ │ ├── AFNetworking-umbrella.h │ │ ├── AFNetworking.modulemap │ │ ├── AFNetworking.xcconfig │ │ └── Info.plist │ ├── Bolts/ │ │ ├── Bolts-dummy.m │ │ ├── Bolts-prefix.pch │ │ ├── Bolts-umbrella.h │ │ ├── Bolts.modulemap │ │ ├── Bolts.xcconfig │ │ └── Info.plist │ ├── FBSDKCoreKit/ │ │ ├── FBSDKCoreKit-dummy.m │ │ ├── FBSDKCoreKit-prefix.pch │ │ ├── FBSDKCoreKit-umbrella.h │ │ ├── FBSDKCoreKit.modulemap │ │ ├── FBSDKCoreKit.xcconfig │ │ └── Info.plist │ ├── FBSDKLoginKit/ │ │ ├── FBSDKLoginKit-dummy.m │ │ ├── FBSDKLoginKit-prefix.pch │ │ ├── FBSDKLoginKit-umbrella.h │ │ ├── FBSDKLoginKit.modulemap │ │ ├── FBSDKLoginKit.xcconfig │ │ └── Info.plist │ ├── FBSDKShareKit/ │ │ ├── FBSDKShareKit-dummy.m │ │ ├── FBSDKShareKit-prefix.pch │ │ ├── FBSDKShareKit-umbrella.h │ │ ├── FBSDKShareKit.modulemap │ │ ├── FBSDKShareKit.xcconfig │ │ └── Info.plist │ ├── MBProgressHUD/ │ │ ├── Info.plist │ │ ├── MBProgressHUD-dummy.m │ │ ├── MBProgressHUD-prefix.pch │ │ ├── MBProgressHUD-umbrella.h │ │ ├── MBProgressHUD.modulemap │ │ └── MBProgressHUD.xcconfig │ ├── Pods-PotterPics/ │ │ ├── Info.plist │ │ ├── Pods-PotterPics-acknowledgements.markdown │ │ ├── Pods-PotterPics-acknowledgements.plist │ │ ├── Pods-PotterPics-dummy.m │ │ ├── Pods-PotterPics-frameworks.sh │ │ ├── Pods-PotterPics-resources.sh │ │ ├── Pods-PotterPics-umbrella.h │ │ ├── Pods-PotterPics.debug.xcconfig │ │ ├── Pods-PotterPics.modulemap │ │ └── Pods-PotterPics.release.xcconfig │ ├── Pods-PotterPicsTests/ │ │ ├── Info.plist │ │ ├── Pods-PotterPicsTests-acknowledgements.markdown │ │ ├── Pods-PotterPicsTests-acknowledgements.plist │ │ ├── Pods-PotterPicsTests-dummy.m │ │ ├── Pods-PotterPicsTests-frameworks.sh │ │ ├── Pods-PotterPicsTests-resources.sh │ │ ├── Pods-PotterPicsTests-umbrella.h │ │ ├── Pods-PotterPicsTests.debug.xcconfig │ │ ├── Pods-PotterPicsTests.modulemap │ │ └── Pods-PotterPicsTests.release.xcconfig │ ├── Pods-PotterPicsUITests/ │ │ ├── Info.plist │ │ ├── Pods-PotterPicsUITests-acknowledgements.markdown │ │ ├── Pods-PotterPicsUITests-acknowledgements.plist │ │ ├── Pods-PotterPicsUITests-dummy.m │ │ ├── Pods-PotterPicsUITests-frameworks.sh │ │ ├── Pods-PotterPicsUITests-resources.sh │ │ ├── Pods-PotterPicsUITests-umbrella.h │ │ ├── Pods-PotterPicsUITests.debug.xcconfig │ │ ├── Pods-PotterPicsUITests.modulemap │ │ └── Pods-PotterPicsUITests.release.xcconfig │ └── SwiftyJSON/ │ ├── Info.plist │ ├── SwiftyJSON-dummy.m │ ├── SwiftyJSON-prefix.pch │ ├── SwiftyJSON-umbrella.h │ ├── SwiftyJSON.modulemap │ └── SwiftyJSON.xcconfig ├── PotterPics/ │ ├── AppDelegate.swift │ ├── Assets.xcassets/ │ │ ├── AppIcon.appiconset/ │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── GfeedDark.imageset/ │ │ │ └── Contents.json │ │ ├── GpostDark.imageset/ │ │ │ └── Contents.json │ │ ├── GprofileDark.imageset/ │ │ │ └── Contents.json │ │ ├── GsearchDark.imageset/ │ │ │ └── Contents.json │ │ ├── HfeedDark.imageset/ │ │ │ └── Contents.json │ │ ├── HpostDark.imageset/ │ │ │ └── Contents.json │ │ ├── HprofileDark.imageset/ │ │ │ └── Contents.json │ │ ├── HsearchDark.imageset/ │ │ │ └── Contents.json │ │ ├── RfeedDark.imageset/ │ │ │ └── Contents.json │ │ ├── RpostDark.imageset/ │ │ │ └── Contents.json │ │ ├── RprofileDark.imageset/ │ │ │ └── Contents.json │ │ ├── RsearchDark.imageset/ │ │ │ └── Contents.json │ │ ├── SfeedDark.imageset/ │ │ │ └── Contents.json │ │ ├── SpostDark.imageset/ │ │ │ └── Contents.json │ │ ├── SprofileDark.imageset/ │ │ │ └── Contents.json │ │ ├── SsearchDark.imageset/ │ │ │ └── Contents.json │ │ ├── cancel.imageset/ │ │ │ └── Contents.json │ │ ├── facebook.imageset/ │ │ │ └── Contents.json │ │ ├── feed.imageset/ │ │ │ └── Contents.json │ │ ├── logout.imageset/ │ │ │ └── Contents.json │ │ ├── nav_more_icon.imageset/ │ │ │ └── Contents.json │ │ ├── post.imageset/ │ │ │ └── Contents.json │ │ ├── profile.imageset/ │ │ │ └── Contents.json │ │ └── search.imageset/ │ │ └── Contents.json │ ├── BackgroundVideo.swift │ ├── Base.lproj/ │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── CameraViewController.swift │ ├── ColorPalette.swift │ ├── Extensions.swift │ ├── FilterCollectionViewCell.swift │ ├── GlobalVariables.swift │ ├── GoogleService-Info.plist │ ├── HomeButton.swift │ ├── HomeViewController.swift │ ├── Info.plist │ ├── MainViewController.swift │ ├── NavVC.swift │ ├── Post.swift │ ├── PostFeedTableViewCell.swift │ ├── PostFeedViewController.swift │ ├── PostViewController.swift │ ├── PotterPics.entitlements │ ├── ProfileTableViewCell.swift │ ├── ProfileViewController.swift │ ├── SearchTableViewCell.swift │ ├── SearchViewController.swift │ ├── TabBar.swift │ └── User.swift ├── PotterPics.xcodeproj/ │ ├── project.pbxproj │ └── project.xcworkspace/ │ └── contents.xcworkspacedata ├── PotterPics.xcworkspace/ │ └── contents.xcworkspacedata ├── PotterPicsTests/ │ ├── Info.plist │ └── PotterPicsTests.swift ├── PotterPicsUITests/ │ ├── Info.plist │ └── PotterPicsUITests.swift └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Xcode ## Build generated build/ DerivedData/ ## Settings *.pbxuser !default.pbxuser *.mode1v3 !default.mode1v3 *.mode2v3 !default.mode2v3 *.perspectivev3 !default.perspectivev3 xcuserdata/ ## Other *.moved-aside *.xccheckout *.xcscmblueprint ================================================ FILE: Podfile ================================================ # Uncomment this line to define a global platform for your project # platform :ios, '9.0' target 'PotterPics' do # Comment this line if you're not using Swift and don't want to use dynamic frameworks use_frameworks! # Pods for PotterPics pod 'Firebase/Auth' pod 'Firebase/Core' pod 'Firebase/Storage' pod 'Firebase/Database' pod 'FBSDKCoreKit' pod 'FBSDKLoginKit' pod 'FBSDKShareKit' pod 'SwiftyJSON' pod 'AFNetworking' pod 'MBProgressHUD' target 'PotterPicsTests' do inherit! :search_paths # Pods for testing end target 'PotterPicsUITests' do inherit! :search_paths # Pods for testing end end ================================================ FILE: Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.h ================================================ // AFHTTPSessionManager.h // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #if !TARGET_OS_WATCH #import #endif #import #if TARGET_OS_IOS || TARGET_OS_WATCH || TARGET_OS_TV #import #else #import #endif #import "AFURLSessionManager.h" /** `AFHTTPSessionManager` is a subclass of `AFURLSessionManager` with convenience methods for making HTTP requests. When a `baseURL` is provided, requests made with the `GET` / `POST` / et al. convenience methods can be made with relative paths. ## Subclassing Notes Developers targeting iOS 7 or Mac OS X 10.9 or later that deal extensively with a web service are encouraged to subclass `AFHTTPSessionManager`, providing a class method that returns a shared singleton object on which authentication and other configuration can be shared across the application. For developers targeting iOS 6 or Mac OS X 10.8 or earlier, `AFHTTPRequestOperationManager` may be used to similar effect. ## Methods to Override To change the behavior of all data task operation construction, which is also used in the `GET` / `POST` / et al. convenience methods, override `dataTaskWithRequest:completionHandler:`. ## Serialization Requests created by an HTTP client will contain default headers and encode parameters according to the `requestSerializer` property, which is an object conforming to ``. Responses received from the server are automatically validated and serialized by the `responseSerializers` property, which is an object conforming to `` ## URL Construction Using Relative Paths For HTTP convenience methods, the request serializer constructs URLs from the path relative to the `-baseURL`, using `NSURL +URLWithString:relativeToURL:`, when provided. If `baseURL` is `nil`, `path` needs to resolve to a valid `NSURL` object using `NSURL +URLWithString:`. Below are a few examples of how `baseURL` and relative paths interact: NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"]; [NSURL URLWithString:@"foo" relativeToURL:baseURL]; // http://example.com/v1/foo [NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL]; // http://example.com/v1/foo?bar=baz [NSURL URLWithString:@"/foo" relativeToURL:baseURL]; // http://example.com/foo [NSURL URLWithString:@"foo/" relativeToURL:baseURL]; // http://example.com/v1/foo [NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; // http://example.com/foo/ [NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/ Also important to note is that a trailing slash will be added to any `baseURL` without one. This would otherwise cause unexpected behavior when constructing URLs using paths without a leading slash. @warning Managers for background sessions must be owned for the duration of their use. This can be accomplished by creating an application-wide or shared singleton instance. */ NS_ASSUME_NONNULL_BEGIN @interface AFHTTPSessionManager : AFURLSessionManager /** The URL used to construct requests from relative paths in methods like `requestWithMethod:URLString:parameters:`, and the `GET` / `POST` / et al. convenience methods. */ @property (readonly, nonatomic, strong, nullable) NSURL *baseURL; /** Requests created with `requestWithMethod:URLString:parameters:` & `multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:` are constructed with a set of default headers using a parameter serialization specified by this property. By default, this is set to an instance of `AFHTTPRequestSerializer`, which serializes query string parameters for `GET`, `HEAD`, and `DELETE` requests, or otherwise URL-form-encodes HTTP message bodies. @warning `requestSerializer` must not be `nil`. */ @property (nonatomic, strong) AFHTTPRequestSerializer * requestSerializer; /** Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an instance of `AFJSONResponseSerializer`. @warning `responseSerializer` must not be `nil`. */ @property (nonatomic, strong) AFHTTPResponseSerializer * responseSerializer; ///--------------------- /// @name Initialization ///--------------------- /** Creates and returns an `AFHTTPSessionManager` object. */ + (instancetype)manager; /** Initializes an `AFHTTPSessionManager` object with the specified base URL. @param url The base URL for the HTTP client. @return The newly-initialized HTTP client */ - (instancetype)initWithBaseURL:(nullable NSURL *)url; /** Initializes an `AFHTTPSessionManager` object with the specified base URL. This is the designated initializer. @param url The base URL for the HTTP client. @param configuration The configuration used to create the managed session. @return The newly-initialized HTTP client */ - (instancetype)initWithBaseURL:(nullable NSURL *)url sessionConfiguration:(nullable NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER; ///--------------------------- /// @name Making HTTP Requests ///--------------------------- /** Creates and runs an `NSURLSessionDataTask` with a `GET` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */ - (nullable NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE; /** Creates and runs an `NSURLSessionDataTask` with a `GET` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param downloadProgress A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler: */ - (nullable NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(nullable id)parameters progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; /** Creates and runs an `NSURLSessionDataTask` with a `HEAD` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes a single arguments: the data task. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */ - (nullable NSURLSessionDataTask *)HEAD:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; /** Creates and runs an `NSURLSessionDataTask` with a `POST` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */ - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE; /** Creates and runs an `NSURLSessionDataTask` with a `POST` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param uploadProgress A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler: */ - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; /** Creates and runs an `NSURLSessionDataTask` with a multipart `POST` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */ - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters constructingBodyWithBlock:(nullable void (^)(id formData))block success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE; /** Creates and runs an `NSURLSessionDataTask` with a multipart `POST` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. @param uploadProgress A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler: */ - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters constructingBodyWithBlock:(nullable void (^)(id formData))block progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; /** Creates and runs an `NSURLSessionDataTask` with a `PUT` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */ - (nullable NSURLSessionDataTask *)PUT:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; /** Creates and runs an `NSURLSessionDataTask` with a `PATCH` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */ - (nullable NSURLSessionDataTask *)PATCH:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; /** Creates and runs an `NSURLSessionDataTask` with a `DELETE` request. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded according to the client request serializer. @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. @see -dataTaskWithRequest:completionHandler: */ - (nullable NSURLSessionDataTask *)DELETE:(NSString *)URLString parameters:(nullable id)parameters success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.m ================================================ // AFHTTPSessionManager.m // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "AFHTTPSessionManager.h" #import "AFURLRequestSerialization.h" #import "AFURLResponseSerialization.h" #import #import #import #import #import #import #import #import #if TARGET_OS_IOS || TARGET_OS_TV #import #elif TARGET_OS_WATCH #import #endif @interface AFHTTPSessionManager () @property (readwrite, nonatomic, strong) NSURL *baseURL; @end @implementation AFHTTPSessionManager @dynamic responseSerializer; + (instancetype)manager { return [[[self class] alloc] initWithBaseURL:nil]; } - (instancetype)init { return [self initWithBaseURL:nil]; } - (instancetype)initWithBaseURL:(NSURL *)url { return [self initWithBaseURL:url sessionConfiguration:nil]; } - (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration { return [self initWithBaseURL:nil sessionConfiguration:configuration]; } - (instancetype)initWithBaseURL:(NSURL *)url sessionConfiguration:(NSURLSessionConfiguration *)configuration { self = [super initWithSessionConfiguration:configuration]; if (!self) { return nil; } // Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) { url = [url URLByAppendingPathComponent:@""]; } self.baseURL = url; self.requestSerializer = [AFHTTPRequestSerializer serializer]; self.responseSerializer = [AFJSONResponseSerializer serializer]; return self; } #pragma mark - - (void)setRequestSerializer:(AFHTTPRequestSerializer *)requestSerializer { NSParameterAssert(requestSerializer); _requestSerializer = requestSerializer; } - (void)setResponseSerializer:(AFHTTPResponseSerializer *)responseSerializer { NSParameterAssert(responseSerializer); [super setResponseSerializer:responseSerializer]; } #pragma mark - - (NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { return [self GET:URLString parameters:parameters progress:nil success:success failure:failure]; } - (NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(id)parameters progress:(void (^)(NSProgress * _Nonnull))downloadProgress success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure { NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:downloadProgress success:success failure:failure]; [dataTask resume]; return dataTask; } - (NSURLSessionDataTask *)HEAD:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"HEAD" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:^(NSURLSessionDataTask *task, __unused id responseObject) { if (success) { success(task); } } failure:failure]; [dataTask resume]; return dataTask; } - (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { return [self POST:URLString parameters:parameters progress:nil success:success failure:failure]; } - (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters progress:(void (^)(NSProgress * _Nonnull))uploadProgress success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure { NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters uploadProgress:uploadProgress downloadProgress:nil success:success failure:failure]; [dataTask resume]; return dataTask; } - (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(nullable id)parameters constructingBodyWithBlock:(nullable void (^)(id _Nonnull))block success:(nullable void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure { return [self POST:URLString parameters:parameters constructingBodyWithBlock:block progress:nil success:success failure:failure]; } - (NSURLSessionDataTask *)POST:(NSString *)URLString parameters:(id)parameters constructingBodyWithBlock:(void (^)(id formData))block progress:(nullable void (^)(NSProgress * _Nonnull))uploadProgress success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSError *serializationError = nil; NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError]; if (serializationError) { if (failure) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{ failure(nil, serializationError); }); #pragma clang diagnostic pop } return nil; } __block NSURLSessionDataTask *task = [self uploadTaskWithStreamedRequest:request progress:uploadProgress completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { if (error) { if (failure) { failure(task, error); } } else { if (success) { success(task, responseObject); } } }]; [task resume]; return task; } - (NSURLSessionDataTask *)PUT:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PUT" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure]; [dataTask resume]; return dataTask; } - (NSURLSessionDataTask *)PATCH:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PATCH" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure]; [dataTask resume]; return dataTask; } - (NSURLSessionDataTask *)DELETE:(NSString *)URLString parameters:(id)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure { NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"DELETE" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure]; [dataTask resume]; return dataTask; } - (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method URLString:(NSString *)URLString parameters:(id)parameters uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress success:(void (^)(NSURLSessionDataTask *, id))success failure:(void (^)(NSURLSessionDataTask *, NSError *))failure { NSError *serializationError = nil; NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError]; if (serializationError) { if (failure) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{ failure(nil, serializationError); }); #pragma clang diagnostic pop } return nil; } __block NSURLSessionDataTask *dataTask = nil; dataTask = [self dataTaskWithRequest:request uploadProgress:uploadProgress downloadProgress:downloadProgress completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { if (error) { if (failure) { failure(dataTask, error); } } else { if (success) { success(dataTask, responseObject); } } }]; return dataTask; } #pragma mark - NSObject - (NSString *)description { return [NSString stringWithFormat:@"<%@: %p, baseURL: %@, session: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.session, self.operationQueue]; } #pragma mark - NSSecureCoding + (BOOL)supportsSecureCoding { return YES; } - (instancetype)initWithCoder:(NSCoder *)decoder { NSURL *baseURL = [decoder decodeObjectOfClass:[NSURL class] forKey:NSStringFromSelector(@selector(baseURL))]; NSURLSessionConfiguration *configuration = [decoder decodeObjectOfClass:[NSURLSessionConfiguration class] forKey:@"sessionConfiguration"]; if (!configuration) { NSString *configurationIdentifier = [decoder decodeObjectOfClass:[NSString class] forKey:@"identifier"]; if (configurationIdentifier) { #if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1100) configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:configurationIdentifier]; #else configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:configurationIdentifier]; #endif } } self = [self initWithBaseURL:baseURL sessionConfiguration:configuration]; if (!self) { return nil; } self.requestSerializer = [decoder decodeObjectOfClass:[AFHTTPRequestSerializer class] forKey:NSStringFromSelector(@selector(requestSerializer))]; self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))]; AFSecurityPolicy *decodedPolicy = [decoder decodeObjectOfClass:[AFSecurityPolicy class] forKey:NSStringFromSelector(@selector(securityPolicy))]; if (decodedPolicy) { self.securityPolicy = decodedPolicy; } return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeObject:self.baseURL forKey:NSStringFromSelector(@selector(baseURL))]; if ([self.session.configuration conformsToProtocol:@protocol(NSCoding)]) { [coder encodeObject:self.session.configuration forKey:@"sessionConfiguration"]; } else { [coder encodeObject:self.session.configuration.identifier forKey:@"identifier"]; } [coder encodeObject:self.requestSerializer forKey:NSStringFromSelector(@selector(requestSerializer))]; [coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))]; [coder encodeObject:self.securityPolicy forKey:NSStringFromSelector(@selector(securityPolicy))]; } #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { AFHTTPSessionManager *HTTPClient = [[[self class] allocWithZone:zone] initWithBaseURL:self.baseURL sessionConfiguration:self.session.configuration]; HTTPClient.requestSerializer = [self.requestSerializer copyWithZone:zone]; HTTPClient.responseSerializer = [self.responseSerializer copyWithZone:zone]; HTTPClient.securityPolicy = [self.securityPolicy copyWithZone:zone]; return HTTPClient; } @end ================================================ FILE: Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.h ================================================ // AFNetworkReachabilityManager.h // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #if !TARGET_OS_WATCH #import typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) { AFNetworkReachabilityStatusUnknown = -1, AFNetworkReachabilityStatusNotReachable = 0, AFNetworkReachabilityStatusReachableViaWWAN = 1, AFNetworkReachabilityStatusReachableViaWiFi = 2, }; NS_ASSUME_NONNULL_BEGIN /** `AFNetworkReachabilityManager` monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces. Reachability can be used to determine background information about why a network operation failed, or to trigger a network operation retrying when a connection is established. It should not be used to prevent a user from initiating a network request, as it's possible that an initial request may be required to establish reachability. See Apple's Reachability Sample Code ( https://developer.apple.com/library/ios/samplecode/reachability/ ) @warning Instances of `AFNetworkReachabilityManager` must be started with `-startMonitoring` before reachability status can be determined. */ @interface AFNetworkReachabilityManager : NSObject /** The current network reachability status. */ @property (readonly, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus; /** Whether or not the network is currently reachable. */ @property (readonly, nonatomic, assign, getter = isReachable) BOOL reachable; /** Whether or not the network is currently reachable via WWAN. */ @property (readonly, nonatomic, assign, getter = isReachableViaWWAN) BOOL reachableViaWWAN; /** Whether or not the network is currently reachable via WiFi. */ @property (readonly, nonatomic, assign, getter = isReachableViaWiFi) BOOL reachableViaWiFi; ///--------------------- /// @name Initialization ///--------------------- /** Returns the shared network reachability manager. */ + (instancetype)sharedManager; /** Creates and returns a network reachability manager with the default socket address. @return An initialized network reachability manager, actively monitoring the default socket address. */ + (instancetype)manager; /** Creates and returns a network reachability manager for the specified domain. @param domain The domain used to evaluate network reachability. @return An initialized network reachability manager, actively monitoring the specified domain. */ + (instancetype)managerForDomain:(NSString *)domain; /** Creates and returns a network reachability manager for the socket address. @param address The socket address (`sockaddr_in6`) used to evaluate network reachability. @return An initialized network reachability manager, actively monitoring the specified socket address. */ + (instancetype)managerForAddress:(const void *)address; /** Initializes an instance of a network reachability manager from the specified reachability object. @param reachability The reachability object to monitor. @return An initialized network reachability manager, actively monitoring the specified reachability. */ - (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability NS_DESIGNATED_INITIALIZER; ///-------------------------------------------------- /// @name Starting & Stopping Reachability Monitoring ///-------------------------------------------------- /** Starts monitoring for changes in network reachability status. */ - (void)startMonitoring; /** Stops monitoring for changes in network reachability status. */ - (void)stopMonitoring; ///------------------------------------------------- /// @name Getting Localized Reachability Description ///------------------------------------------------- /** Returns a localized string representation of the current network reachability status. */ - (NSString *)localizedNetworkReachabilityStatusString; ///--------------------------------------------------- /// @name Setting Network Reachability Change Callback ///--------------------------------------------------- /** Sets a callback to be executed when the network availability of the `baseURL` host changes. @param block A block object to be executed when the network availability of the `baseURL` host changes.. This block has no return value and takes a single argument which represents the various reachability states from the device to the `baseURL`. */ - (void)setReachabilityStatusChangeBlock:(nullable void (^)(AFNetworkReachabilityStatus status))block; @end ///---------------- /// @name Constants ///---------------- /** ## Network Reachability The following constants are provided by `AFNetworkReachabilityManager` as possible network reachability statuses. enum { AFNetworkReachabilityStatusUnknown, AFNetworkReachabilityStatusNotReachable, AFNetworkReachabilityStatusReachableViaWWAN, AFNetworkReachabilityStatusReachableViaWiFi, } `AFNetworkReachabilityStatusUnknown` The `baseURL` host reachability is not known. `AFNetworkReachabilityStatusNotReachable` The `baseURL` host cannot be reached. `AFNetworkReachabilityStatusReachableViaWWAN` The `baseURL` host can be reached via a cellular connection, such as EDGE or GPRS. `AFNetworkReachabilityStatusReachableViaWiFi` The `baseURL` host can be reached via a Wi-Fi connection. ### Keys for Notification UserInfo Dictionary Strings that are used as keys in a `userInfo` dictionary in a network reachability status change notification. `AFNetworkingReachabilityNotificationStatusItem` A key in the userInfo dictionary in a `AFNetworkingReachabilityDidChangeNotification` notification. The corresponding value is an `NSNumber` object representing the `AFNetworkReachabilityStatus` value for the current reachability status. */ ///-------------------- /// @name Notifications ///-------------------- /** Posted when network reachability changes. This notification assigns no notification object. The `userInfo` dictionary contains an `NSNumber` object under the `AFNetworkingReachabilityNotificationStatusItem` key, representing the `AFNetworkReachabilityStatus` value for the current network reachability. @warning In order for network reachability to be monitored, include the `SystemConfiguration` framework in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (`Prefix.pch`). */ FOUNDATION_EXPORT NSString * const AFNetworkingReachabilityDidChangeNotification; FOUNDATION_EXPORT NSString * const AFNetworkingReachabilityNotificationStatusItem; ///-------------------- /// @name Functions ///-------------------- /** Returns a localized string representation of an `AFNetworkReachabilityStatus` value. */ FOUNDATION_EXPORT NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status); NS_ASSUME_NONNULL_END #endif ================================================ FILE: Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.m ================================================ // AFNetworkReachabilityManager.m // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "AFNetworkReachabilityManager.h" #if !TARGET_OS_WATCH #import #import #import #import #import NSString * const AFNetworkingReachabilityDidChangeNotification = @"com.alamofire.networking.reachability.change"; NSString * const AFNetworkingReachabilityNotificationStatusItem = @"AFNetworkingReachabilityNotificationStatusItem"; typedef void (^AFNetworkReachabilityStatusBlock)(AFNetworkReachabilityStatus status); NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status) { switch (status) { case AFNetworkReachabilityStatusNotReachable: return NSLocalizedStringFromTable(@"Not Reachable", @"AFNetworking", nil); case AFNetworkReachabilityStatusReachableViaWWAN: return NSLocalizedStringFromTable(@"Reachable via WWAN", @"AFNetworking", nil); case AFNetworkReachabilityStatusReachableViaWiFi: return NSLocalizedStringFromTable(@"Reachable via WiFi", @"AFNetworking", nil); case AFNetworkReachabilityStatusUnknown: default: return NSLocalizedStringFromTable(@"Unknown", @"AFNetworking", nil); } } static AFNetworkReachabilityStatus AFNetworkReachabilityStatusForFlags(SCNetworkReachabilityFlags flags) { BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0); BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0); BOOL canConnectionAutomatically = (((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || ((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0)); BOOL canConnectWithoutUserInteraction = (canConnectionAutomatically && (flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0); BOOL isNetworkReachable = (isReachable && (!needsConnection || canConnectWithoutUserInteraction)); AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusUnknown; if (isNetworkReachable == NO) { status = AFNetworkReachabilityStatusNotReachable; } #if TARGET_OS_IPHONE else if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) { status = AFNetworkReachabilityStatusReachableViaWWAN; } #endif else { status = AFNetworkReachabilityStatusReachableViaWiFi; } return status; } /** * Queue a status change notification for the main thread. * * This is done to ensure that the notifications are received in the same order * as they are sent. If notifications are sent directly, it is possible that * a queued notification (for an earlier status condition) is processed after * the later update, resulting in the listener being left in the wrong state. */ static void AFPostReachabilityStatusChange(SCNetworkReachabilityFlags flags, AFNetworkReachabilityStatusBlock block) { AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags); dispatch_async(dispatch_get_main_queue(), ^{ if (block) { block(status); } NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; NSDictionary *userInfo = @{ AFNetworkingReachabilityNotificationStatusItem: @(status) }; [notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:userInfo]; }); } static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) { AFPostReachabilityStatusChange(flags, (__bridge AFNetworkReachabilityStatusBlock)info); } static const void * AFNetworkReachabilityRetainCallback(const void *info) { return Block_copy(info); } static void AFNetworkReachabilityReleaseCallback(const void *info) { if (info) { Block_release(info); } } @interface AFNetworkReachabilityManager () @property (readonly, nonatomic, assign) SCNetworkReachabilityRef networkReachability; @property (readwrite, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus; @property (readwrite, nonatomic, copy) AFNetworkReachabilityStatusBlock networkReachabilityStatusBlock; @end @implementation AFNetworkReachabilityManager + (instancetype)sharedManager { static AFNetworkReachabilityManager *_sharedManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _sharedManager = [self manager]; }); return _sharedManager; } + (instancetype)managerForDomain:(NSString *)domain { SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [domain UTF8String]); AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability]; CFRelease(reachability); return manager; } + (instancetype)managerForAddress:(const void *)address { SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)address); AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability]; CFRelease(reachability); return manager; } + (instancetype)manager { #if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) struct sockaddr_in6 address; bzero(&address, sizeof(address)); address.sin6_len = sizeof(address); address.sin6_family = AF_INET6; #else struct sockaddr_in address; bzero(&address, sizeof(address)); address.sin_len = sizeof(address); address.sin_family = AF_INET; #endif return [self managerForAddress:&address]; } - (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability { self = [super init]; if (!self) { return nil; } _networkReachability = CFRetain(reachability); self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown; return self; } - (instancetype)init NS_UNAVAILABLE { return nil; } - (void)dealloc { [self stopMonitoring]; if (_networkReachability != NULL) { CFRelease(_networkReachability); } } #pragma mark - - (BOOL)isReachable { return [self isReachableViaWWAN] || [self isReachableViaWiFi]; } - (BOOL)isReachableViaWWAN { return self.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWWAN; } - (BOOL)isReachableViaWiFi { return self.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWiFi; } #pragma mark - - (void)startMonitoring { [self stopMonitoring]; if (!self.networkReachability) { return; } __weak __typeof(self)weakSelf = self; AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) { __strong __typeof(weakSelf)strongSelf = weakSelf; strongSelf.networkReachabilityStatus = status; if (strongSelf.networkReachabilityStatusBlock) { strongSelf.networkReachabilityStatusBlock(status); } }; SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL}; SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context); SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{ SCNetworkReachabilityFlags flags; if (SCNetworkReachabilityGetFlags(self.networkReachability, &flags)) { AFPostReachabilityStatusChange(flags, callback); } }); } - (void)stopMonitoring { if (!self.networkReachability) { return; } SCNetworkReachabilityUnscheduleFromRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes); } #pragma mark - - (NSString *)localizedNetworkReachabilityStatusString { return AFStringFromNetworkReachabilityStatus(self.networkReachabilityStatus); } #pragma mark - - (void)setReachabilityStatusChangeBlock:(void (^)(AFNetworkReachabilityStatus status))block { self.networkReachabilityStatusBlock = block; } #pragma mark - NSKeyValueObserving + (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key { if ([key isEqualToString:@"reachable"] || [key isEqualToString:@"reachableViaWWAN"] || [key isEqualToString:@"reachableViaWiFi"]) { return [NSSet setWithObject:@"networkReachabilityStatus"]; } return [super keyPathsForValuesAffectingValueForKey:key]; } @end #endif ================================================ FILE: Pods/AFNetworking/AFNetworking/AFNetworking.h ================================================ // AFNetworking.h // // Copyright (c) 2013 AFNetworking (http://afnetworking.com/) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #import #ifndef _AFNETWORKING_ #define _AFNETWORKING_ #import "AFURLRequestSerialization.h" #import "AFURLResponseSerialization.h" #import "AFSecurityPolicy.h" #if !TARGET_OS_WATCH #import "AFNetworkReachabilityManager.h" #endif #import "AFURLSessionManager.h" #import "AFHTTPSessionManager.h" #endif /* _AFNETWORKING_ */ ================================================ FILE: Pods/AFNetworking/AFNetworking/AFSecurityPolicy.h ================================================ // AFSecurityPolicy.h // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import typedef NS_ENUM(NSUInteger, AFSSLPinningMode) { AFSSLPinningModeNone, AFSSLPinningModePublicKey, AFSSLPinningModeCertificate, }; /** `AFSecurityPolicy` evaluates server trust against pinned X.509 certificates and public keys over secure connections. Adding pinned SSL certificates to your app helps prevent man-in-the-middle attacks and other vulnerabilities. Applications dealing with sensitive customer data or financial information are strongly encouraged to route all communication over an HTTPS connection with SSL pinning configured and enabled. */ NS_ASSUME_NONNULL_BEGIN @interface AFSecurityPolicy : NSObject /** The criteria by which server trust should be evaluated against the pinned SSL certificates. Defaults to `AFSSLPinningModeNone`. */ @property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode; /** The certificates used to evaluate server trust according to the SSL pinning mode. By default, this property is set to any (`.cer`) certificates included in the target compiling AFNetworking. Note that if you are using AFNetworking as embedded framework, no certificates will be pinned by default. Use `certificatesInBundle` to load certificates from your target, and then create a new policy by calling `policyWithPinningMode:withPinnedCertificates`. Note that if pinning is enabled, `evaluateServerTrust:forDomain:` will return true if any pinned certificate matches. */ @property (nonatomic, strong, nullable) NSSet *pinnedCertificates; /** Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`. */ @property (nonatomic, assign) BOOL allowInvalidCertificates; /** Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES`. */ @property (nonatomic, assign) BOOL validatesDomainName; ///----------------------------------------- /// @name Getting Certificates from the Bundle ///----------------------------------------- /** Returns any certificates included in the bundle. If you are using AFNetworking as an embedded framework, you must use this method to find the certificates you have included in your app bundle, and use them when creating your security policy by calling `policyWithPinningMode:withPinnedCertificates`. @return The certificates included in the given bundle. */ + (NSSet *)certificatesInBundle:(NSBundle *)bundle; ///----------------------------------------- /// @name Getting Specific Security Policies ///----------------------------------------- /** Returns the shared default security policy, which does not allow invalid certificates, validates domain name, and does not validate against pinned certificates or public keys. @return The default security policy. */ + (instancetype)defaultPolicy; ///--------------------- /// @name Initialization ///--------------------- /** Creates and returns a security policy with the specified pinning mode. @param pinningMode The SSL pinning mode. @return A new security policy. */ + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode; /** Creates and returns a security policy with the specified pinning mode. @param pinningMode The SSL pinning mode. @param pinnedCertificates The certificates to pin against. @return A new security policy. */ + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode withPinnedCertificates:(NSSet *)pinnedCertificates; ///------------------------------ /// @name Evaluating Server Trust ///------------------------------ /** Whether or not the specified server trust should be accepted, based on the security policy. This method should be used when responding to an authentication challenge from a server. @param serverTrust The X.509 certificate trust of the server. @param domain The domain of serverTrust. If `nil`, the domain will not be validated. @return Whether or not to trust the server. */ - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(nullable NSString *)domain; @end NS_ASSUME_NONNULL_END ///---------------- /// @name Constants ///---------------- /** ## SSL Pinning Modes The following constants are provided by `AFSSLPinningMode` as possible SSL pinning modes. enum { AFSSLPinningModeNone, AFSSLPinningModePublicKey, AFSSLPinningModeCertificate, } `AFSSLPinningModeNone` Do not used pinned certificates to validate servers. `AFSSLPinningModePublicKey` Validate host certificates against public keys of pinned certificates. `AFSSLPinningModeCertificate` Validate host certificates against pinned certificates. */ ================================================ FILE: Pods/AFNetworking/AFNetworking/AFSecurityPolicy.m ================================================ // AFSecurityPolicy.m // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "AFSecurityPolicy.h" #import #if !TARGET_OS_IOS && !TARGET_OS_WATCH && !TARGET_OS_TV static NSData * AFSecKeyGetData(SecKeyRef key) { CFDataRef data = NULL; __Require_noErr_Quiet(SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data), _out); return (__bridge_transfer NSData *)data; _out: if (data) { CFRelease(data); } return nil; } #endif static BOOL AFSecKeyIsEqualToKey(SecKeyRef key1, SecKeyRef key2) { #if TARGET_OS_IOS || TARGET_OS_WATCH || TARGET_OS_TV return [(__bridge id)key1 isEqual:(__bridge id)key2]; #else return [AFSecKeyGetData(key1) isEqual:AFSecKeyGetData(key2)]; #endif } static id AFPublicKeyForCertificate(NSData *certificate) { id allowedPublicKey = nil; SecCertificateRef allowedCertificate; SecCertificateRef allowedCertificates[1]; CFArrayRef tempCertificates = nil; SecPolicyRef policy = nil; SecTrustRef allowedTrust = nil; SecTrustResultType result; allowedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificate); __Require_Quiet(allowedCertificate != NULL, _out); allowedCertificates[0] = allowedCertificate; tempCertificates = CFArrayCreate(NULL, (const void **)allowedCertificates, 1, NULL); policy = SecPolicyCreateBasicX509(); __Require_noErr_Quiet(SecTrustCreateWithCertificates(tempCertificates, policy, &allowedTrust), _out); __Require_noErr_Quiet(SecTrustEvaluate(allowedTrust, &result), _out); allowedPublicKey = (__bridge_transfer id)SecTrustCopyPublicKey(allowedTrust); _out: if (allowedTrust) { CFRelease(allowedTrust); } if (policy) { CFRelease(policy); } if (tempCertificates) { CFRelease(tempCertificates); } if (allowedCertificate) { CFRelease(allowedCertificate); } return allowedPublicKey; } static BOOL AFServerTrustIsValid(SecTrustRef serverTrust) { BOOL isValid = NO; SecTrustResultType result; __Require_noErr_Quiet(SecTrustEvaluate(serverTrust, &result), _out); isValid = (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed); _out: return isValid; } static NSArray * AFCertificateTrustChainForServerTrust(SecTrustRef serverTrust) { CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust); NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount]; for (CFIndex i = 0; i < certificateCount; i++) { SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i); [trustChain addObject:(__bridge_transfer NSData *)SecCertificateCopyData(certificate)]; } return [NSArray arrayWithArray:trustChain]; } static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) { SecPolicyRef policy = SecPolicyCreateBasicX509(); CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust); NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount]; for (CFIndex i = 0; i < certificateCount; i++) { SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i); SecCertificateRef someCertificates[] = {certificate}; CFArrayRef certificates = CFArrayCreate(NULL, (const void **)someCertificates, 1, NULL); SecTrustRef trust; __Require_noErr_Quiet(SecTrustCreateWithCertificates(certificates, policy, &trust), _out); SecTrustResultType result; __Require_noErr_Quiet(SecTrustEvaluate(trust, &result), _out); [trustChain addObject:(__bridge_transfer id)SecTrustCopyPublicKey(trust)]; _out: if (trust) { CFRelease(trust); } if (certificates) { CFRelease(certificates); } continue; } CFRelease(policy); return [NSArray arrayWithArray:trustChain]; } #pragma mark - @interface AFSecurityPolicy() @property (readwrite, nonatomic, assign) AFSSLPinningMode SSLPinningMode; @property (readwrite, nonatomic, strong) NSSet *pinnedPublicKeys; @end @implementation AFSecurityPolicy + (NSSet *)certificatesInBundle:(NSBundle *)bundle { NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"."]; NSMutableSet *certificates = [NSMutableSet setWithCapacity:[paths count]]; for (NSString *path in paths) { NSData *certificateData = [NSData dataWithContentsOfFile:path]; [certificates addObject:certificateData]; } return [NSSet setWithSet:certificates]; } + (NSSet *)defaultPinnedCertificates { static NSSet *_defaultPinnedCertificates = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSBundle *bundle = [NSBundle bundleForClass:[self class]]; _defaultPinnedCertificates = [self certificatesInBundle:bundle]; }); return _defaultPinnedCertificates; } + (instancetype)defaultPolicy { AFSecurityPolicy *securityPolicy = [[self alloc] init]; securityPolicy.SSLPinningMode = AFSSLPinningModeNone; return securityPolicy; } + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode { return [self policyWithPinningMode:pinningMode withPinnedCertificates:[self defaultPinnedCertificates]]; } + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode withPinnedCertificates:(NSSet *)pinnedCertificates { AFSecurityPolicy *securityPolicy = [[self alloc] init]; securityPolicy.SSLPinningMode = pinningMode; [securityPolicy setPinnedCertificates:pinnedCertificates]; return securityPolicy; } - (instancetype)init { self = [super init]; if (!self) { return nil; } self.validatesDomainName = YES; return self; } - (void)setPinnedCertificates:(NSSet *)pinnedCertificates { _pinnedCertificates = pinnedCertificates; if (self.pinnedCertificates) { NSMutableSet *mutablePinnedPublicKeys = [NSMutableSet setWithCapacity:[self.pinnedCertificates count]]; for (NSData *certificate in self.pinnedCertificates) { id publicKey = AFPublicKeyForCertificate(certificate); if (!publicKey) { continue; } [mutablePinnedPublicKeys addObject:publicKey]; } self.pinnedPublicKeys = [NSSet setWithSet:mutablePinnedPublicKeys]; } else { self.pinnedPublicKeys = nil; } } #pragma mark - - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain { if (domain && self.allowInvalidCertificates && self.validatesDomainName && (self.SSLPinningMode == AFSSLPinningModeNone || [self.pinnedCertificates count] == 0)) { // https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/OverridingSSLChainValidationCorrectly.html // According to the docs, you should only trust your provided certs for evaluation. // Pinned certificates are added to the trust. Without pinned certificates, // there is nothing to evaluate against. // // From Apple Docs: // "Do not implicitly trust self-signed certificates as anchors (kSecTrustOptionImplicitAnchors). // Instead, add your own (self-signed) CA certificate to the list of trusted anchors." NSLog(@"In order to validate a domain name for self signed certificates, you MUST use pinning."); return NO; } NSMutableArray *policies = [NSMutableArray array]; if (self.validatesDomainName) { [policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)]; } else { [policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()]; } SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies); if (self.SSLPinningMode == AFSSLPinningModeNone) { return self.allowInvalidCertificates || AFServerTrustIsValid(serverTrust); } else if (!AFServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) { return NO; } switch (self.SSLPinningMode) { case AFSSLPinningModeNone: default: return NO; case AFSSLPinningModeCertificate: { NSMutableArray *pinnedCertificates = [NSMutableArray array]; for (NSData *certificateData in self.pinnedCertificates) { [pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)]; } SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates); if (!AFServerTrustIsValid(serverTrust)) { return NO; } // obtain the chain after being validated, which *should* contain the pinned certificate in the last position (if it's the Root CA) NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust); for (NSData *trustChainCertificate in [serverCertificates reverseObjectEnumerator]) { if ([self.pinnedCertificates containsObject:trustChainCertificate]) { return YES; } } return NO; } case AFSSLPinningModePublicKey: { NSUInteger trustedPublicKeyCount = 0; NSArray *publicKeys = AFPublicKeyTrustChainForServerTrust(serverTrust); for (id trustChainPublicKey in publicKeys) { for (id pinnedPublicKey in self.pinnedPublicKeys) { if (AFSecKeyIsEqualToKey((__bridge SecKeyRef)trustChainPublicKey, (__bridge SecKeyRef)pinnedPublicKey)) { trustedPublicKeyCount += 1; } } } return trustedPublicKeyCount > 0; } } return NO; } #pragma mark - NSKeyValueObserving + (NSSet *)keyPathsForValuesAffectingPinnedPublicKeys { return [NSSet setWithObject:@"pinnedCertificates"]; } #pragma mark - NSSecureCoding + (BOOL)supportsSecureCoding { return YES; } - (instancetype)initWithCoder:(NSCoder *)decoder { self = [self init]; if (!self) { return nil; } self.SSLPinningMode = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(SSLPinningMode))] unsignedIntegerValue]; self.allowInvalidCertificates = [decoder decodeBoolForKey:NSStringFromSelector(@selector(allowInvalidCertificates))]; self.validatesDomainName = [decoder decodeBoolForKey:NSStringFromSelector(@selector(validatesDomainName))]; self.pinnedCertificates = [decoder decodeObjectOfClass:[NSArray class] forKey:NSStringFromSelector(@selector(pinnedCertificates))]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [coder encodeObject:[NSNumber numberWithUnsignedInteger:self.SSLPinningMode] forKey:NSStringFromSelector(@selector(SSLPinningMode))]; [coder encodeBool:self.allowInvalidCertificates forKey:NSStringFromSelector(@selector(allowInvalidCertificates))]; [coder encodeBool:self.validatesDomainName forKey:NSStringFromSelector(@selector(validatesDomainName))]; [coder encodeObject:self.pinnedCertificates forKey:NSStringFromSelector(@selector(pinnedCertificates))]; } #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { AFSecurityPolicy *securityPolicy = [[[self class] allocWithZone:zone] init]; securityPolicy.SSLPinningMode = self.SSLPinningMode; securityPolicy.allowInvalidCertificates = self.allowInvalidCertificates; securityPolicy.validatesDomainName = self.validatesDomainName; securityPolicy.pinnedCertificates = [self.pinnedCertificates copyWithZone:zone]; return securityPolicy; } @end ================================================ FILE: Pods/AFNetworking/AFNetworking/AFURLRequestSerialization.h ================================================ // AFURLRequestSerialization.h // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #if TARGET_OS_IOS || TARGET_OS_TV #import #elif TARGET_OS_WATCH #import #endif NS_ASSUME_NONNULL_BEGIN /** Returns a percent-escaped string following RFC 3986 for a query string key or value. RFC 3986 states that the following characters are "reserved" characters. - General Delimiters: ":", "#", "[", "]", "@", "?", "/" - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "=" In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/" should be percent-escaped in the query string. @param string The string to be percent-escaped. @return The percent-escaped string. */ FOUNDATION_EXPORT NSString * AFPercentEscapedStringFromString(NSString *string); /** A helper method to generate encoded url query parameters for appending to the end of a URL. @param parameters A dictionary of key/values to be encoded. @return A url encoded query string */ FOUNDATION_EXPORT NSString * AFQueryStringFromParameters(NSDictionary *parameters); /** The `AFURLRequestSerialization` protocol is adopted by an object that encodes parameters for a specified HTTP requests. Request serializers may encode parameters as query strings, HTTP bodies, setting the appropriate HTTP header fields as necessary. For example, a JSON request serializer may set the HTTP body of the request to a JSON representation, and set the `Content-Type` HTTP header field value to `application/json`. */ @protocol AFURLRequestSerialization /** Returns a request with the specified parameters encoded into a copy of the original request. @param request The original request. @param parameters The parameters to be encoded. @param error The error that occurred while attempting to encode the request parameters. @return A serialized request. */ - (nullable NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request withParameters:(nullable id)parameters error:(NSError * _Nullable __autoreleasing *)error NS_SWIFT_NOTHROW; @end #pragma mark - /** */ typedef NS_ENUM(NSUInteger, AFHTTPRequestQueryStringSerializationStyle) { AFHTTPRequestQueryStringDefaultStyle = 0, }; @protocol AFMultipartFormData; /** `AFHTTPRequestSerializer` conforms to the `AFURLRequestSerialization` & `AFURLResponseSerialization` protocols, offering a concrete base implementation of query string / URL form-encoded parameter serialization and default request headers, as well as response status code and content type validation. Any request or response serializer dealing with HTTP is encouraged to subclass `AFHTTPRequestSerializer` in order to ensure consistent default behavior. */ @interface AFHTTPRequestSerializer : NSObject /** The string encoding used to serialize parameters. `NSUTF8StringEncoding` by default. */ @property (nonatomic, assign) NSStringEncoding stringEncoding; /** Whether created requests can use the device’s cellular radio (if present). `YES` by default. @see NSMutableURLRequest -setAllowsCellularAccess: */ @property (nonatomic, assign) BOOL allowsCellularAccess; /** The cache policy of created requests. `NSURLRequestUseProtocolCachePolicy` by default. @see NSMutableURLRequest -setCachePolicy: */ @property (nonatomic, assign) NSURLRequestCachePolicy cachePolicy; /** Whether created requests should use the default cookie handling. `YES` by default. @see NSMutableURLRequest -setHTTPShouldHandleCookies: */ @property (nonatomic, assign) BOOL HTTPShouldHandleCookies; /** Whether created requests can continue transmitting data before receiving a response from an earlier transmission. `NO` by default @see NSMutableURLRequest -setHTTPShouldUsePipelining: */ @property (nonatomic, assign) BOOL HTTPShouldUsePipelining; /** The network service type for created requests. `NSURLNetworkServiceTypeDefault` by default. @see NSMutableURLRequest -setNetworkServiceType: */ @property (nonatomic, assign) NSURLRequestNetworkServiceType networkServiceType; /** The timeout interval, in seconds, for created requests. The default timeout interval is 60 seconds. @see NSMutableURLRequest -setTimeoutInterval: */ @property (nonatomic, assign) NSTimeInterval timeoutInterval; ///--------------------------------------- /// @name Configuring HTTP Request Headers ///--------------------------------------- /** Default HTTP header field values to be applied to serialized requests. By default, these include the following: - `Accept-Language` with the contents of `NSLocale +preferredLanguages` - `User-Agent` with the contents of various bundle identifiers and OS designations @discussion To add or remove default request headers, use `setValue:forHTTPHeaderField:`. */ @property (readonly, nonatomic, strong) NSDictionary *HTTPRequestHeaders; /** Creates and returns a serializer with default configuration. */ + (instancetype)serializer; /** Sets the value for the HTTP headers set in request objects made by the HTTP client. If `nil`, removes the existing value for that header. @param field The HTTP header to set a default value for @param value The value set as default for the specified header, or `nil` */ - (void)setValue:(nullable NSString *)value forHTTPHeaderField:(NSString *)field; /** Returns the value for the HTTP headers set in the request serializer. @param field The HTTP header to retrieve the default value for @return The value set as default for the specified header, or `nil` */ - (nullable NSString *)valueForHTTPHeaderField:(NSString *)field; /** Sets the "Authorization" HTTP header set in request objects made by the HTTP client to a basic authentication value with Base64-encoded username and password. This overwrites any existing value for this header. @param username The HTTP basic auth username @param password The HTTP basic auth password */ - (void)setAuthorizationHeaderFieldWithUsername:(NSString *)username password:(NSString *)password; /** Clears any existing value for the "Authorization" HTTP header. */ - (void)clearAuthorizationHeader; ///------------------------------------------------------- /// @name Configuring Query String Parameter Serialization ///------------------------------------------------------- /** HTTP methods for which serialized requests will encode parameters as a query string. `GET`, `HEAD`, and `DELETE` by default. */ @property (nonatomic, strong) NSSet *HTTPMethodsEncodingParametersInURI; /** Set the method of query string serialization according to one of the pre-defined styles. @param style The serialization style. @see AFHTTPRequestQueryStringSerializationStyle */ - (void)setQueryStringSerializationWithStyle:(AFHTTPRequestQueryStringSerializationStyle)style; /** Set the a custom method of query string serialization according to the specified block. @param block A block that defines a process of encoding parameters into a query string. This block returns the query string and takes three arguments: the request, the parameters to encode, and the error that occurred when attempting to encode parameters for the given request. */ - (void)setQueryStringSerializationWithBlock:(nullable NSString * (^)(NSURLRequest *request, id parameters, NSError * __autoreleasing *error))block; ///------------------------------- /// @name Creating Request Objects ///------------------------------- /** Creates an `NSMutableURLRequest` object with the specified HTTP method and URL string. If the HTTP method is `GET`, `HEAD`, or `DELETE`, the parameters will be used to construct a url-encoded query string that is appended to the request's URL. Otherwise, the parameters will be encoded according to the value of the `parameterEncoding` property, and set as the request body. @param method The HTTP method for the request, such as `GET`, `POST`, `PUT`, or `DELETE`. This parameter must not be `nil`. @param URLString The URL string used to create the request URL. @param parameters The parameters to be either set as a query string for `GET` requests, or the request HTTP body. @param error The error that occurred while constructing the request. @return An `NSMutableURLRequest` object. */ - (NSMutableURLRequest *)requestWithMethod:(NSString *)method URLString:(NSString *)URLString parameters:(nullable id)parameters error:(NSError * _Nullable __autoreleasing *)error; /** Creates an `NSMutableURLRequest` object with the specified HTTP method and URLString, and constructs a `multipart/form-data` HTTP body, using the specified parameters and multipart form data block. See http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2 Multipart form requests are automatically streamed, reading files directly from disk along with in-memory data in a single HTTP body. The resulting `NSMutableURLRequest` object has an `HTTPBodyStream` property, so refrain from setting `HTTPBodyStream` or `HTTPBody` on this request object, as it will clear out the multipart form body stream. @param method The HTTP method for the request. This parameter must not be `GET` or `HEAD`, or `nil`. @param URLString The URL string used to create the request URL. @param parameters The parameters to be encoded and set in the request HTTP body. @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. @param error The error that occurred while constructing the request. @return An `NSMutableURLRequest` object */ - (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method URLString:(NSString *)URLString parameters:(nullable NSDictionary *)parameters constructingBodyWithBlock:(nullable void (^)(id formData))block error:(NSError * _Nullable __autoreleasing *)error; /** Creates an `NSMutableURLRequest` by removing the `HTTPBodyStream` from a request, and asynchronously writing its contents into the specified file, invoking the completion handler when finished. @param request The multipart form request. The `HTTPBodyStream` property of `request` must not be `nil`. @param fileURL The file URL to write multipart form contents to. @param handler A handler block to execute. @discussion There is a bug in `NSURLSessionTask` that causes requests to not send a `Content-Length` header when streaming contents from an HTTP body, which is notably problematic when interacting with the Amazon S3 webservice. As a workaround, this method takes a request constructed with `multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:error:`, or any other request with an `HTTPBodyStream`, writes the contents to the specified file and returns a copy of the original request with the `HTTPBodyStream` property set to `nil`. From here, the file can either be passed to `AFURLSessionManager -uploadTaskWithRequest:fromFile:progress:completionHandler:`, or have its contents read into an `NSData` that's assigned to the `HTTPBody` property of the request. @see https://github.com/AFNetworking/AFNetworking/issues/1398 */ - (NSMutableURLRequest *)requestWithMultipartFormRequest:(NSURLRequest *)request writingStreamContentsToFile:(NSURL *)fileURL completionHandler:(nullable void (^)(NSError * _Nullable error))handler; @end #pragma mark - /** The `AFMultipartFormData` protocol defines the methods supported by the parameter in the block argument of `AFHTTPRequestSerializer -multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:`. */ @protocol AFMultipartFormData /** Appends the HTTP header `Content-Disposition: file; filename=#{generated filename}; name=#{name}"` and `Content-Type: #{generated mimeType}`, followed by the encoded file data and the multipart form boundary. The filename and MIME type for this data in the form will be automatically generated, using the last path component of the `fileURL` and system associated MIME type for the `fileURL` extension, respectively. @param fileURL The URL corresponding to the file whose content will be appended to the form. This parameter must not be `nil`. @param name The name to be associated with the specified data. This parameter must not be `nil`. @param error If an error occurs, upon return contains an `NSError` object that describes the problem. @return `YES` if the file data was successfully appended, otherwise `NO`. */ - (BOOL)appendPartWithFileURL:(NSURL *)fileURL name:(NSString *)name error:(NSError * _Nullable __autoreleasing *)error; /** Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary. @param fileURL The URL corresponding to the file whose content will be appended to the form. This parameter must not be `nil`. @param name The name to be associated with the specified data. This parameter must not be `nil`. @param fileName The file name to be used in the `Content-Disposition` header. This parameter must not be `nil`. @param mimeType The declared MIME type of the file data. This parameter must not be `nil`. @param error If an error occurs, upon return contains an `NSError` object that describes the problem. @return `YES` if the file data was successfully appended otherwise `NO`. */ - (BOOL)appendPartWithFileURL:(NSURL *)fileURL name:(NSString *)name fileName:(NSString *)fileName mimeType:(NSString *)mimeType error:(NSError * _Nullable __autoreleasing *)error; /** Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the data from the input stream and the multipart form boundary. @param inputStream The input stream to be appended to the form data @param name The name to be associated with the specified input stream. This parameter must not be `nil`. @param fileName The filename to be associated with the specified input stream. This parameter must not be `nil`. @param length The length of the specified input stream in bytes. @param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. This parameter must not be `nil`. */ - (void)appendPartWithInputStream:(nullable NSInputStream *)inputStream name:(NSString *)name fileName:(NSString *)fileName length:(int64_t)length mimeType:(NSString *)mimeType; /** Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary. @param data The data to be encoded and appended to the form data. @param name The name to be associated with the specified data. This parameter must not be `nil`. @param fileName The filename to be associated with the specified data. This parameter must not be `nil`. @param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. This parameter must not be `nil`. */ - (void)appendPartWithFileData:(NSData *)data name:(NSString *)name fileName:(NSString *)fileName mimeType:(NSString *)mimeType; /** Appends the HTTP headers `Content-Disposition: form-data; name=#{name}"`, followed by the encoded data and the multipart form boundary. @param data The data to be encoded and appended to the form data. @param name The name to be associated with the specified data. This parameter must not be `nil`. */ - (void)appendPartWithFormData:(NSData *)data name:(NSString *)name; /** Appends HTTP headers, followed by the encoded data and the multipart form boundary. @param headers The HTTP headers to be appended to the form data. @param body The data to be encoded and appended to the form data. This parameter must not be `nil`. */ - (void)appendPartWithHeaders:(nullable NSDictionary *)headers body:(NSData *)body; /** Throttles request bandwidth by limiting the packet size and adding a delay for each chunk read from the upload stream. When uploading over a 3G or EDGE connection, requests may fail with "request body stream exhausted". Setting a maximum packet size and delay according to the recommended values (`kAFUploadStream3GSuggestedPacketSize` and `kAFUploadStream3GSuggestedDelay`) lowers the risk of the input stream exceeding its allocated bandwidth. Unfortunately, there is no definite way to distinguish between a 3G, EDGE, or LTE connection over `NSURLConnection`. As such, it is not recommended that you throttle bandwidth based solely on network reachability. Instead, you should consider checking for the "request body stream exhausted" in a failure block, and then retrying the request with throttled bandwidth. @param numberOfBytes Maximum packet size, in number of bytes. The default packet size for an input stream is 16kb. @param delay Duration of delay each time a packet is read. By default, no delay is set. */ - (void)throttleBandwidthWithPacketSize:(NSUInteger)numberOfBytes delay:(NSTimeInterval)delay; @end #pragma mark - /** `AFJSONRequestSerializer` is a subclass of `AFHTTPRequestSerializer` that encodes parameters as JSON using `NSJSONSerialization`, setting the `Content-Type` of the encoded request to `application/json`. */ @interface AFJSONRequestSerializer : AFHTTPRequestSerializer /** Options for writing the request JSON data from Foundation objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONWritingOptions". `0` by default. */ @property (nonatomic, assign) NSJSONWritingOptions writingOptions; /** Creates and returns a JSON serializer with specified reading and writing options. @param writingOptions The specified JSON writing options. */ + (instancetype)serializerWithWritingOptions:(NSJSONWritingOptions)writingOptions; @end #pragma mark - /** `AFPropertyListRequestSerializer` is a subclass of `AFHTTPRequestSerializer` that encodes parameters as JSON using `NSPropertyListSerializer`, setting the `Content-Type` of the encoded request to `application/x-plist`. */ @interface AFPropertyListRequestSerializer : AFHTTPRequestSerializer /** The property list format. Possible values are described in "NSPropertyListFormat". */ @property (nonatomic, assign) NSPropertyListFormat format; /** @warning The `writeOptions` property is currently unused. */ @property (nonatomic, assign) NSPropertyListWriteOptions writeOptions; /** Creates and returns a property list serializer with a specified format, read options, and write options. @param format The property list format. @param writeOptions The property list write options. @warning The `writeOptions` property is currently unused. */ + (instancetype)serializerWithFormat:(NSPropertyListFormat)format writeOptions:(NSPropertyListWriteOptions)writeOptions; @end #pragma mark - ///---------------- /// @name Constants ///---------------- /** ## Error Domains The following error domain is predefined. - `NSString * const AFURLRequestSerializationErrorDomain` ### Constants `AFURLRequestSerializationErrorDomain` AFURLRequestSerializer errors. Error codes for `AFURLRequestSerializationErrorDomain` correspond to codes in `NSURLErrorDomain`. */ FOUNDATION_EXPORT NSString * const AFURLRequestSerializationErrorDomain; /** ## User info dictionary keys These keys may exist in the user info dictionary, in addition to those defined for NSError. - `NSString * const AFNetworkingOperationFailingURLRequestErrorKey` ### Constants `AFNetworkingOperationFailingURLRequestErrorKey` The corresponding value is an `NSURLRequest` containing the request of the operation associated with an error. This key is only present in the `AFURLRequestSerializationErrorDomain`. */ FOUNDATION_EXPORT NSString * const AFNetworkingOperationFailingURLRequestErrorKey; /** ## Throttling Bandwidth for HTTP Request Input Streams @see -throttleBandwidthWithPacketSize:delay: ### Constants `kAFUploadStream3GSuggestedPacketSize` Maximum packet size, in number of bytes. Equal to 16kb. `kAFUploadStream3GSuggestedDelay` Duration of delay each time a packet is read. Equal to 0.2 seconds. */ FOUNDATION_EXPORT NSUInteger const kAFUploadStream3GSuggestedPacketSize; FOUNDATION_EXPORT NSTimeInterval const kAFUploadStream3GSuggestedDelay; NS_ASSUME_NONNULL_END ================================================ FILE: Pods/AFNetworking/AFNetworking/AFURLRequestSerialization.m ================================================ // AFURLRequestSerialization.m // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "AFURLRequestSerialization.h" #if TARGET_OS_IOS || TARGET_OS_WATCH || TARGET_OS_TV #import #else #import #endif NSString * const AFURLRequestSerializationErrorDomain = @"com.alamofire.error.serialization.request"; NSString * const AFNetworkingOperationFailingURLRequestErrorKey = @"com.alamofire.serialization.request.error.response"; typedef NSString * (^AFQueryStringSerializationBlock)(NSURLRequest *request, id parameters, NSError *__autoreleasing *error); /** Returns a percent-escaped string following RFC 3986 for a query string key or value. RFC 3986 states that the following characters are "reserved" characters. - General Delimiters: ":", "#", "[", "]", "@", "?", "/" - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "=" In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/" should be percent-escaped in the query string. - parameter string: The string to be percent-escaped. - returns: The percent-escaped string. */ NSString * AFPercentEscapedStringFromString(NSString *string) { static NSString * const kAFCharactersGeneralDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4 static NSString * const kAFCharactersSubDelimitersToEncode = @"!$&'()*+,;="; NSMutableCharacterSet * allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy]; [allowedCharacterSet removeCharactersInString:[kAFCharactersGeneralDelimitersToEncode stringByAppendingString:kAFCharactersSubDelimitersToEncode]]; // FIXME: https://github.com/AFNetworking/AFNetworking/pull/3028 // return [string stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet]; static NSUInteger const batchSize = 50; NSUInteger index = 0; NSMutableString *escaped = @"".mutableCopy; while (index < string.length) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wgnu" NSUInteger length = MIN(string.length - index, batchSize); #pragma GCC diagnostic pop NSRange range = NSMakeRange(index, length); // To avoid breaking up character sequences such as 👴🏻👮🏽 range = [string rangeOfComposedCharacterSequencesForRange:range]; NSString *substring = [string substringWithRange:range]; NSString *encoded = [substring stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet]; [escaped appendString:encoded]; index += range.length; } return escaped; } #pragma mark - @interface AFQueryStringPair : NSObject @property (readwrite, nonatomic, strong) id field; @property (readwrite, nonatomic, strong) id value; - (instancetype)initWithField:(id)field value:(id)value; - (NSString *)URLEncodedStringValue; @end @implementation AFQueryStringPair - (instancetype)initWithField:(id)field value:(id)value { self = [super init]; if (!self) { return nil; } self.field = field; self.value = value; return self; } - (NSString *)URLEncodedStringValue { if (!self.value || [self.value isEqual:[NSNull null]]) { return AFPercentEscapedStringFromString([self.field description]); } else { return [NSString stringWithFormat:@"%@=%@", AFPercentEscapedStringFromString([self.field description]), AFPercentEscapedStringFromString([self.value description])]; } } @end #pragma mark - FOUNDATION_EXPORT NSArray * AFQueryStringPairsFromDictionary(NSDictionary *dictionary); FOUNDATION_EXPORT NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value); NSString * AFQueryStringFromParameters(NSDictionary *parameters) { NSMutableArray *mutablePairs = [NSMutableArray array]; for (AFQueryStringPair *pair in AFQueryStringPairsFromDictionary(parameters)) { [mutablePairs addObject:[pair URLEncodedStringValue]]; } return [mutablePairs componentsJoinedByString:@"&"]; } NSArray * AFQueryStringPairsFromDictionary(NSDictionary *dictionary) { return AFQueryStringPairsFromKeyAndValue(nil, dictionary); } NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) { NSMutableArray *mutableQueryStringComponents = [NSMutableArray array]; NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES selector:@selector(compare:)]; if ([value isKindOfClass:[NSDictionary class]]) { NSDictionary *dictionary = value; // Sort dictionary keys to ensure consistent ordering in query string, which is important when deserializing potentially ambiguous sequences, such as an array of dictionaries for (id nestedKey in [dictionary.allKeys sortedArrayUsingDescriptors:@[ sortDescriptor ]]) { id nestedValue = dictionary[nestedKey]; if (nestedValue) { [mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue((key ? [NSString stringWithFormat:@"%@[%@]", key, nestedKey] : nestedKey), nestedValue)]; } } } else if ([value isKindOfClass:[NSArray class]]) { NSArray *array = value; for (id nestedValue in array) { [mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue([NSString stringWithFormat:@"%@[]", key], nestedValue)]; } } else if ([value isKindOfClass:[NSSet class]]) { NSSet *set = value; for (id obj in [set sortedArrayUsingDescriptors:@[ sortDescriptor ]]) { [mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue(key, obj)]; } } else { [mutableQueryStringComponents addObject:[[AFQueryStringPair alloc] initWithField:key value:value]]; } return mutableQueryStringComponents; } #pragma mark - @interface AFStreamingMultipartFormData : NSObject - (instancetype)initWithURLRequest:(NSMutableURLRequest *)urlRequest stringEncoding:(NSStringEncoding)encoding; - (NSMutableURLRequest *)requestByFinalizingMultipartFormData; @end #pragma mark - static NSArray * AFHTTPRequestSerializerObservedKeyPaths() { static NSArray *_AFHTTPRequestSerializerObservedKeyPaths = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _AFHTTPRequestSerializerObservedKeyPaths = @[NSStringFromSelector(@selector(allowsCellularAccess)), NSStringFromSelector(@selector(cachePolicy)), NSStringFromSelector(@selector(HTTPShouldHandleCookies)), NSStringFromSelector(@selector(HTTPShouldUsePipelining)), NSStringFromSelector(@selector(networkServiceType)), NSStringFromSelector(@selector(timeoutInterval))]; }); return _AFHTTPRequestSerializerObservedKeyPaths; } static void *AFHTTPRequestSerializerObserverContext = &AFHTTPRequestSerializerObserverContext; @interface AFHTTPRequestSerializer () @property (readwrite, nonatomic, strong) NSMutableSet *mutableObservedChangedKeyPaths; @property (readwrite, nonatomic, strong) NSMutableDictionary *mutableHTTPRequestHeaders; @property (readwrite, nonatomic, assign) AFHTTPRequestQueryStringSerializationStyle queryStringSerializationStyle; @property (readwrite, nonatomic, copy) AFQueryStringSerializationBlock queryStringSerialization; @end @implementation AFHTTPRequestSerializer + (instancetype)serializer { return [[self alloc] init]; } - (instancetype)init { self = [super init]; if (!self) { return nil; } self.stringEncoding = NSUTF8StringEncoding; self.mutableHTTPRequestHeaders = [NSMutableDictionary dictionary]; // Accept-Language HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 NSMutableArray *acceptLanguagesComponents = [NSMutableArray array]; [[NSLocale preferredLanguages] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { float q = 1.0f - (idx * 0.1f); [acceptLanguagesComponents addObject:[NSString stringWithFormat:@"%@;q=%0.1g", obj, q]]; *stop = q <= 0.5f; }]; [self setValue:[acceptLanguagesComponents componentsJoinedByString:@", "] forHTTPHeaderField:@"Accept-Language"]; NSString *userAgent = nil; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" #if TARGET_OS_IOS // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43 userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]]; #elif TARGET_OS_WATCH // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43 userAgent = [NSString stringWithFormat:@"%@/%@ (%@; watchOS %@; Scale/%0.2f)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[WKInterfaceDevice currentDevice] model], [[WKInterfaceDevice currentDevice] systemVersion], [[WKInterfaceDevice currentDevice] screenScale]]; #elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) userAgent = [NSString stringWithFormat:@"%@/%@ (Mac OS X %@)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]]; #endif #pragma clang diagnostic pop if (userAgent) { if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) { NSMutableString *mutableUserAgent = [userAgent mutableCopy]; if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@"Any-Latin; Latin-ASCII; [:^ASCII:] Remove", false)) { userAgent = mutableUserAgent; } } [self setValue:userAgent forHTTPHeaderField:@"User-Agent"]; } // HTTP Method Definitions; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html self.HTTPMethodsEncodingParametersInURI = [NSSet setWithObjects:@"GET", @"HEAD", @"DELETE", nil]; self.mutableObservedChangedKeyPaths = [NSMutableSet set]; for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) { if ([self respondsToSelector:NSSelectorFromString(keyPath)]) { [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:AFHTTPRequestSerializerObserverContext]; } } return self; } - (void)dealloc { for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) { if ([self respondsToSelector:NSSelectorFromString(keyPath)]) { [self removeObserver:self forKeyPath:keyPath context:AFHTTPRequestSerializerObserverContext]; } } } #pragma mark - // Workarounds for crashing behavior using Key-Value Observing with XCTest // See https://github.com/AFNetworking/AFNetworking/issues/2523 - (void)setAllowsCellularAccess:(BOOL)allowsCellularAccess { [self willChangeValueForKey:NSStringFromSelector(@selector(allowsCellularAccess))]; _allowsCellularAccess = allowsCellularAccess; [self didChangeValueForKey:NSStringFromSelector(@selector(allowsCellularAccess))]; } - (void)setCachePolicy:(NSURLRequestCachePolicy)cachePolicy { [self willChangeValueForKey:NSStringFromSelector(@selector(cachePolicy))]; _cachePolicy = cachePolicy; [self didChangeValueForKey:NSStringFromSelector(@selector(cachePolicy))]; } - (void)setHTTPShouldHandleCookies:(BOOL)HTTPShouldHandleCookies { [self willChangeValueForKey:NSStringFromSelector(@selector(HTTPShouldHandleCookies))]; _HTTPShouldHandleCookies = HTTPShouldHandleCookies; [self didChangeValueForKey:NSStringFromSelector(@selector(HTTPShouldHandleCookies))]; } - (void)setHTTPShouldUsePipelining:(BOOL)HTTPShouldUsePipelining { [self willChangeValueForKey:NSStringFromSelector(@selector(HTTPShouldUsePipelining))]; _HTTPShouldUsePipelining = HTTPShouldUsePipelining; [self didChangeValueForKey:NSStringFromSelector(@selector(HTTPShouldUsePipelining))]; } - (void)setNetworkServiceType:(NSURLRequestNetworkServiceType)networkServiceType { [self willChangeValueForKey:NSStringFromSelector(@selector(networkServiceType))]; _networkServiceType = networkServiceType; [self didChangeValueForKey:NSStringFromSelector(@selector(networkServiceType))]; } - (void)setTimeoutInterval:(NSTimeInterval)timeoutInterval { [self willChangeValueForKey:NSStringFromSelector(@selector(timeoutInterval))]; _timeoutInterval = timeoutInterval; [self didChangeValueForKey:NSStringFromSelector(@selector(timeoutInterval))]; } #pragma mark - - (NSDictionary *)HTTPRequestHeaders { return [NSDictionary dictionaryWithDictionary:self.mutableHTTPRequestHeaders]; } - (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field { [self.mutableHTTPRequestHeaders setValue:value forKey:field]; } - (NSString *)valueForHTTPHeaderField:(NSString *)field { return [self.mutableHTTPRequestHeaders valueForKey:field]; } - (void)setAuthorizationHeaderFieldWithUsername:(NSString *)username password:(NSString *)password { NSData *basicAuthCredentials = [[NSString stringWithFormat:@"%@:%@", username, password] dataUsingEncoding:NSUTF8StringEncoding]; NSString *base64AuthCredentials = [basicAuthCredentials base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0]; [self setValue:[NSString stringWithFormat:@"Basic %@", base64AuthCredentials] forHTTPHeaderField:@"Authorization"]; } - (void)clearAuthorizationHeader { [self.mutableHTTPRequestHeaders removeObjectForKey:@"Authorization"]; } #pragma mark - - (void)setQueryStringSerializationWithStyle:(AFHTTPRequestQueryStringSerializationStyle)style { self.queryStringSerializationStyle = style; self.queryStringSerialization = nil; } - (void)setQueryStringSerializationWithBlock:(NSString *(^)(NSURLRequest *, id, NSError *__autoreleasing *))block { self.queryStringSerialization = block; } #pragma mark - - (NSMutableURLRequest *)requestWithMethod:(NSString *)method URLString:(NSString *)URLString parameters:(id)parameters error:(NSError *__autoreleasing *)error { NSParameterAssert(method); NSParameterAssert(URLString); NSURL *url = [NSURL URLWithString:URLString]; NSParameterAssert(url); NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:url]; mutableRequest.HTTPMethod = method; for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) { if ([self.mutableObservedChangedKeyPaths containsObject:keyPath]) { [mutableRequest setValue:[self valueForKeyPath:keyPath] forKey:keyPath]; } } mutableRequest = [[self requestBySerializingRequest:mutableRequest withParameters:parameters error:error] mutableCopy]; return mutableRequest; } - (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method URLString:(NSString *)URLString parameters:(NSDictionary *)parameters constructingBodyWithBlock:(void (^)(id formData))block error:(NSError *__autoreleasing *)error { NSParameterAssert(method); NSParameterAssert(![method isEqualToString:@"GET"] && ![method isEqualToString:@"HEAD"]); NSMutableURLRequest *mutableRequest = [self requestWithMethod:method URLString:URLString parameters:nil error:error]; __block AFStreamingMultipartFormData *formData = [[AFStreamingMultipartFormData alloc] initWithURLRequest:mutableRequest stringEncoding:NSUTF8StringEncoding]; if (parameters) { for (AFQueryStringPair *pair in AFQueryStringPairsFromDictionary(parameters)) { NSData *data = nil; if ([pair.value isKindOfClass:[NSData class]]) { data = pair.value; } else if ([pair.value isEqual:[NSNull null]]) { data = [NSData data]; } else { data = [[pair.value description] dataUsingEncoding:self.stringEncoding]; } if (data) { [formData appendPartWithFormData:data name:[pair.field description]]; } } } if (block) { block(formData); } return [formData requestByFinalizingMultipartFormData]; } - (NSMutableURLRequest *)requestWithMultipartFormRequest:(NSURLRequest *)request writingStreamContentsToFile:(NSURL *)fileURL completionHandler:(void (^)(NSError *error))handler { NSParameterAssert(request.HTTPBodyStream); NSParameterAssert([fileURL isFileURL]); NSInputStream *inputStream = request.HTTPBodyStream; NSOutputStream *outputStream = [[NSOutputStream alloc] initWithURL:fileURL append:NO]; __block NSError *error = nil; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [inputStream open]; [outputStream open]; while ([inputStream hasBytesAvailable] && [outputStream hasSpaceAvailable]) { uint8_t buffer[1024]; NSInteger bytesRead = [inputStream read:buffer maxLength:1024]; if (inputStream.streamError || bytesRead < 0) { error = inputStream.streamError; break; } NSInteger bytesWritten = [outputStream write:buffer maxLength:(NSUInteger)bytesRead]; if (outputStream.streamError || bytesWritten < 0) { error = outputStream.streamError; break; } if (bytesRead == 0 && bytesWritten == 0) { break; } } [outputStream close]; [inputStream close]; if (handler) { dispatch_async(dispatch_get_main_queue(), ^{ handler(error); }); } }); NSMutableURLRequest *mutableRequest = [request mutableCopy]; mutableRequest.HTTPBodyStream = nil; return mutableRequest; } #pragma mark - AFURLRequestSerialization - (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request withParameters:(id)parameters error:(NSError *__autoreleasing *)error { NSParameterAssert(request); NSMutableURLRequest *mutableRequest = [request mutableCopy]; [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) { if (![request valueForHTTPHeaderField:field]) { [mutableRequest setValue:value forHTTPHeaderField:field]; } }]; NSString *query = nil; if (parameters) { if (self.queryStringSerialization) { NSError *serializationError; query = self.queryStringSerialization(request, parameters, &serializationError); if (serializationError) { if (error) { *error = serializationError; } return nil; } } else { switch (self.queryStringSerializationStyle) { case AFHTTPRequestQueryStringDefaultStyle: query = AFQueryStringFromParameters(parameters); break; } } } if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) { if (query && query.length > 0) { mutableRequest.URL = [NSURL URLWithString:[[mutableRequest.URL absoluteString] stringByAppendingFormat:mutableRequest.URL.query ? @"&%@" : @"?%@", query]]; } } else { // #2864: an empty string is a valid x-www-form-urlencoded payload if (!query) { query = @""; } if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) { [mutableRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; } [mutableRequest setHTTPBody:[query dataUsingEncoding:self.stringEncoding]]; } return mutableRequest; } #pragma mark - NSKeyValueObserving + (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key { if ([AFHTTPRequestSerializerObservedKeyPaths() containsObject:key]) { return NO; } return [super automaticallyNotifiesObserversForKey:key]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(__unused id)object change:(NSDictionary *)change context:(void *)context { if (context == AFHTTPRequestSerializerObserverContext) { if ([change[NSKeyValueChangeNewKey] isEqual:[NSNull null]]) { [self.mutableObservedChangedKeyPaths removeObject:keyPath]; } else { [self.mutableObservedChangedKeyPaths addObject:keyPath]; } } } #pragma mark - NSSecureCoding + (BOOL)supportsSecureCoding { return YES; } - (instancetype)initWithCoder:(NSCoder *)decoder { self = [self init]; if (!self) { return nil; } self.mutableHTTPRequestHeaders = [[decoder decodeObjectOfClass:[NSDictionary class] forKey:NSStringFromSelector(@selector(mutableHTTPRequestHeaders))] mutableCopy]; self.queryStringSerializationStyle = (AFHTTPRequestQueryStringSerializationStyle)[[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(queryStringSerializationStyle))] unsignedIntegerValue]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [coder encodeObject:self.mutableHTTPRequestHeaders forKey:NSStringFromSelector(@selector(mutableHTTPRequestHeaders))]; [coder encodeInteger:self.queryStringSerializationStyle forKey:NSStringFromSelector(@selector(queryStringSerializationStyle))]; } #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { AFHTTPRequestSerializer *serializer = [[[self class] allocWithZone:zone] init]; serializer.mutableHTTPRequestHeaders = [self.mutableHTTPRequestHeaders mutableCopyWithZone:zone]; serializer.queryStringSerializationStyle = self.queryStringSerializationStyle; serializer.queryStringSerialization = self.queryStringSerialization; return serializer; } @end #pragma mark - static NSString * AFCreateMultipartFormBoundary() { return [NSString stringWithFormat:@"Boundary+%08X%08X", arc4random(), arc4random()]; } static NSString * const kAFMultipartFormCRLF = @"\r\n"; static inline NSString * AFMultipartFormInitialBoundary(NSString *boundary) { return [NSString stringWithFormat:@"--%@%@", boundary, kAFMultipartFormCRLF]; } static inline NSString * AFMultipartFormEncapsulationBoundary(NSString *boundary) { return [NSString stringWithFormat:@"%@--%@%@", kAFMultipartFormCRLF, boundary, kAFMultipartFormCRLF]; } static inline NSString * AFMultipartFormFinalBoundary(NSString *boundary) { return [NSString stringWithFormat:@"%@--%@--%@", kAFMultipartFormCRLF, boundary, kAFMultipartFormCRLF]; } static inline NSString * AFContentTypeForPathExtension(NSString *extension) { NSString *UTI = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)extension, NULL); NSString *contentType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)UTI, kUTTagClassMIMEType); if (!contentType) { return @"application/octet-stream"; } else { return contentType; } } NSUInteger const kAFUploadStream3GSuggestedPacketSize = 1024 * 16; NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2; @interface AFHTTPBodyPart : NSObject @property (nonatomic, assign) NSStringEncoding stringEncoding; @property (nonatomic, strong) NSDictionary *headers; @property (nonatomic, copy) NSString *boundary; @property (nonatomic, strong) id body; @property (nonatomic, assign) unsigned long long bodyContentLength; @property (nonatomic, strong) NSInputStream *inputStream; @property (nonatomic, assign) BOOL hasInitialBoundary; @property (nonatomic, assign) BOOL hasFinalBoundary; @property (readonly, nonatomic, assign, getter = hasBytesAvailable) BOOL bytesAvailable; @property (readonly, nonatomic, assign) unsigned long long contentLength; - (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)length; @end @interface AFMultipartBodyStream : NSInputStream @property (nonatomic, assign) NSUInteger numberOfBytesInPacket; @property (nonatomic, assign) NSTimeInterval delay; @property (nonatomic, strong) NSInputStream *inputStream; @property (readonly, nonatomic, assign) unsigned long long contentLength; @property (readonly, nonatomic, assign, getter = isEmpty) BOOL empty; - (instancetype)initWithStringEncoding:(NSStringEncoding)encoding; - (void)setInitialAndFinalBoundaries; - (void)appendHTTPBodyPart:(AFHTTPBodyPart *)bodyPart; @end #pragma mark - @interface AFStreamingMultipartFormData () @property (readwrite, nonatomic, copy) NSMutableURLRequest *request; @property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding; @property (readwrite, nonatomic, copy) NSString *boundary; @property (readwrite, nonatomic, strong) AFMultipartBodyStream *bodyStream; @end @implementation AFStreamingMultipartFormData - (instancetype)initWithURLRequest:(NSMutableURLRequest *)urlRequest stringEncoding:(NSStringEncoding)encoding { self = [super init]; if (!self) { return nil; } self.request = urlRequest; self.stringEncoding = encoding; self.boundary = AFCreateMultipartFormBoundary(); self.bodyStream = [[AFMultipartBodyStream alloc] initWithStringEncoding:encoding]; return self; } - (BOOL)appendPartWithFileURL:(NSURL *)fileURL name:(NSString *)name error:(NSError * __autoreleasing *)error { NSParameterAssert(fileURL); NSParameterAssert(name); NSString *fileName = [fileURL lastPathComponent]; NSString *mimeType = AFContentTypeForPathExtension([fileURL pathExtension]); return [self appendPartWithFileURL:fileURL name:name fileName:fileName mimeType:mimeType error:error]; } - (BOOL)appendPartWithFileURL:(NSURL *)fileURL name:(NSString *)name fileName:(NSString *)fileName mimeType:(NSString *)mimeType error:(NSError * __autoreleasing *)error { NSParameterAssert(fileURL); NSParameterAssert(name); NSParameterAssert(fileName); NSParameterAssert(mimeType); if (![fileURL isFileURL]) { NSDictionary *userInfo = @{NSLocalizedFailureReasonErrorKey: NSLocalizedStringFromTable(@"Expected URL to be a file URL", @"AFNetworking", nil)}; if (error) { *error = [[NSError alloc] initWithDomain:AFURLRequestSerializationErrorDomain code:NSURLErrorBadURL userInfo:userInfo]; } return NO; } else if ([fileURL checkResourceIsReachableAndReturnError:error] == NO) { NSDictionary *userInfo = @{NSLocalizedFailureReasonErrorKey: NSLocalizedStringFromTable(@"File URL not reachable.", @"AFNetworking", nil)}; if (error) { *error = [[NSError alloc] initWithDomain:AFURLRequestSerializationErrorDomain code:NSURLErrorBadURL userInfo:userInfo]; } return NO; } NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[fileURL path] error:error]; if (!fileAttributes) { return NO; } NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"]; [mutableHeaders setValue:mimeType forKey:@"Content-Type"]; AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init]; bodyPart.stringEncoding = self.stringEncoding; bodyPart.headers = mutableHeaders; bodyPart.boundary = self.boundary; bodyPart.body = fileURL; bodyPart.bodyContentLength = [fileAttributes[NSFileSize] unsignedLongLongValue]; [self.bodyStream appendHTTPBodyPart:bodyPart]; return YES; } - (void)appendPartWithInputStream:(NSInputStream *)inputStream name:(NSString *)name fileName:(NSString *)fileName length:(int64_t)length mimeType:(NSString *)mimeType { NSParameterAssert(name); NSParameterAssert(fileName); NSParameterAssert(mimeType); NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"]; [mutableHeaders setValue:mimeType forKey:@"Content-Type"]; AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init]; bodyPart.stringEncoding = self.stringEncoding; bodyPart.headers = mutableHeaders; bodyPart.boundary = self.boundary; bodyPart.body = inputStream; bodyPart.bodyContentLength = (unsigned long long)length; [self.bodyStream appendHTTPBodyPart:bodyPart]; } - (void)appendPartWithFileData:(NSData *)data name:(NSString *)name fileName:(NSString *)fileName mimeType:(NSString *)mimeType { NSParameterAssert(name); NSParameterAssert(fileName); NSParameterAssert(mimeType); NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"]; [mutableHeaders setValue:mimeType forKey:@"Content-Type"]; [self appendPartWithHeaders:mutableHeaders body:data]; } - (void)appendPartWithFormData:(NSData *)data name:(NSString *)name { NSParameterAssert(name); NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"", name] forKey:@"Content-Disposition"]; [self appendPartWithHeaders:mutableHeaders body:data]; } - (void)appendPartWithHeaders:(NSDictionary *)headers body:(NSData *)body { NSParameterAssert(body); AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init]; bodyPart.stringEncoding = self.stringEncoding; bodyPart.headers = headers; bodyPart.boundary = self.boundary; bodyPart.bodyContentLength = [body length]; bodyPart.body = body; [self.bodyStream appendHTTPBodyPart:bodyPart]; } - (void)throttleBandwidthWithPacketSize:(NSUInteger)numberOfBytes delay:(NSTimeInterval)delay { self.bodyStream.numberOfBytesInPacket = numberOfBytes; self.bodyStream.delay = delay; } - (NSMutableURLRequest *)requestByFinalizingMultipartFormData { if ([self.bodyStream isEmpty]) { return self.request; } // Reset the initial and final boundaries to ensure correct Content-Length [self.bodyStream setInitialAndFinalBoundaries]; [self.request setHTTPBodyStream:self.bodyStream]; [self.request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", self.boundary] forHTTPHeaderField:@"Content-Type"]; [self.request setValue:[NSString stringWithFormat:@"%llu", [self.bodyStream contentLength]] forHTTPHeaderField:@"Content-Length"]; return self.request; } @end #pragma mark - @interface NSStream () @property (readwrite) NSStreamStatus streamStatus; @property (readwrite, copy) NSError *streamError; @end @interface AFMultipartBodyStream () @property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding; @property (readwrite, nonatomic, strong) NSMutableArray *HTTPBodyParts; @property (readwrite, nonatomic, strong) NSEnumerator *HTTPBodyPartEnumerator; @property (readwrite, nonatomic, strong) AFHTTPBodyPart *currentHTTPBodyPart; @property (readwrite, nonatomic, strong) NSOutputStream *outputStream; @property (readwrite, nonatomic, strong) NSMutableData *buffer; @end @implementation AFMultipartBodyStream #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wimplicit-atomic-properties" #if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1100) @synthesize delegate; #endif @synthesize streamStatus; @synthesize streamError; #pragma clang diagnostic pop - (instancetype)initWithStringEncoding:(NSStringEncoding)encoding { self = [super init]; if (!self) { return nil; } self.stringEncoding = encoding; self.HTTPBodyParts = [NSMutableArray array]; self.numberOfBytesInPacket = NSIntegerMax; return self; } - (void)setInitialAndFinalBoundaries { if ([self.HTTPBodyParts count] > 0) { for (AFHTTPBodyPart *bodyPart in self.HTTPBodyParts) { bodyPart.hasInitialBoundary = NO; bodyPart.hasFinalBoundary = NO; } [[self.HTTPBodyParts firstObject] setHasInitialBoundary:YES]; [[self.HTTPBodyParts lastObject] setHasFinalBoundary:YES]; } } - (void)appendHTTPBodyPart:(AFHTTPBodyPart *)bodyPart { [self.HTTPBodyParts addObject:bodyPart]; } - (BOOL)isEmpty { return [self.HTTPBodyParts count] == 0; } #pragma mark - NSInputStream - (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)length { if ([self streamStatus] == NSStreamStatusClosed) { return 0; } NSInteger totalNumberOfBytesRead = 0; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" while ((NSUInteger)totalNumberOfBytesRead < MIN(length, self.numberOfBytesInPacket)) { if (!self.currentHTTPBodyPart || ![self.currentHTTPBodyPart hasBytesAvailable]) { if (!(self.currentHTTPBodyPart = [self.HTTPBodyPartEnumerator nextObject])) { break; } } else { NSUInteger maxLength = MIN(length, self.numberOfBytesInPacket) - (NSUInteger)totalNumberOfBytesRead; NSInteger numberOfBytesRead = [self.currentHTTPBodyPart read:&buffer[totalNumberOfBytesRead] maxLength:maxLength]; if (numberOfBytesRead == -1) { self.streamError = self.currentHTTPBodyPart.inputStream.streamError; break; } else { totalNumberOfBytesRead += numberOfBytesRead; if (self.delay > 0.0f) { [NSThread sleepForTimeInterval:self.delay]; } } } } #pragma clang diagnostic pop return totalNumberOfBytesRead; } - (BOOL)getBuffer:(__unused uint8_t **)buffer length:(__unused NSUInteger *)len { return NO; } - (BOOL)hasBytesAvailable { return [self streamStatus] == NSStreamStatusOpen; } #pragma mark - NSStream - (void)open { if (self.streamStatus == NSStreamStatusOpen) { return; } self.streamStatus = NSStreamStatusOpen; [self setInitialAndFinalBoundaries]; self.HTTPBodyPartEnumerator = [self.HTTPBodyParts objectEnumerator]; } - (void)close { self.streamStatus = NSStreamStatusClosed; } - (id)propertyForKey:(__unused NSString *)key { return nil; } - (BOOL)setProperty:(__unused id)property forKey:(__unused NSString *)key { return NO; } - (void)scheduleInRunLoop:(__unused NSRunLoop *)aRunLoop forMode:(__unused NSString *)mode {} - (void)removeFromRunLoop:(__unused NSRunLoop *)aRunLoop forMode:(__unused NSString *)mode {} - (unsigned long long)contentLength { unsigned long long length = 0; for (AFHTTPBodyPart *bodyPart in self.HTTPBodyParts) { length += [bodyPart contentLength]; } return length; } #pragma mark - Undocumented CFReadStream Bridged Methods - (void)_scheduleInCFRunLoop:(__unused CFRunLoopRef)aRunLoop forMode:(__unused CFStringRef)aMode {} - (void)_unscheduleFromCFRunLoop:(__unused CFRunLoopRef)aRunLoop forMode:(__unused CFStringRef)aMode {} - (BOOL)_setCFClientFlags:(__unused CFOptionFlags)inFlags callback:(__unused CFReadStreamClientCallBack)inCallback context:(__unused CFStreamClientContext *)inContext { return NO; } #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { AFMultipartBodyStream *bodyStreamCopy = [[[self class] allocWithZone:zone] initWithStringEncoding:self.stringEncoding]; for (AFHTTPBodyPart *bodyPart in self.HTTPBodyParts) { [bodyStreamCopy appendHTTPBodyPart:[bodyPart copy]]; } [bodyStreamCopy setInitialAndFinalBoundaries]; return bodyStreamCopy; } @end #pragma mark - typedef enum { AFEncapsulationBoundaryPhase = 1, AFHeaderPhase = 2, AFBodyPhase = 3, AFFinalBoundaryPhase = 4, } AFHTTPBodyPartReadPhase; @interface AFHTTPBodyPart () { AFHTTPBodyPartReadPhase _phase; NSInputStream *_inputStream; unsigned long long _phaseReadOffset; } - (BOOL)transitionToNextPhase; - (NSInteger)readData:(NSData *)data intoBuffer:(uint8_t *)buffer maxLength:(NSUInteger)length; @end @implementation AFHTTPBodyPart - (instancetype)init { self = [super init]; if (!self) { return nil; } [self transitionToNextPhase]; return self; } - (void)dealloc { if (_inputStream) { [_inputStream close]; _inputStream = nil; } } - (NSInputStream *)inputStream { if (!_inputStream) { if ([self.body isKindOfClass:[NSData class]]) { _inputStream = [NSInputStream inputStreamWithData:self.body]; } else if ([self.body isKindOfClass:[NSURL class]]) { _inputStream = [NSInputStream inputStreamWithURL:self.body]; } else if ([self.body isKindOfClass:[NSInputStream class]]) { _inputStream = self.body; } else { _inputStream = [NSInputStream inputStreamWithData:[NSData data]]; } } return _inputStream; } - (NSString *)stringForHeaders { NSMutableString *headerString = [NSMutableString string]; for (NSString *field in [self.headers allKeys]) { [headerString appendString:[NSString stringWithFormat:@"%@: %@%@", field, [self.headers valueForKey:field], kAFMultipartFormCRLF]]; } [headerString appendString:kAFMultipartFormCRLF]; return [NSString stringWithString:headerString]; } - (unsigned long long)contentLength { unsigned long long length = 0; NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary(self.boundary) : AFMultipartFormEncapsulationBoundary(self.boundary)) dataUsingEncoding:self.stringEncoding]; length += [encapsulationBoundaryData length]; NSData *headersData = [[self stringForHeaders] dataUsingEncoding:self.stringEncoding]; length += [headersData length]; length += _bodyContentLength; NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary(self.boundary) dataUsingEncoding:self.stringEncoding] : [NSData data]); length += [closingBoundaryData length]; return length; } - (BOOL)hasBytesAvailable { // Allows `read:maxLength:` to be called again if `AFMultipartFormFinalBoundary` doesn't fit into the available buffer if (_phase == AFFinalBoundaryPhase) { return YES; } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wcovered-switch-default" switch (self.inputStream.streamStatus) { case NSStreamStatusNotOpen: case NSStreamStatusOpening: case NSStreamStatusOpen: case NSStreamStatusReading: case NSStreamStatusWriting: return YES; case NSStreamStatusAtEnd: case NSStreamStatusClosed: case NSStreamStatusError: default: return NO; } #pragma clang diagnostic pop } - (NSInteger)read:(uint8_t *)buffer maxLength:(NSUInteger)length { NSInteger totalNumberOfBytesRead = 0; if (_phase == AFEncapsulationBoundaryPhase) { NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary(self.boundary) : AFMultipartFormEncapsulationBoundary(self.boundary)) dataUsingEncoding:self.stringEncoding]; totalNumberOfBytesRead += [self readData:encapsulationBoundaryData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; } if (_phase == AFHeaderPhase) { NSData *headersData = [[self stringForHeaders] dataUsingEncoding:self.stringEncoding]; totalNumberOfBytesRead += [self readData:headersData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; } if (_phase == AFBodyPhase) { NSInteger numberOfBytesRead = 0; numberOfBytesRead = [self.inputStream read:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; if (numberOfBytesRead == -1) { return -1; } else { totalNumberOfBytesRead += numberOfBytesRead; if ([self.inputStream streamStatus] >= NSStreamStatusAtEnd) { [self transitionToNextPhase]; } } } if (_phase == AFFinalBoundaryPhase) { NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary(self.boundary) dataUsingEncoding:self.stringEncoding] : [NSData data]); totalNumberOfBytesRead += [self readData:closingBoundaryData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; } return totalNumberOfBytesRead; } - (NSInteger)readData:(NSData *)data intoBuffer:(uint8_t *)buffer maxLength:(NSUInteger)length { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" NSRange range = NSMakeRange((NSUInteger)_phaseReadOffset, MIN([data length] - ((NSUInteger)_phaseReadOffset), length)); [data getBytes:buffer range:range]; #pragma clang diagnostic pop _phaseReadOffset += range.length; if (((NSUInteger)_phaseReadOffset) >= [data length]) { [self transitionToNextPhase]; } return (NSInteger)range.length; } - (BOOL)transitionToNextPhase { if (![[NSThread currentThread] isMainThread]) { dispatch_sync(dispatch_get_main_queue(), ^{ [self transitionToNextPhase]; }); return YES; } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wcovered-switch-default" switch (_phase) { case AFEncapsulationBoundaryPhase: _phase = AFHeaderPhase; break; case AFHeaderPhase: [self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; [self.inputStream open]; _phase = AFBodyPhase; break; case AFBodyPhase: [self.inputStream close]; _phase = AFFinalBoundaryPhase; break; case AFFinalBoundaryPhase: default: _phase = AFEncapsulationBoundaryPhase; break; } _phaseReadOffset = 0; #pragma clang diagnostic pop return YES; } #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { AFHTTPBodyPart *bodyPart = [[[self class] allocWithZone:zone] init]; bodyPart.stringEncoding = self.stringEncoding; bodyPart.headers = self.headers; bodyPart.bodyContentLength = self.bodyContentLength; bodyPart.body = self.body; bodyPart.boundary = self.boundary; return bodyPart; } @end #pragma mark - @implementation AFJSONRequestSerializer + (instancetype)serializer { return [self serializerWithWritingOptions:(NSJSONWritingOptions)0]; } + (instancetype)serializerWithWritingOptions:(NSJSONWritingOptions)writingOptions { AFJSONRequestSerializer *serializer = [[self alloc] init]; serializer.writingOptions = writingOptions; return serializer; } #pragma mark - AFURLRequestSerialization - (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request withParameters:(id)parameters error:(NSError *__autoreleasing *)error { NSParameterAssert(request); if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) { return [super requestBySerializingRequest:request withParameters:parameters error:error]; } NSMutableURLRequest *mutableRequest = [request mutableCopy]; [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) { if (![request valueForHTTPHeaderField:field]) { [mutableRequest setValue:value forHTTPHeaderField:field]; } }]; if (parameters) { if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) { [mutableRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; } [mutableRequest setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:self.writingOptions error:error]]; } return mutableRequest; } #pragma mark - NSSecureCoding - (instancetype)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (!self) { return nil; } self.writingOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(writingOptions))] unsignedIntegerValue]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeInteger:self.writingOptions forKey:NSStringFromSelector(@selector(writingOptions))]; } #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { AFJSONRequestSerializer *serializer = [super copyWithZone:zone]; serializer.writingOptions = self.writingOptions; return serializer; } @end #pragma mark - @implementation AFPropertyListRequestSerializer + (instancetype)serializer { return [self serializerWithFormat:NSPropertyListXMLFormat_v1_0 writeOptions:0]; } + (instancetype)serializerWithFormat:(NSPropertyListFormat)format writeOptions:(NSPropertyListWriteOptions)writeOptions { AFPropertyListRequestSerializer *serializer = [[self alloc] init]; serializer.format = format; serializer.writeOptions = writeOptions; return serializer; } #pragma mark - AFURLRequestSerializer - (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request withParameters:(id)parameters error:(NSError *__autoreleasing *)error { NSParameterAssert(request); if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) { return [super requestBySerializingRequest:request withParameters:parameters error:error]; } NSMutableURLRequest *mutableRequest = [request mutableCopy]; [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) { if (![request valueForHTTPHeaderField:field]) { [mutableRequest setValue:value forHTTPHeaderField:field]; } }]; if (parameters) { if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) { [mutableRequest setValue:@"application/x-plist" forHTTPHeaderField:@"Content-Type"]; } [mutableRequest setHTTPBody:[NSPropertyListSerialization dataWithPropertyList:parameters format:self.format options:self.writeOptions error:error]]; } return mutableRequest; } #pragma mark - NSSecureCoding - (instancetype)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (!self) { return nil; } self.format = (NSPropertyListFormat)[[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(format))] unsignedIntegerValue]; self.writeOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(writeOptions))] unsignedIntegerValue]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeInteger:self.format forKey:NSStringFromSelector(@selector(format))]; [coder encodeObject:@(self.writeOptions) forKey:NSStringFromSelector(@selector(writeOptions))]; } #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { AFPropertyListRequestSerializer *serializer = [super copyWithZone:zone]; serializer.format = self.format; serializer.writeOptions = self.writeOptions; return serializer; } @end ================================================ FILE: Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.h ================================================ // AFURLResponseSerialization.h // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import NS_ASSUME_NONNULL_BEGIN /** The `AFURLResponseSerialization` protocol is adopted by an object that decodes data into a more useful object representation, according to details in the server response. Response serializers may additionally perform validation on the incoming response and data. For example, a JSON response serializer may check for an acceptable status code (`2XX` range) and content type (`application/json`), decoding a valid JSON response into an object. */ @protocol AFURLResponseSerialization /** The response object decoded from the data associated with a specified response. @param response The response to be processed. @param data The response data to be decoded. @param error The error that occurred while attempting to decode the response data. @return The object decoded from the specified response data. */ - (nullable id)responseObjectForResponse:(nullable NSURLResponse *)response data:(nullable NSData *)data error:(NSError * _Nullable __autoreleasing *)error NS_SWIFT_NOTHROW; @end #pragma mark - /** `AFHTTPResponseSerializer` conforms to the `AFURLRequestSerialization` & `AFURLResponseSerialization` protocols, offering a concrete base implementation of query string / URL form-encoded parameter serialization and default request headers, as well as response status code and content type validation. Any request or response serializer dealing with HTTP is encouraged to subclass `AFHTTPResponseSerializer` in order to ensure consistent default behavior. */ @interface AFHTTPResponseSerializer : NSObject - (instancetype)init; /** The string encoding used to serialize data received from the server, when no string encoding is specified by the response. `NSUTF8StringEncoding` by default. */ @property (nonatomic, assign) NSStringEncoding stringEncoding; /** Creates and returns a serializer with default configuration. */ + (instancetype)serializer; ///----------------------------------------- /// @name Configuring Response Serialization ///----------------------------------------- /** The acceptable HTTP status codes for responses. When non-`nil`, responses with status codes not contained by the set will result in an error during validation. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html */ @property (nonatomic, copy, nullable) NSIndexSet *acceptableStatusCodes; /** The acceptable MIME types for responses. When non-`nil`, responses with a `Content-Type` with MIME types that do not intersect with the set will result in an error during validation. */ @property (nonatomic, copy, nullable) NSSet *acceptableContentTypes; /** Validates the specified response and data. In its base implementation, this method checks for an acceptable status code and content type. Subclasses may wish to add other domain-specific checks. @param response The response to be validated. @param data The data associated with the response. @param error The error that occurred while attempting to validate the response. @return `YES` if the response is valid, otherwise `NO`. */ - (BOOL)validateResponse:(nullable NSHTTPURLResponse *)response data:(nullable NSData *)data error:(NSError * _Nullable __autoreleasing *)error; @end #pragma mark - /** `AFJSONResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes JSON responses. By default, `AFJSONResponseSerializer` accepts the following MIME types, which includes the official standard, `application/json`, as well as other commonly-used types: - `application/json` - `text/json` - `text/javascript` */ @interface AFJSONResponseSerializer : AFHTTPResponseSerializer - (instancetype)init; /** Options for reading the response JSON data and creating the Foundation objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONReadingOptions". `0` by default. */ @property (nonatomic, assign) NSJSONReadingOptions readingOptions; /** Whether to remove keys with `NSNull` values from response JSON. Defaults to `NO`. */ @property (nonatomic, assign) BOOL removesKeysWithNullValues; /** Creates and returns a JSON serializer with specified reading and writing options. @param readingOptions The specified JSON reading options. */ + (instancetype)serializerWithReadingOptions:(NSJSONReadingOptions)readingOptions; @end #pragma mark - /** `AFXMLParserResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLParser` objects. By default, `AFXMLParserResponseSerializer` accepts the following MIME types, which includes the official standard, `application/xml`, as well as other commonly-used types: - `application/xml` - `text/xml` */ @interface AFXMLParserResponseSerializer : AFHTTPResponseSerializer @end #pragma mark - #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED /** `AFXMLDocumentResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLDocument` objects. By default, `AFXMLDocumentResponseSerializer` accepts the following MIME types, which includes the official standard, `application/xml`, as well as other commonly-used types: - `application/xml` - `text/xml` */ @interface AFXMLDocumentResponseSerializer : AFHTTPResponseSerializer - (instancetype)init; /** Input and output options specifically intended for `NSXMLDocument` objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONReadingOptions". `0` by default. */ @property (nonatomic, assign) NSUInteger options; /** Creates and returns an XML document serializer with the specified options. @param mask The XML document options. */ + (instancetype)serializerWithXMLDocumentOptions:(NSUInteger)mask; @end #endif #pragma mark - /** `AFPropertyListResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLDocument` objects. By default, `AFPropertyListResponseSerializer` accepts the following MIME types: - `application/x-plist` */ @interface AFPropertyListResponseSerializer : AFHTTPResponseSerializer - (instancetype)init; /** The property list format. Possible values are described in "NSPropertyListFormat". */ @property (nonatomic, assign) NSPropertyListFormat format; /** The property list reading options. Possible values are described in "NSPropertyListMutabilityOptions." */ @property (nonatomic, assign) NSPropertyListReadOptions readOptions; /** Creates and returns a property list serializer with a specified format, read options, and write options. @param format The property list format. @param readOptions The property list reading options. */ + (instancetype)serializerWithFormat:(NSPropertyListFormat)format readOptions:(NSPropertyListReadOptions)readOptions; @end #pragma mark - /** `AFImageResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes image responses. By default, `AFImageResponseSerializer` accepts the following MIME types, which correspond to the image formats supported by UIImage or NSImage: - `image/tiff` - `image/jpeg` - `image/gif` - `image/png` - `image/ico` - `image/x-icon` - `image/bmp` - `image/x-bmp` - `image/x-xbitmap` - `image/x-win-bitmap` */ @interface AFImageResponseSerializer : AFHTTPResponseSerializer #if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH /** The scale factor used when interpreting the image data to construct `responseImage`. Specifying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the size property. This is set to the value of scale of the main screen by default, which automatically scales images for retina displays, for instance. */ @property (nonatomic, assign) CGFloat imageScale; /** Whether to automatically inflate response image data for compressed formats (such as PNG or JPEG). Enabling this can significantly improve drawing performance on iOS when used with `setCompletionBlockWithSuccess:failure:`, as it allows a bitmap representation to be constructed in the background rather than on the main thread. `YES` by default. */ @property (nonatomic, assign) BOOL automaticallyInflatesResponseImage; #endif @end #pragma mark - /** `AFCompoundSerializer` is a subclass of `AFHTTPResponseSerializer` that delegates the response serialization to the first `AFHTTPResponseSerializer` object that returns an object for `responseObjectForResponse:data:error:`, falling back on the default behavior of `AFHTTPResponseSerializer`. This is useful for supporting multiple potential types and structures of server responses with a single serializer. */ @interface AFCompoundResponseSerializer : AFHTTPResponseSerializer /** The component response serializers. */ @property (readonly, nonatomic, copy) NSArray > *responseSerializers; /** Creates and returns a compound serializer comprised of the specified response serializers. @warning Each response serializer specified must be a subclass of `AFHTTPResponseSerializer`, and response to `-validateResponse:data:error:`. */ + (instancetype)compoundSerializerWithResponseSerializers:(NSArray > *)responseSerializers; @end ///---------------- /// @name Constants ///---------------- /** ## Error Domains The following error domain is predefined. - `NSString * const AFURLResponseSerializationErrorDomain` ### Constants `AFURLResponseSerializationErrorDomain` AFURLResponseSerializer errors. Error codes for `AFURLResponseSerializationErrorDomain` correspond to codes in `NSURLErrorDomain`. */ FOUNDATION_EXPORT NSString * const AFURLResponseSerializationErrorDomain; /** ## User info dictionary keys These keys may exist in the user info dictionary, in addition to those defined for NSError. - `NSString * const AFNetworkingOperationFailingURLResponseErrorKey` - `NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey` ### Constants `AFNetworkingOperationFailingURLResponseErrorKey` The corresponding value is an `NSURLResponse` containing the response of the operation associated with an error. This key is only present in the `AFURLResponseSerializationErrorDomain`. `AFNetworkingOperationFailingURLResponseDataErrorKey` The corresponding value is an `NSData` containing the original data of the operation associated with an error. This key is only present in the `AFURLResponseSerializationErrorDomain`. */ FOUNDATION_EXPORT NSString * const AFNetworkingOperationFailingURLResponseErrorKey; FOUNDATION_EXPORT NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey; NS_ASSUME_NONNULL_END ================================================ FILE: Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.m ================================================ // AFURLResponseSerialization.m // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "AFURLResponseSerialization.h" #import #if TARGET_OS_IOS #import #elif TARGET_OS_WATCH #import #elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) #import #endif NSString * const AFURLResponseSerializationErrorDomain = @"com.alamofire.error.serialization.response"; NSString * const AFNetworkingOperationFailingURLResponseErrorKey = @"com.alamofire.serialization.response.error.response"; NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey = @"com.alamofire.serialization.response.error.data"; static NSError * AFErrorWithUnderlyingError(NSError *error, NSError *underlyingError) { if (!error) { return underlyingError; } if (!underlyingError || error.userInfo[NSUnderlyingErrorKey]) { return error; } NSMutableDictionary *mutableUserInfo = [error.userInfo mutableCopy]; mutableUserInfo[NSUnderlyingErrorKey] = underlyingError; return [[NSError alloc] initWithDomain:error.domain code:error.code userInfo:mutableUserInfo]; } static BOOL AFErrorOrUnderlyingErrorHasCodeInDomain(NSError *error, NSInteger code, NSString *domain) { if ([error.domain isEqualToString:domain] && error.code == code) { return YES; } else if (error.userInfo[NSUnderlyingErrorKey]) { return AFErrorOrUnderlyingErrorHasCodeInDomain(error.userInfo[NSUnderlyingErrorKey], code, domain); } return NO; } static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingOptions readingOptions) { if ([JSONObject isKindOfClass:[NSArray class]]) { NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:[(NSArray *)JSONObject count]]; for (id value in (NSArray *)JSONObject) { [mutableArray addObject:AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions)]; } return (readingOptions & NSJSONReadingMutableContainers) ? mutableArray : [NSArray arrayWithArray:mutableArray]; } else if ([JSONObject isKindOfClass:[NSDictionary class]]) { NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:JSONObject]; for (id key in [(NSDictionary *)JSONObject allKeys]) { id value = (NSDictionary *)JSONObject[key]; if (!value || [value isEqual:[NSNull null]]) { [mutableDictionary removeObjectForKey:key]; } else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) { mutableDictionary[key] = AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions); } } return (readingOptions & NSJSONReadingMutableContainers) ? mutableDictionary : [NSDictionary dictionaryWithDictionary:mutableDictionary]; } return JSONObject; } @implementation AFHTTPResponseSerializer + (instancetype)serializer { return [[self alloc] init]; } - (instancetype)init { self = [super init]; if (!self) { return nil; } self.stringEncoding = NSUTF8StringEncoding; self.acceptableStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)]; self.acceptableContentTypes = nil; return self; } #pragma mark - - (BOOL)validateResponse:(NSHTTPURLResponse *)response data:(NSData *)data error:(NSError * __autoreleasing *)error { BOOL responseIsValid = YES; NSError *validationError = nil; if (response && [response isKindOfClass:[NSHTTPURLResponse class]]) { if (self.acceptableContentTypes && ![self.acceptableContentTypes containsObject:[response MIMEType]] && !([response MIMEType] == nil && [data length] == 0)) { if ([data length] > 0 && [response URL]) { NSMutableDictionary *mutableUserInfo = [@{ NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: unacceptable content-type: %@", @"AFNetworking", nil), [response MIMEType]], NSURLErrorFailingURLErrorKey:[response URL], AFNetworkingOperationFailingURLResponseErrorKey: response, } mutableCopy]; if (data) { mutableUserInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] = data; } validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:mutableUserInfo], validationError); } responseIsValid = NO; } if (self.acceptableStatusCodes && ![self.acceptableStatusCodes containsIndex:(NSUInteger)response.statusCode] && [response URL]) { NSMutableDictionary *mutableUserInfo = [@{ NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: %@ (%ld)", @"AFNetworking", nil), [NSHTTPURLResponse localizedStringForStatusCode:response.statusCode], (long)response.statusCode], NSURLErrorFailingURLErrorKey:[response URL], AFNetworkingOperationFailingURLResponseErrorKey: response, } mutableCopy]; if (data) { mutableUserInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] = data; } validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorBadServerResponse userInfo:mutableUserInfo], validationError); responseIsValid = NO; } } if (error && !responseIsValid) { *error = validationError; } return responseIsValid; } #pragma mark - AFURLResponseSerialization - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { [self validateResponse:(NSHTTPURLResponse *)response data:data error:error]; return data; } #pragma mark - NSSecureCoding + (BOOL)supportsSecureCoding { return YES; } - (instancetype)initWithCoder:(NSCoder *)decoder { self = [self init]; if (!self) { return nil; } self.acceptableStatusCodes = [decoder decodeObjectOfClass:[NSIndexSet class] forKey:NSStringFromSelector(@selector(acceptableStatusCodes))]; self.acceptableContentTypes = [decoder decodeObjectOfClass:[NSIndexSet class] forKey:NSStringFromSelector(@selector(acceptableContentTypes))]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [coder encodeObject:self.acceptableStatusCodes forKey:NSStringFromSelector(@selector(acceptableStatusCodes))]; [coder encodeObject:self.acceptableContentTypes forKey:NSStringFromSelector(@selector(acceptableContentTypes))]; } #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { AFHTTPResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; serializer.acceptableStatusCodes = [self.acceptableStatusCodes copyWithZone:zone]; serializer.acceptableContentTypes = [self.acceptableContentTypes copyWithZone:zone]; return serializer; } @end #pragma mark - @implementation AFJSONResponseSerializer + (instancetype)serializer { return [self serializerWithReadingOptions:(NSJSONReadingOptions)0]; } + (instancetype)serializerWithReadingOptions:(NSJSONReadingOptions)readingOptions { AFJSONResponseSerializer *serializer = [[self alloc] init]; serializer.readingOptions = readingOptions; return serializer; } - (instancetype)init { self = [super init]; if (!self) { return nil; } self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil]; return self; } #pragma mark - AFURLResponseSerialization - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) { return nil; } } id responseObject = nil; NSError *serializationError = nil; // Workaround for behavior of Rails to return a single space for `head :ok` (a workaround for a bug in Safari), which is not interpreted as valid input by NSJSONSerialization. // See https://github.com/rails/rails/issues/1742 BOOL isSpace = [data isEqualToData:[NSData dataWithBytes:" " length:1]]; if (data.length > 0 && !isSpace) { responseObject = [NSJSONSerialization JSONObjectWithData:data options:self.readingOptions error:&serializationError]; } else { return nil; } if (self.removesKeysWithNullValues && responseObject) { responseObject = AFJSONObjectByRemovingKeysWithNullValues(responseObject, self.readingOptions); } if (error) { *error = AFErrorWithUnderlyingError(serializationError, *error); } return responseObject; } #pragma mark - NSSecureCoding - (instancetype)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (!self) { return nil; } self.readingOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(readingOptions))] unsignedIntegerValue]; self.removesKeysWithNullValues = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(removesKeysWithNullValues))] boolValue]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeObject:@(self.readingOptions) forKey:NSStringFromSelector(@selector(readingOptions))]; [coder encodeObject:@(self.removesKeysWithNullValues) forKey:NSStringFromSelector(@selector(removesKeysWithNullValues))]; } #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { AFJSONResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; serializer.readingOptions = self.readingOptions; serializer.removesKeysWithNullValues = self.removesKeysWithNullValues; return serializer; } @end #pragma mark - @implementation AFXMLParserResponseSerializer + (instancetype)serializer { AFXMLParserResponseSerializer *serializer = [[self alloc] init]; return serializer; } - (instancetype)init { self = [super init]; if (!self) { return nil; } self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml", nil]; return self; } #pragma mark - AFURLResponseSerialization - (id)responseObjectForResponse:(NSHTTPURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) { return nil; } } return [[NSXMLParser alloc] initWithData:data]; } @end #pragma mark - #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED @implementation AFXMLDocumentResponseSerializer + (instancetype)serializer { return [self serializerWithXMLDocumentOptions:0]; } + (instancetype)serializerWithXMLDocumentOptions:(NSUInteger)mask { AFXMLDocumentResponseSerializer *serializer = [[self alloc] init]; serializer.options = mask; return serializer; } - (instancetype)init { self = [super init]; if (!self) { return nil; } self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml", nil]; return self; } #pragma mark - AFURLResponseSerialization - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) { return nil; } } NSError *serializationError = nil; NSXMLDocument *document = [[NSXMLDocument alloc] initWithData:data options:self.options error:&serializationError]; if (error) { *error = AFErrorWithUnderlyingError(serializationError, *error); } return document; } #pragma mark - NSSecureCoding - (instancetype)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (!self) { return nil; } self.options = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(options))] unsignedIntegerValue]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeObject:@(self.options) forKey:NSStringFromSelector(@selector(options))]; } #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { AFXMLDocumentResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; serializer.options = self.options; return serializer; } @end #endif #pragma mark - @implementation AFPropertyListResponseSerializer + (instancetype)serializer { return [self serializerWithFormat:NSPropertyListXMLFormat_v1_0 readOptions:0]; } + (instancetype)serializerWithFormat:(NSPropertyListFormat)format readOptions:(NSPropertyListReadOptions)readOptions { AFPropertyListResponseSerializer *serializer = [[self alloc] init]; serializer.format = format; serializer.readOptions = readOptions; return serializer; } - (instancetype)init { self = [super init]; if (!self) { return nil; } self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/x-plist", nil]; return self; } #pragma mark - AFURLResponseSerialization - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) { return nil; } } id responseObject; NSError *serializationError = nil; if (data) { responseObject = [NSPropertyListSerialization propertyListWithData:data options:self.readOptions format:NULL error:&serializationError]; } if (error) { *error = AFErrorWithUnderlyingError(serializationError, *error); } return responseObject; } #pragma mark - NSSecureCoding - (instancetype)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (!self) { return nil; } self.format = (NSPropertyListFormat)[[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(format))] unsignedIntegerValue]; self.readOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(readOptions))] unsignedIntegerValue]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeObject:@(self.format) forKey:NSStringFromSelector(@selector(format))]; [coder encodeObject:@(self.readOptions) forKey:NSStringFromSelector(@selector(readOptions))]; } #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { AFPropertyListResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; serializer.format = self.format; serializer.readOptions = self.readOptions; return serializer; } @end #pragma mark - #if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH #import #import @interface UIImage (AFNetworkingSafeImageLoading) + (UIImage *)af_safeImageWithData:(NSData *)data; @end static NSLock* imageLock = nil; @implementation UIImage (AFNetworkingSafeImageLoading) + (UIImage *)af_safeImageWithData:(NSData *)data { UIImage* image = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ imageLock = [[NSLock alloc] init]; }); [imageLock lock]; image = [UIImage imageWithData:data]; [imageLock unlock]; return image; } @end static UIImage * AFImageWithDataAtScale(NSData *data, CGFloat scale) { UIImage *image = [UIImage af_safeImageWithData:data]; if (image.images) { return image; } return [[UIImage alloc] initWithCGImage:[image CGImage] scale:scale orientation:image.imageOrientation]; } static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *response, NSData *data, CGFloat scale) { if (!data || [data length] == 0) { return nil; } CGImageRef imageRef = NULL; CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); if ([response.MIMEType isEqualToString:@"image/png"]) { imageRef = CGImageCreateWithPNGDataProvider(dataProvider, NULL, true, kCGRenderingIntentDefault); } else if ([response.MIMEType isEqualToString:@"image/jpeg"]) { imageRef = CGImageCreateWithJPEGDataProvider(dataProvider, NULL, true, kCGRenderingIntentDefault); if (imageRef) { CGColorSpaceRef imageColorSpace = CGImageGetColorSpace(imageRef); CGColorSpaceModel imageColorSpaceModel = CGColorSpaceGetModel(imageColorSpace); // CGImageCreateWithJPEGDataProvider does not properly handle CMKY, so fall back to AFImageWithDataAtScale if (imageColorSpaceModel == kCGColorSpaceModelCMYK) { CGImageRelease(imageRef); imageRef = NULL; } } } CGDataProviderRelease(dataProvider); UIImage *image = AFImageWithDataAtScale(data, scale); if (!imageRef) { if (image.images || !image) { return image; } imageRef = CGImageCreateCopy([image CGImage]); if (!imageRef) { return nil; } } size_t width = CGImageGetWidth(imageRef); size_t height = CGImageGetHeight(imageRef); size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef); if (width * height > 1024 * 1024 || bitsPerComponent > 8) { CGImageRelease(imageRef); return image; } // CGImageGetBytesPerRow() calculates incorrectly in iOS 5.0, so defer to CGBitmapContextCreate size_t bytesPerRow = 0; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace); CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); if (colorSpaceModel == kCGColorSpaceModelRGB) { uint32_t alpha = (bitmapInfo & kCGBitmapAlphaInfoMask); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wassign-enum" if (alpha == kCGImageAlphaNone) { bitmapInfo &= ~kCGBitmapAlphaInfoMask; bitmapInfo |= kCGImageAlphaNoneSkipFirst; } else if (!(alpha == kCGImageAlphaNoneSkipFirst || alpha == kCGImageAlphaNoneSkipLast)) { bitmapInfo &= ~kCGBitmapAlphaInfoMask; bitmapInfo |= kCGImageAlphaPremultipliedFirst; } #pragma clang diagnostic pop } CGContextRef context = CGBitmapContextCreate(NULL, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo); CGColorSpaceRelease(colorSpace); if (!context) { CGImageRelease(imageRef); return image; } CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), imageRef); CGImageRef inflatedImageRef = CGBitmapContextCreateImage(context); CGContextRelease(context); UIImage *inflatedImage = [[UIImage alloc] initWithCGImage:inflatedImageRef scale:scale orientation:image.imageOrientation]; CGImageRelease(inflatedImageRef); CGImageRelease(imageRef); return inflatedImage; } #endif @implementation AFImageResponseSerializer - (instancetype)init { self = [super init]; if (!self) { return nil; } self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"image/tiff", @"image/jpeg", @"image/gif", @"image/png", @"image/ico", @"image/x-icon", @"image/bmp", @"image/x-bmp", @"image/x-xbitmap", @"image/x-win-bitmap", nil]; #if TARGET_OS_IOS || TARGET_OS_TV self.imageScale = [[UIScreen mainScreen] scale]; self.automaticallyInflatesResponseImage = YES; #elif TARGET_OS_WATCH self.imageScale = [[WKInterfaceDevice currentDevice] screenScale]; self.automaticallyInflatesResponseImage = YES; #endif return self; } #pragma mark - AFURLResponseSerializer - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) { return nil; } } #if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH if (self.automaticallyInflatesResponseImage) { return AFInflatedImageFromResponseWithDataAtScale((NSHTTPURLResponse *)response, data, self.imageScale); } else { return AFImageWithDataAtScale(data, self.imageScale); } #else // Ensure that the image is set to it's correct pixel width and height NSBitmapImageRep *bitimage = [[NSBitmapImageRep alloc] initWithData:data]; NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize([bitimage pixelsWide], [bitimage pixelsHigh])]; [image addRepresentation:bitimage]; return image; #endif return nil; } #pragma mark - NSSecureCoding - (instancetype)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (!self) { return nil; } #if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH NSNumber *imageScale = [decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(imageScale))]; #if CGFLOAT_IS_DOUBLE self.imageScale = [imageScale doubleValue]; #else self.imageScale = [imageScale floatValue]; #endif self.automaticallyInflatesResponseImage = [decoder decodeBoolForKey:NSStringFromSelector(@selector(automaticallyInflatesResponseImage))]; #endif return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; #if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH [coder encodeObject:@(self.imageScale) forKey:NSStringFromSelector(@selector(imageScale))]; [coder encodeBool:self.automaticallyInflatesResponseImage forKey:NSStringFromSelector(@selector(automaticallyInflatesResponseImage))]; #endif } #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { AFImageResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; #if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH serializer.imageScale = self.imageScale; serializer.automaticallyInflatesResponseImage = self.automaticallyInflatesResponseImage; #endif return serializer; } @end #pragma mark - @interface AFCompoundResponseSerializer () @property (readwrite, nonatomic, copy) NSArray *responseSerializers; @end @implementation AFCompoundResponseSerializer + (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers { AFCompoundResponseSerializer *serializer = [[self alloc] init]; serializer.responseSerializers = responseSerializers; return serializer; } #pragma mark - AFURLResponseSerialization - (id)responseObjectForResponse:(NSURLResponse *)response data:(NSData *)data error:(NSError *__autoreleasing *)error { for (id serializer in self.responseSerializers) { if (![serializer isKindOfClass:[AFHTTPResponseSerializer class]]) { continue; } NSError *serializerError = nil; id responseObject = [serializer responseObjectForResponse:response data:data error:&serializerError]; if (responseObject) { if (error) { *error = AFErrorWithUnderlyingError(serializerError, *error); } return responseObject; } } return [super responseObjectForResponse:response data:data error:error]; } #pragma mark - NSSecureCoding - (instancetype)initWithCoder:(NSCoder *)decoder { self = [super initWithCoder:decoder]; if (!self) { return nil; } self.responseSerializers = [decoder decodeObjectOfClass:[NSArray class] forKey:NSStringFromSelector(@selector(responseSerializers))]; return self; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; [coder encodeObject:self.responseSerializers forKey:NSStringFromSelector(@selector(responseSerializers))]; } #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { AFCompoundResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; serializer.responseSerializers = self.responseSerializers; return serializer; } @end ================================================ FILE: Pods/AFNetworking/AFNetworking/AFURLSessionManager.h ================================================ // AFURLSessionManager.h // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import "AFURLResponseSerialization.h" #import "AFURLRequestSerialization.h" #import "AFSecurityPolicy.h" #if !TARGET_OS_WATCH #import "AFNetworkReachabilityManager.h" #endif /** `AFURLSessionManager` creates and manages an `NSURLSession` object based on a specified `NSURLSessionConfiguration` object, which conforms to ``, ``, ``, and ``. ## Subclassing Notes This is the base class for `AFHTTPSessionManager`, which adds functionality specific to making HTTP requests. If you are looking to extend `AFURLSessionManager` specifically for HTTP, consider subclassing `AFHTTPSessionManager` instead. ## NSURLSession & NSURLSessionTask Delegate Methods `AFURLSessionManager` implements the following delegate methods: ### `NSURLSessionDelegate` - `URLSession:didBecomeInvalidWithError:` - `URLSession:didReceiveChallenge:completionHandler:` - `URLSessionDidFinishEventsForBackgroundURLSession:` ### `NSURLSessionTaskDelegate` - `URLSession:willPerformHTTPRedirection:newRequest:completionHandler:` - `URLSession:task:didReceiveChallenge:completionHandler:` - `URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:` - `URLSession:task:needNewBodyStream:` - `URLSession:task:didCompleteWithError:` ### `NSURLSessionDataDelegate` - `URLSession:dataTask:didReceiveResponse:completionHandler:` - `URLSession:dataTask:didBecomeDownloadTask:` - `URLSession:dataTask:didReceiveData:` - `URLSession:dataTask:willCacheResponse:completionHandler:` ### `NSURLSessionDownloadDelegate` - `URLSession:downloadTask:didFinishDownloadingToURL:` - `URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesWritten:totalBytesExpectedToWrite:` - `URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:` If any of these methods are overridden in a subclass, they _must_ call the `super` implementation first. ## Network Reachability Monitoring Network reachability status and change monitoring is available through the `reachabilityManager` property. Applications may choose to monitor network reachability conditions in order to prevent or suspend any outbound requests. See `AFNetworkReachabilityManager` for more details. ## NSCoding Caveats - Encoded managers do not include any block properties. Be sure to set delegate callback blocks when using `-initWithCoder:` or `NSKeyedUnarchiver`. ## NSCopying Caveats - `-copy` and `-copyWithZone:` return a new manager with a new `NSURLSession` created from the configuration of the original. - Operation copies do not include any delegate callback blocks, as they often strongly captures a reference to `self`, which would otherwise have the unintuitive side-effect of pointing to the _original_ session manager when copied. @warning Managers for background sessions must be owned for the duration of their use. This can be accomplished by creating an application-wide or shared singleton instance. */ NS_ASSUME_NONNULL_BEGIN @interface AFURLSessionManager : NSObject /** The managed session. */ @property (readonly, nonatomic, strong) NSURLSession *session; /** The operation queue on which delegate callbacks are run. */ @property (readonly, nonatomic, strong) NSOperationQueue *operationQueue; /** Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an instance of `AFJSONResponseSerializer`. @warning `responseSerializer` must not be `nil`. */ @property (nonatomic, strong) id responseSerializer; ///------------------------------- /// @name Managing Security Policy ///------------------------------- /** The security policy used by created session to evaluate server trust for secure connections. `AFURLSessionManager` uses the `defaultPolicy` unless otherwise specified. */ @property (nonatomic, strong) AFSecurityPolicy *securityPolicy; #if !TARGET_OS_WATCH ///-------------------------------------- /// @name Monitoring Network Reachability ///-------------------------------------- /** The network reachability manager. `AFURLSessionManager` uses the `sharedManager` by default. */ @property (readwrite, nonatomic, strong) AFNetworkReachabilityManager *reachabilityManager; #endif ///---------------------------- /// @name Getting Session Tasks ///---------------------------- /** The data, upload, and download tasks currently run by the managed session. */ @property (readonly, nonatomic, strong) NSArray *tasks; /** The data tasks currently run by the managed session. */ @property (readonly, nonatomic, strong) NSArray *dataTasks; /** The upload tasks currently run by the managed session. */ @property (readonly, nonatomic, strong) NSArray *uploadTasks; /** The download tasks currently run by the managed session. */ @property (readonly, nonatomic, strong) NSArray *downloadTasks; ///------------------------------- /// @name Managing Callback Queues ///------------------------------- /** The dispatch queue for `completionBlock`. If `NULL` (default), the main queue is used. */ @property (nonatomic, strong, nullable) dispatch_queue_t completionQueue; /** The dispatch group for `completionBlock`. If `NULL` (default), a private dispatch group is used. */ @property (nonatomic, strong, nullable) dispatch_group_t completionGroup; ///--------------------------------- /// @name Working Around System Bugs ///--------------------------------- /** Whether to attempt to retry creation of upload tasks for background sessions when initial call returns `nil`. `NO` by default. @bug As of iOS 7.0, there is a bug where upload tasks created for background tasks are sometimes `nil`. As a workaround, if this property is `YES`, AFNetworking will follow Apple's recommendation to try creating the task again. @see https://github.com/AFNetworking/AFNetworking/issues/1675 */ @property (nonatomic, assign) BOOL attemptsToRecreateUploadTasksForBackgroundSessions; ///--------------------- /// @name Initialization ///--------------------- /** Creates and returns a manager for a session created with the specified configuration. This is the designated initializer. @param configuration The configuration used to create the managed session. @return A manager for a newly-created session. */ - (instancetype)initWithSessionConfiguration:(nullable NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER; /** Invalidates the managed session, optionally canceling pending tasks. @param cancelPendingTasks Whether or not to cancel pending tasks. */ - (void)invalidateSessionCancelingTasks:(BOOL)cancelPendingTasks; ///------------------------- /// @name Running Data Tasks ///------------------------- /** Creates an `NSURLSessionDataTask` with the specified request. @param request The HTTP request for the request. @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. */ - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler; /** Creates an `NSURLSessionDataTask` with the specified request. @param request The HTTP request for the request. @param uploadProgressBlock A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. @param downloadProgressBlock A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue. @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. */ - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request uploadProgress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock downloadProgress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler; ///--------------------------- /// @name Running Upload Tasks ///--------------------------- /** Creates an `NSURLSessionUploadTask` with the specified request for a local file. @param request The HTTP request for the request. @param fileURL A URL to the local file to be uploaded. @param uploadProgressBlock A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. @see `attemptsToRecreateUploadTasksForBackgroundSessions` */ - (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler; /** Creates an `NSURLSessionUploadTask` with the specified request for an HTTP body. @param request The HTTP request for the request. @param bodyData A data object containing the HTTP body to be uploaded. @param uploadProgressBlock A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. */ - (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(nullable NSData *)bodyData progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler; /** Creates an `NSURLSessionUploadTask` with the specified streaming request. @param request The HTTP request for the request. @param uploadProgressBlock A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue. @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. */ - (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler; ///----------------------------- /// @name Running Download Tasks ///----------------------------- /** Creates an `NSURLSessionDownloadTask` with the specified request. @param request The HTTP request for the request. @param downloadProgressBlock A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue. @param destination A block object to be executed in order to determine the destination of the downloaded file. This block takes two arguments, the target path & the server response, and returns the desired file URL of the resulting download. The temporary file used during the download will be automatically deleted after being moved to the returned URL. @param completionHandler A block to be executed when a task finishes. This block has no return value and takes three arguments: the server response, the path of the downloaded file, and the error describing the network or parsing error that occurred, if any. @warning If using a background `NSURLSessionConfiguration` on iOS, these blocks will be lost when the app is terminated. Background sessions may prefer to use `-setDownloadTaskDidFinishDownloadingBlock:` to specify the URL for saving the downloaded file, rather than the destination block of this method. */ - (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * _Nullable filePath, NSError * _Nullable error))completionHandler; /** Creates an `NSURLSessionDownloadTask` with the specified resume data. @param resumeData The data used to resume downloading. @param downloadProgressBlock A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue. @param destination A block object to be executed in order to determine the destination of the downloaded file. This block takes two arguments, the target path & the server response, and returns the desired file URL of the resulting download. The temporary file used during the download will be automatically deleted after being moved to the returned URL. @param completionHandler A block to be executed when a task finishes. This block has no return value and takes three arguments: the server response, the path of the downloaded file, and the error describing the network or parsing error that occurred, if any. */ - (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * _Nullable filePath, NSError * _Nullable error))completionHandler; ///--------------------------------- /// @name Getting Progress for Tasks ///--------------------------------- /** Returns the upload progress of the specified task. @param task The session task. Must not be `nil`. @return An `NSProgress` object reporting the upload progress of a task, or `nil` if the progress is unavailable. */ - (nullable NSProgress *)uploadProgressForTask:(NSURLSessionTask *)task; /** Returns the download progress of the specified task. @param task The session task. Must not be `nil`. @return An `NSProgress` object reporting the download progress of a task, or `nil` if the progress is unavailable. */ - (nullable NSProgress *)downloadProgressForTask:(NSURLSessionTask *)task; ///----------------------------------------- /// @name Setting Session Delegate Callbacks ///----------------------------------------- /** Sets a block to be executed when the managed session becomes invalid, as handled by the `NSURLSessionDelegate` method `URLSession:didBecomeInvalidWithError:`. @param block A block object to be executed when the managed session becomes invalid. The block has no return value, and takes two arguments: the session, and the error related to the cause of invalidation. */ - (void)setSessionDidBecomeInvalidBlock:(nullable void (^)(NSURLSession *session, NSError *error))block; /** Sets a block to be executed when a connection level authentication challenge has occurred, as handled by the `NSURLSessionDelegate` method `URLSession:didReceiveChallenge:completionHandler:`. @param block A block object to be executed when a connection level authentication challenge has occurred. The block returns the disposition of the authentication challenge, and takes three arguments: the session, the authentication challenge, and a pointer to the credential that should be used to resolve the challenge. */ - (void)setSessionDidReceiveAuthenticationChallengeBlock:(nullable NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * _Nullable __autoreleasing * _Nullable credential))block; ///-------------------------------------- /// @name Setting Task Delegate Callbacks ///-------------------------------------- /** Sets a block to be executed when a task requires a new request body stream to send to the remote server, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:needNewBodyStream:`. @param block A block object to be executed when a task requires a new request body stream. */ - (void)setTaskNeedNewBodyStreamBlock:(nullable NSInputStream * (^)(NSURLSession *session, NSURLSessionTask *task))block; /** Sets a block to be executed when an HTTP request is attempting to perform a redirection to a different URL, as handled by the `NSURLSessionTaskDelegate` method `URLSession:willPerformHTTPRedirection:newRequest:completionHandler:`. @param block A block object to be executed when an HTTP request is attempting to perform a redirection to a different URL. The block returns the request to be made for the redirection, and takes four arguments: the session, the task, the redirection response, and the request corresponding to the redirection response. */ - (void)setTaskWillPerformHTTPRedirectionBlock:(nullable NSURLRequest * (^)(NSURLSession *session, NSURLSessionTask *task, NSURLResponse *response, NSURLRequest *request))block; /** Sets a block to be executed when a session task has received a request specific authentication challenge, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:didReceiveChallenge:completionHandler:`. @param block A block object to be executed when a session task has received a request specific authentication challenge. The block returns the disposition of the authentication challenge, and takes four arguments: the session, the task, the authentication challenge, and a pointer to the credential that should be used to resolve the challenge. */ - (void)setTaskDidReceiveAuthenticationChallengeBlock:(nullable NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * _Nullable __autoreleasing * _Nullable credential))block; /** Sets a block to be executed periodically to track upload progress, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:`. @param block A block object to be called when an undetermined number of bytes have been uploaded to the server. This block has no return value and takes five arguments: the session, the task, the number of bytes written since the last time the upload progress block was called, the total bytes written, and the total bytes expected to be written during the request, as initially determined by the length of the HTTP body. This block may be called multiple times, and will execute on the main thread. */ - (void)setTaskDidSendBodyDataBlock:(nullable void (^)(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend))block; /** Sets a block to be executed as the last message related to a specific task, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:didCompleteWithError:`. @param block A block object to be executed when a session task is completed. The block has no return value, and takes three arguments: the session, the task, and any error that occurred in the process of executing the task. */ - (void)setTaskDidCompleteBlock:(nullable void (^)(NSURLSession *session, NSURLSessionTask *task, NSError * _Nullable error))block; ///------------------------------------------- /// @name Setting Data Task Delegate Callbacks ///------------------------------------------- /** Sets a block to be executed when a data task has received a response, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:didReceiveResponse:completionHandler:`. @param block A block object to be executed when a data task has received a response. The block returns the disposition of the session response, and takes three arguments: the session, the data task, and the received response. */ - (void)setDataTaskDidReceiveResponseBlock:(nullable NSURLSessionResponseDisposition (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response))block; /** Sets a block to be executed when a data task has become a download task, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:didBecomeDownloadTask:`. @param block A block object to be executed when a data task has become a download task. The block has no return value, and takes three arguments: the session, the data task, and the download task it has become. */ - (void)setDataTaskDidBecomeDownloadTaskBlock:(nullable void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask))block; /** Sets a block to be executed when a data task receives data, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:didReceiveData:`. @param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the session, the data task, and the data received. This block may be called multiple times, and will execute on the session manager operation queue. */ - (void)setDataTaskDidReceiveDataBlock:(nullable void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data))block; /** Sets a block to be executed to determine the caching behavior of a data task, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:willCacheResponse:completionHandler:`. @param block A block object to be executed to determine the caching behavior of a data task. The block returns the response to cache, and takes three arguments: the session, the data task, and the proposed cached URL response. */ - (void)setDataTaskWillCacheResponseBlock:(nullable NSCachedURLResponse * (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse))block; /** Sets a block to be executed once all messages enqueued for a session have been delivered, as handled by the `NSURLSessionDataDelegate` method `URLSessionDidFinishEventsForBackgroundURLSession:`. @param block A block object to be executed once all messages enqueued for a session have been delivered. The block has no return value and takes a single argument: the session. */ - (void)setDidFinishEventsForBackgroundURLSessionBlock:(nullable void (^)(NSURLSession *session))block; ///----------------------------------------------- /// @name Setting Download Task Delegate Callbacks ///----------------------------------------------- /** Sets a block to be executed when a download task has completed a download, as handled by the `NSURLSessionDownloadDelegate` method `URLSession:downloadTask:didFinishDownloadingToURL:`. @param block A block object to be executed when a download task has completed. The block returns the URL the download should be moved to, and takes three arguments: the session, the download task, and the temporary location of the downloaded file. If the file manager encounters an error while attempting to move the temporary file to the destination, an `AFURLSessionDownloadTaskDidFailToMoveFileNotification` will be posted, with the download task as its object, and the user info of the error. */ - (void)setDownloadTaskDidFinishDownloadingBlock:(nullable NSURL * _Nullable (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location))block; /** Sets a block to be executed periodically to track download progress, as handled by the `NSURLSessionDownloadDelegate` method `URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesWritten:totalBytesExpectedToWrite:`. @param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes five arguments: the session, the download task, the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times, and will execute on the session manager operation queue. */ - (void)setDownloadTaskDidWriteDataBlock:(nullable void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite))block; /** Sets a block to be executed when a download task has been resumed, as handled by the `NSURLSessionDownloadDelegate` method `URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:`. @param block A block object to be executed when a download task has been resumed. The block has no return value and takes four arguments: the session, the download task, the file offset of the resumed download, and the total number of bytes expected to be downloaded. */ - (void)setDownloadTaskDidResumeBlock:(nullable void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes))block; @end ///-------------------- /// @name Notifications ///-------------------- /** Posted when a task resumes. */ FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidResumeNotification; /** Posted when a task finishes executing. Includes a userInfo dictionary with additional information about the task. */ FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidCompleteNotification; /** Posted when a task suspends its execution. */ FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidSuspendNotification; /** Posted when a session is invalidated. */ FOUNDATION_EXPORT NSString * const AFURLSessionDidInvalidateNotification; /** Posted when a session download task encountered an error when moving the temporary download file to a specified destination. */ FOUNDATION_EXPORT NSString * const AFURLSessionDownloadTaskDidFailToMoveFileNotification; /** The raw response data of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidCompleteNotification` if response data exists for the task. */ FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidCompleteResponseDataKey; /** The serialized response object of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidCompleteNotification` if the response was serialized. */ FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidCompleteSerializedResponseKey; /** The response serializer used to serialize the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidCompleteNotification` if the task has an associated response serializer. */ FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidCompleteResponseSerializerKey; /** The file path associated with the download task. Included in the userInfo dictionary of the `AFNetworkingTaskDidCompleteNotification` if an the response data has been stored directly to disk. */ FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidCompleteAssetPathKey; /** Any error associated with the task, or the serialization of the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidCompleteNotification` if an error exists. */ FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidCompleteErrorKey; NS_ASSUME_NONNULL_END ================================================ FILE: Pods/AFNetworking/AFNetworking/AFURLSessionManager.m ================================================ // AFURLSessionManager.m // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "AFURLSessionManager.h" #import #ifndef NSFoundationVersionNumber_iOS_8_0 #define NSFoundationVersionNumber_With_Fixed_5871104061079552_bug 1140.11 #else #define NSFoundationVersionNumber_With_Fixed_5871104061079552_bug NSFoundationVersionNumber_iOS_8_0 #endif static dispatch_queue_t url_session_manager_creation_queue() { static dispatch_queue_t af_url_session_manager_creation_queue; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ af_url_session_manager_creation_queue = dispatch_queue_create("com.alamofire.networking.session.manager.creation", DISPATCH_QUEUE_SERIAL); }); return af_url_session_manager_creation_queue; } static void url_session_manager_create_task_safely(dispatch_block_t block) { if (NSFoundationVersionNumber < NSFoundationVersionNumber_With_Fixed_5871104061079552_bug) { // Fix of bug // Open Radar:http://openradar.appspot.com/radar?id=5871104061079552 (status: Fixed in iOS8) // Issue about:https://github.com/AFNetworking/AFNetworking/issues/2093 dispatch_sync(url_session_manager_creation_queue(), block); } else { block(); } } static dispatch_queue_t url_session_manager_processing_queue() { static dispatch_queue_t af_url_session_manager_processing_queue; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ af_url_session_manager_processing_queue = dispatch_queue_create("com.alamofire.networking.session.manager.processing", DISPATCH_QUEUE_CONCURRENT); }); return af_url_session_manager_processing_queue; } static dispatch_group_t url_session_manager_completion_group() { static dispatch_group_t af_url_session_manager_completion_group; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ af_url_session_manager_completion_group = dispatch_group_create(); }); return af_url_session_manager_completion_group; } NSString * const AFNetworkingTaskDidResumeNotification = @"com.alamofire.networking.task.resume"; NSString * const AFNetworkingTaskDidCompleteNotification = @"com.alamofire.networking.task.complete"; NSString * const AFNetworkingTaskDidSuspendNotification = @"com.alamofire.networking.task.suspend"; NSString * const AFURLSessionDidInvalidateNotification = @"com.alamofire.networking.session.invalidate"; NSString * const AFURLSessionDownloadTaskDidFailToMoveFileNotification = @"com.alamofire.networking.session.download.file-manager-error"; NSString * const AFNetworkingTaskDidCompleteSerializedResponseKey = @"com.alamofire.networking.task.complete.serializedresponse"; NSString * const AFNetworkingTaskDidCompleteResponseSerializerKey = @"com.alamofire.networking.task.complete.responseserializer"; NSString * const AFNetworkingTaskDidCompleteResponseDataKey = @"com.alamofire.networking.complete.finish.responsedata"; NSString * const AFNetworkingTaskDidCompleteErrorKey = @"com.alamofire.networking.task.complete.error"; NSString * const AFNetworkingTaskDidCompleteAssetPathKey = @"com.alamofire.networking.task.complete.assetpath"; static NSString * const AFURLSessionManagerLockName = @"com.alamofire.networking.session.manager.lock"; static NSUInteger const AFMaximumNumberOfAttemptsToRecreateBackgroundSessionUploadTask = 3; static void * AFTaskStateChangedContext = &AFTaskStateChangedContext; typedef void (^AFURLSessionDidBecomeInvalidBlock)(NSURLSession *session, NSError *error); typedef NSURLSessionAuthChallengeDisposition (^AFURLSessionDidReceiveAuthenticationChallengeBlock)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential); typedef NSURLRequest * (^AFURLSessionTaskWillPerformHTTPRedirectionBlock)(NSURLSession *session, NSURLSessionTask *task, NSURLResponse *response, NSURLRequest *request); typedef NSURLSessionAuthChallengeDisposition (^AFURLSessionTaskDidReceiveAuthenticationChallengeBlock)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential); typedef void (^AFURLSessionDidFinishEventsForBackgroundURLSessionBlock)(NSURLSession *session); typedef NSInputStream * (^AFURLSessionTaskNeedNewBodyStreamBlock)(NSURLSession *session, NSURLSessionTask *task); typedef void (^AFURLSessionTaskDidSendBodyDataBlock)(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend); typedef void (^AFURLSessionTaskDidCompleteBlock)(NSURLSession *session, NSURLSessionTask *task, NSError *error); typedef NSURLSessionResponseDisposition (^AFURLSessionDataTaskDidReceiveResponseBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response); typedef void (^AFURLSessionDataTaskDidBecomeDownloadTaskBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask); typedef void (^AFURLSessionDataTaskDidReceiveDataBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data); typedef NSCachedURLResponse * (^AFURLSessionDataTaskWillCacheResponseBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse); typedef NSURL * (^AFURLSessionDownloadTaskDidFinishDownloadingBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location); typedef void (^AFURLSessionDownloadTaskDidWriteDataBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite); typedef void (^AFURLSessionDownloadTaskDidResumeBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes); typedef void (^AFURLSessionTaskProgressBlock)(NSProgress *); typedef void (^AFURLSessionTaskCompletionHandler)(NSURLResponse *response, id responseObject, NSError *error); #pragma mark - @interface AFURLSessionManagerTaskDelegate : NSObject @property (nonatomic, weak) AFURLSessionManager *manager; @property (nonatomic, strong) NSMutableData *mutableData; @property (nonatomic, strong) NSProgress *uploadProgress; @property (nonatomic, strong) NSProgress *downloadProgress; @property (nonatomic, copy) NSURL *downloadFileURL; @property (nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading; @property (nonatomic, copy) AFURLSessionTaskProgressBlock uploadProgressBlock; @property (nonatomic, copy) AFURLSessionTaskProgressBlock downloadProgressBlock; @property (nonatomic, copy) AFURLSessionTaskCompletionHandler completionHandler; @end @implementation AFURLSessionManagerTaskDelegate - (instancetype)init { self = [super init]; if (!self) { return nil; } self.mutableData = [NSMutableData data]; self.uploadProgress = [[NSProgress alloc] initWithParent:nil userInfo:nil]; self.uploadProgress.totalUnitCount = NSURLSessionTransferSizeUnknown; self.downloadProgress = [[NSProgress alloc] initWithParent:nil userInfo:nil]; self.downloadProgress.totalUnitCount = NSURLSessionTransferSizeUnknown; return self; } #pragma mark - NSProgress Tracking - (void)setupProgressForTask:(NSURLSessionTask *)task { __weak __typeof__(task) weakTask = task; self.uploadProgress.totalUnitCount = task.countOfBytesExpectedToSend; self.downloadProgress.totalUnitCount = task.countOfBytesExpectedToReceive; [self.uploadProgress setCancellable:YES]; [self.uploadProgress setCancellationHandler:^{ __typeof__(weakTask) strongTask = weakTask; [strongTask cancel]; }]; [self.uploadProgress setPausable:YES]; [self.uploadProgress setPausingHandler:^{ __typeof__(weakTask) strongTask = weakTask; [strongTask suspend]; }]; if ([self.uploadProgress respondsToSelector:@selector(setResumingHandler:)]) { [self.uploadProgress setResumingHandler:^{ __typeof__(weakTask) strongTask = weakTask; [strongTask resume]; }]; } [self.downloadProgress setCancellable:YES]; [self.downloadProgress setCancellationHandler:^{ __typeof__(weakTask) strongTask = weakTask; [strongTask cancel]; }]; [self.downloadProgress setPausable:YES]; [self.downloadProgress setPausingHandler:^{ __typeof__(weakTask) strongTask = weakTask; [strongTask suspend]; }]; if ([self.downloadProgress respondsToSelector:@selector(setResumingHandler:)]) { [self.downloadProgress setResumingHandler:^{ __typeof__(weakTask) strongTask = weakTask; [strongTask resume]; }]; } [task addObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesReceived)) options:NSKeyValueObservingOptionNew context:NULL]; [task addObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesExpectedToReceive)) options:NSKeyValueObservingOptionNew context:NULL]; [task addObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesSent)) options:NSKeyValueObservingOptionNew context:NULL]; [task addObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesExpectedToSend)) options:NSKeyValueObservingOptionNew context:NULL]; [self.downloadProgress addObserver:self forKeyPath:NSStringFromSelector(@selector(fractionCompleted)) options:NSKeyValueObservingOptionNew context:NULL]; [self.uploadProgress addObserver:self forKeyPath:NSStringFromSelector(@selector(fractionCompleted)) options:NSKeyValueObservingOptionNew context:NULL]; } - (void)cleanUpProgressForTask:(NSURLSessionTask *)task { [task removeObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesReceived))]; [task removeObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesExpectedToReceive))]; [task removeObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesSent))]; [task removeObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesExpectedToSend))]; [self.downloadProgress removeObserver:self forKeyPath:NSStringFromSelector(@selector(fractionCompleted))]; [self.uploadProgress removeObserver:self forKeyPath:NSStringFromSelector(@selector(fractionCompleted))]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([object isKindOfClass:[NSURLSessionTask class]] || [object isKindOfClass:[NSURLSessionDownloadTask class]]) { if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesReceived))]) { self.downloadProgress.completedUnitCount = [change[NSKeyValueChangeNewKey] longLongValue]; } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesExpectedToReceive))]) { self.downloadProgress.totalUnitCount = [change[NSKeyValueChangeNewKey] longLongValue]; } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesSent))]) { self.uploadProgress.completedUnitCount = [change[NSKeyValueChangeNewKey] longLongValue]; } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesExpectedToSend))]) { self.uploadProgress.totalUnitCount = [change[NSKeyValueChangeNewKey] longLongValue]; } } else if ([object isEqual:self.downloadProgress]) { if (self.downloadProgressBlock) { self.downloadProgressBlock(object); } } else if ([object isEqual:self.uploadProgress]) { if (self.uploadProgressBlock) { self.uploadProgressBlock(object); } } } #pragma mark - NSURLSessionTaskDelegate - (void)URLSession:(__unused NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" __strong AFURLSessionManager *manager = self.manager; __block id responseObject = nil; __block NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; userInfo[AFNetworkingTaskDidCompleteResponseSerializerKey] = manager.responseSerializer; //Performance Improvement from #2672 NSData *data = nil; if (self.mutableData) { data = [self.mutableData copy]; //We no longer need the reference, so nil it out to gain back some memory. self.mutableData = nil; } if (self.downloadFileURL) { userInfo[AFNetworkingTaskDidCompleteAssetPathKey] = self.downloadFileURL; } else if (data) { userInfo[AFNetworkingTaskDidCompleteResponseDataKey] = data; } if (error) { userInfo[AFNetworkingTaskDidCompleteErrorKey] = error; dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{ if (self.completionHandler) { self.completionHandler(task.response, responseObject, error); } dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo]; }); }); } else { dispatch_async(url_session_manager_processing_queue(), ^{ NSError *serializationError = nil; responseObject = [manager.responseSerializer responseObjectForResponse:task.response data:data error:&serializationError]; if (self.downloadFileURL) { responseObject = self.downloadFileURL; } if (responseObject) { userInfo[AFNetworkingTaskDidCompleteSerializedResponseKey] = responseObject; } if (serializationError) { userInfo[AFNetworkingTaskDidCompleteErrorKey] = serializationError; } dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{ if (self.completionHandler) { self.completionHandler(task.response, responseObject, serializationError); } dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo]; }); }); }); } #pragma clang diagnostic pop } #pragma mark - NSURLSessionDataTaskDelegate - (void)URLSession:(__unused NSURLSession *)session dataTask:(__unused NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { [self.mutableData appendData:data]; } #pragma mark - NSURLSessionDownloadTaskDelegate - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { NSError *fileManagerError = nil; self.downloadFileURL = nil; if (self.downloadTaskDidFinishDownloading) { self.downloadFileURL = self.downloadTaskDidFinishDownloading(session, downloadTask, location); if (self.downloadFileURL) { [[NSFileManager defaultManager] moveItemAtURL:location toURL:self.downloadFileURL error:&fileManagerError]; if (fileManagerError) { [[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDownloadTaskDidFailToMoveFileNotification object:downloadTask userInfo:fileManagerError.userInfo]; } } } } @end #pragma mark - /** * A workaround for issues related to key-value observing the `state` of an `NSURLSessionTask`. * * See: * - https://github.com/AFNetworking/AFNetworking/issues/1477 * - https://github.com/AFNetworking/AFNetworking/issues/2638 * - https://github.com/AFNetworking/AFNetworking/pull/2702 */ static inline void af_swizzleSelector(Class theClass, SEL originalSelector, SEL swizzledSelector) { Method originalMethod = class_getInstanceMethod(theClass, originalSelector); Method swizzledMethod = class_getInstanceMethod(theClass, swizzledSelector); method_exchangeImplementations(originalMethod, swizzledMethod); } static inline BOOL af_addMethod(Class theClass, SEL selector, Method method) { return class_addMethod(theClass, selector, method_getImplementation(method), method_getTypeEncoding(method)); } static NSString * const AFNSURLSessionTaskDidResumeNotification = @"com.alamofire.networking.nsurlsessiontask.resume"; static NSString * const AFNSURLSessionTaskDidSuspendNotification = @"com.alamofire.networking.nsurlsessiontask.suspend"; @interface _AFURLSessionTaskSwizzling : NSObject @end @implementation _AFURLSessionTaskSwizzling + (void)load { /** WARNING: Trouble Ahead https://github.com/AFNetworking/AFNetworking/pull/2702 */ if (NSClassFromString(@"NSURLSessionTask")) { /** iOS 7 and iOS 8 differ in NSURLSessionTask implementation, which makes the next bit of code a bit tricky. Many Unit Tests have been built to validate as much of this behavior has possible. Here is what we know: - NSURLSessionTasks are implemented with class clusters, meaning the class you request from the API isn't actually the type of class you will get back. - Simply referencing `[NSURLSessionTask class]` will not work. You need to ask an `NSURLSession` to actually create an object, and grab the class from there. - On iOS 7, `localDataTask` is a `__NSCFLocalDataTask`, which inherits from `__NSCFLocalSessionTask`, which inherits from `__NSCFURLSessionTask`. - On iOS 8, `localDataTask` is a `__NSCFLocalDataTask`, which inherits from `__NSCFLocalSessionTask`, which inherits from `NSURLSessionTask`. - On iOS 7, `__NSCFLocalSessionTask` and `__NSCFURLSessionTask` are the only two classes that have their own implementations of `resume` and `suspend`, and `__NSCFLocalSessionTask` DOES NOT CALL SUPER. This means both classes need to be swizzled. - On iOS 8, `NSURLSessionTask` is the only class that implements `resume` and `suspend`. This means this is the only class that needs to be swizzled. - Because `NSURLSessionTask` is not involved in the class hierarchy for every version of iOS, its easier to add the swizzled methods to a dummy class and manage them there. Some Assumptions: - No implementations of `resume` or `suspend` call super. If this were to change in a future version of iOS, we'd need to handle it. - No background task classes override `resume` or `suspend` The current solution: 1) Grab an instance of `__NSCFLocalDataTask` by asking an instance of `NSURLSession` for a data task. 2) Grab a pointer to the original implementation of `af_resume` 3) Check to see if the current class has an implementation of resume. If so, continue to step 4. 4) Grab the super class of the current class. 5) Grab a pointer for the current class to the current implementation of `resume`. 6) Grab a pointer for the super class to the current implementation of `resume`. 7) If the current class implementation of `resume` is not equal to the super class implementation of `resume` AND the current implementation of `resume` is not equal to the original implementation of `af_resume`, THEN swizzle the methods 8) Set the current class to the super class, and repeat steps 3-8 */ NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; NSURLSession * session = [NSURLSession sessionWithConfiguration:configuration]; #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnonnull" NSURLSessionDataTask *localDataTask = [session dataTaskWithURL:nil]; #pragma clang diagnostic pop IMP originalAFResumeIMP = method_getImplementation(class_getInstanceMethod([self class], @selector(af_resume))); Class currentClass = [localDataTask class]; while (class_getInstanceMethod(currentClass, @selector(resume))) { Class superClass = [currentClass superclass]; IMP classResumeIMP = method_getImplementation(class_getInstanceMethod(currentClass, @selector(resume))); IMP superclassResumeIMP = method_getImplementation(class_getInstanceMethod(superClass, @selector(resume))); if (classResumeIMP != superclassResumeIMP && originalAFResumeIMP != classResumeIMP) { [self swizzleResumeAndSuspendMethodForClass:currentClass]; } currentClass = [currentClass superclass]; } [localDataTask cancel]; [session finishTasksAndInvalidate]; } } + (void)swizzleResumeAndSuspendMethodForClass:(Class)theClass { Method afResumeMethod = class_getInstanceMethod(self, @selector(af_resume)); Method afSuspendMethod = class_getInstanceMethod(self, @selector(af_suspend)); if (af_addMethod(theClass, @selector(af_resume), afResumeMethod)) { af_swizzleSelector(theClass, @selector(resume), @selector(af_resume)); } if (af_addMethod(theClass, @selector(af_suspend), afSuspendMethod)) { af_swizzleSelector(theClass, @selector(suspend), @selector(af_suspend)); } } - (NSURLSessionTaskState)state { NSAssert(NO, @"State method should never be called in the actual dummy class"); return NSURLSessionTaskStateCanceling; } - (void)af_resume { NSAssert([self respondsToSelector:@selector(state)], @"Does not respond to state"); NSURLSessionTaskState state = [self state]; [self af_resume]; if (state != NSURLSessionTaskStateRunning) { [[NSNotificationCenter defaultCenter] postNotificationName:AFNSURLSessionTaskDidResumeNotification object:self]; } } - (void)af_suspend { NSAssert([self respondsToSelector:@selector(state)], @"Does not respond to state"); NSURLSessionTaskState state = [self state]; [self af_suspend]; if (state != NSURLSessionTaskStateSuspended) { [[NSNotificationCenter defaultCenter] postNotificationName:AFNSURLSessionTaskDidSuspendNotification object:self]; } } @end #pragma mark - @interface AFURLSessionManager () @property (readwrite, nonatomic, strong) NSURLSessionConfiguration *sessionConfiguration; @property (readwrite, nonatomic, strong) NSOperationQueue *operationQueue; @property (readwrite, nonatomic, strong) NSURLSession *session; @property (readwrite, nonatomic, strong) NSMutableDictionary *mutableTaskDelegatesKeyedByTaskIdentifier; @property (readonly, nonatomic, copy) NSString *taskDescriptionForSessionTasks; @property (readwrite, nonatomic, strong) NSLock *lock; @property (readwrite, nonatomic, copy) AFURLSessionDidBecomeInvalidBlock sessionDidBecomeInvalid; @property (readwrite, nonatomic, copy) AFURLSessionDidReceiveAuthenticationChallengeBlock sessionDidReceiveAuthenticationChallenge; @property (readwrite, nonatomic, copy) AFURLSessionDidFinishEventsForBackgroundURLSessionBlock didFinishEventsForBackgroundURLSession; @property (readwrite, nonatomic, copy) AFURLSessionTaskWillPerformHTTPRedirectionBlock taskWillPerformHTTPRedirection; @property (readwrite, nonatomic, copy) AFURLSessionTaskDidReceiveAuthenticationChallengeBlock taskDidReceiveAuthenticationChallenge; @property (readwrite, nonatomic, copy) AFURLSessionTaskNeedNewBodyStreamBlock taskNeedNewBodyStream; @property (readwrite, nonatomic, copy) AFURLSessionTaskDidSendBodyDataBlock taskDidSendBodyData; @property (readwrite, nonatomic, copy) AFURLSessionTaskDidCompleteBlock taskDidComplete; @property (readwrite, nonatomic, copy) AFURLSessionDataTaskDidReceiveResponseBlock dataTaskDidReceiveResponse; @property (readwrite, nonatomic, copy) AFURLSessionDataTaskDidBecomeDownloadTaskBlock dataTaskDidBecomeDownloadTask; @property (readwrite, nonatomic, copy) AFURLSessionDataTaskDidReceiveDataBlock dataTaskDidReceiveData; @property (readwrite, nonatomic, copy) AFURLSessionDataTaskWillCacheResponseBlock dataTaskWillCacheResponse; @property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading; @property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidWriteDataBlock downloadTaskDidWriteData; @property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidResumeBlock downloadTaskDidResume; @end @implementation AFURLSessionManager - (instancetype)init { return [self initWithSessionConfiguration:nil]; } - (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration { self = [super init]; if (!self) { return nil; } if (!configuration) { configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; } self.sessionConfiguration = configuration; self.operationQueue = [[NSOperationQueue alloc] init]; self.operationQueue.maxConcurrentOperationCount = 1; self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue]; self.responseSerializer = [AFJSONResponseSerializer serializer]; self.securityPolicy = [AFSecurityPolicy defaultPolicy]; #if !TARGET_OS_WATCH self.reachabilityManager = [AFNetworkReachabilityManager sharedManager]; #endif self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init]; self.lock = [[NSLock alloc] init]; self.lock.name = AFURLSessionManagerLockName; [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) { for (NSURLSessionDataTask *task in dataTasks) { [self addDelegateForDataTask:task uploadProgress:nil downloadProgress:nil completionHandler:nil]; } for (NSURLSessionUploadTask *uploadTask in uploadTasks) { [self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil]; } for (NSURLSessionDownloadTask *downloadTask in downloadTasks) { [self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil]; } }]; return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } #pragma mark - - (NSString *)taskDescriptionForSessionTasks { return [NSString stringWithFormat:@"%p", self]; } - (void)taskDidResume:(NSNotification *)notification { NSURLSessionTask *task = notification.object; if ([task respondsToSelector:@selector(taskDescription)]) { if ([task.taskDescription isEqualToString:self.taskDescriptionForSessionTasks]) { dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidResumeNotification object:task]; }); } } } - (void)taskDidSuspend:(NSNotification *)notification { NSURLSessionTask *task = notification.object; if ([task respondsToSelector:@selector(taskDescription)]) { if ([task.taskDescription isEqualToString:self.taskDescriptionForSessionTasks]) { dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidSuspendNotification object:task]; }); } } } #pragma mark - - (AFURLSessionManagerTaskDelegate *)delegateForTask:(NSURLSessionTask *)task { NSParameterAssert(task); AFURLSessionManagerTaskDelegate *delegate = nil; [self.lock lock]; delegate = self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)]; [self.lock unlock]; return delegate; } - (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate forTask:(NSURLSessionTask *)task { NSParameterAssert(task); NSParameterAssert(delegate); [self.lock lock]; self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate; [delegate setupProgressForTask:task]; [self addNotificationObserverForTask:task]; [self.lock unlock]; } - (void)addDelegateForDataTask:(NSURLSessionDataTask *)dataTask uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler { AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init]; delegate.manager = self; delegate.completionHandler = completionHandler; dataTask.taskDescription = self.taskDescriptionForSessionTasks; [self setDelegate:delegate forTask:dataTask]; delegate.uploadProgressBlock = uploadProgressBlock; delegate.downloadProgressBlock = downloadProgressBlock; } - (void)addDelegateForUploadTask:(NSURLSessionUploadTask *)uploadTask progress:(void (^)(NSProgress *uploadProgress)) uploadProgressBlock completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler { AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init]; delegate.manager = self; delegate.completionHandler = completionHandler; uploadTask.taskDescription = self.taskDescriptionForSessionTasks; [self setDelegate:delegate forTask:uploadTask]; delegate.uploadProgressBlock = uploadProgressBlock; } - (void)addDelegateForDownloadTask:(NSURLSessionDownloadTask *)downloadTask progress:(void (^)(NSProgress *downloadProgress)) downloadProgressBlock destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler { AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init]; delegate.manager = self; delegate.completionHandler = completionHandler; if (destination) { delegate.downloadTaskDidFinishDownloading = ^NSURL * (NSURLSession * __unused session, NSURLSessionDownloadTask *task, NSURL *location) { return destination(location, task.response); }; } downloadTask.taskDescription = self.taskDescriptionForSessionTasks; [self setDelegate:delegate forTask:downloadTask]; delegate.downloadProgressBlock = downloadProgressBlock; } - (void)removeDelegateForTask:(NSURLSessionTask *)task { NSParameterAssert(task); AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task]; [self.lock lock]; [delegate cleanUpProgressForTask:task]; [self removeNotificationObserverForTask:task]; [self.mutableTaskDelegatesKeyedByTaskIdentifier removeObjectForKey:@(task.taskIdentifier)]; [self.lock unlock]; } #pragma mark - - (NSArray *)tasksForKeyPath:(NSString *)keyPath { __block NSArray *tasks = nil; dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) { if ([keyPath isEqualToString:NSStringFromSelector(@selector(dataTasks))]) { tasks = dataTasks; } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(uploadTasks))]) { tasks = uploadTasks; } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(downloadTasks))]) { tasks = downloadTasks; } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(tasks))]) { tasks = [@[dataTasks, uploadTasks, downloadTasks] valueForKeyPath:@"@unionOfArrays.self"]; } dispatch_semaphore_signal(semaphore); }]; dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); return tasks; } - (NSArray *)tasks { return [self tasksForKeyPath:NSStringFromSelector(_cmd)]; } - (NSArray *)dataTasks { return [self tasksForKeyPath:NSStringFromSelector(_cmd)]; } - (NSArray *)uploadTasks { return [self tasksForKeyPath:NSStringFromSelector(_cmd)]; } - (NSArray *)downloadTasks { return [self tasksForKeyPath:NSStringFromSelector(_cmd)]; } #pragma mark - - (void)invalidateSessionCancelingTasks:(BOOL)cancelPendingTasks { dispatch_async(dispatch_get_main_queue(), ^{ if (cancelPendingTasks) { [self.session invalidateAndCancel]; } else { [self.session finishTasksAndInvalidate]; } }); } #pragma mark - - (void)setResponseSerializer:(id )responseSerializer { NSParameterAssert(responseSerializer); _responseSerializer = responseSerializer; } #pragma mark - - (void)addNotificationObserverForTask:(NSURLSessionTask *)task { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidResume:) name:AFNSURLSessionTaskDidResumeNotification object:task]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidSuspend:) name:AFNSURLSessionTaskDidSuspendNotification object:task]; } - (void)removeNotificationObserverForTask:(NSURLSessionTask *)task { [[NSNotificationCenter defaultCenter] removeObserver:self name:AFNSURLSessionTaskDidSuspendNotification object:task]; [[NSNotificationCenter defaultCenter] removeObserver:self name:AFNSURLSessionTaskDidResumeNotification object:task]; } #pragma mark - - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler { return [self dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:completionHandler]; } - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler { __block NSURLSessionDataTask *dataTask = nil; url_session_manager_create_task_safely(^{ dataTask = [self.session dataTaskWithRequest:request]; }); [self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler]; return dataTask; } #pragma mark - - (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL progress:(void (^)(NSProgress *uploadProgress)) uploadProgressBlock completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler { __block NSURLSessionUploadTask *uploadTask = nil; url_session_manager_create_task_safely(^{ uploadTask = [self.session uploadTaskWithRequest:request fromFile:fileURL]; }); if (!uploadTask && self.attemptsToRecreateUploadTasksForBackgroundSessions && self.session.configuration.identifier) { for (NSUInteger attempts = 0; !uploadTask && attempts < AFMaximumNumberOfAttemptsToRecreateBackgroundSessionUploadTask; attempts++) { uploadTask = [self.session uploadTaskWithRequest:request fromFile:fileURL]; } } [self addDelegateForUploadTask:uploadTask progress:uploadProgressBlock completionHandler:completionHandler]; return uploadTask; } - (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData progress:(void (^)(NSProgress *uploadProgress)) uploadProgressBlock completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler { __block NSURLSessionUploadTask *uploadTask = nil; url_session_manager_create_task_safely(^{ uploadTask = [self.session uploadTaskWithRequest:request fromData:bodyData]; }); [self addDelegateForUploadTask:uploadTask progress:uploadProgressBlock completionHandler:completionHandler]; return uploadTask; } - (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request progress:(void (^)(NSProgress *uploadProgress)) uploadProgressBlock completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler { __block NSURLSessionUploadTask *uploadTask = nil; url_session_manager_create_task_safely(^{ uploadTask = [self.session uploadTaskWithStreamedRequest:request]; }); [self addDelegateForUploadTask:uploadTask progress:uploadProgressBlock completionHandler:completionHandler]; return uploadTask; } #pragma mark - - (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request progress:(void (^)(NSProgress *downloadProgress)) downloadProgressBlock destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler { __block NSURLSessionDownloadTask *downloadTask = nil; url_session_manager_create_task_safely(^{ downloadTask = [self.session downloadTaskWithRequest:request]; }); [self addDelegateForDownloadTask:downloadTask progress:downloadProgressBlock destination:destination completionHandler:completionHandler]; return downloadTask; } - (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData progress:(void (^)(NSProgress *downloadProgress)) downloadProgressBlock destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler { __block NSURLSessionDownloadTask *downloadTask = nil; url_session_manager_create_task_safely(^{ downloadTask = [self.session downloadTaskWithResumeData:resumeData]; }); [self addDelegateForDownloadTask:downloadTask progress:downloadProgressBlock destination:destination completionHandler:completionHandler]; return downloadTask; } #pragma mark - - (NSProgress *)uploadProgressForTask:(NSURLSessionTask *)task { return [[self delegateForTask:task] uploadProgress]; } - (NSProgress *)downloadProgressForTask:(NSURLSessionTask *)task { return [[self delegateForTask:task] downloadProgress]; } #pragma mark - - (void)setSessionDidBecomeInvalidBlock:(void (^)(NSURLSession *session, NSError *error))block { self.sessionDidBecomeInvalid = block; } - (void)setSessionDidReceiveAuthenticationChallengeBlock:(NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential))block { self.sessionDidReceiveAuthenticationChallenge = block; } - (void)setDidFinishEventsForBackgroundURLSessionBlock:(void (^)(NSURLSession *session))block { self.didFinishEventsForBackgroundURLSession = block; } #pragma mark - - (void)setTaskNeedNewBodyStreamBlock:(NSInputStream * (^)(NSURLSession *session, NSURLSessionTask *task))block { self.taskNeedNewBodyStream = block; } - (void)setTaskWillPerformHTTPRedirectionBlock:(NSURLRequest * (^)(NSURLSession *session, NSURLSessionTask *task, NSURLResponse *response, NSURLRequest *request))block { self.taskWillPerformHTTPRedirection = block; } - (void)setTaskDidReceiveAuthenticationChallengeBlock:(NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential))block { self.taskDidReceiveAuthenticationChallenge = block; } - (void)setTaskDidSendBodyDataBlock:(void (^)(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend))block { self.taskDidSendBodyData = block; } - (void)setTaskDidCompleteBlock:(void (^)(NSURLSession *session, NSURLSessionTask *task, NSError *error))block { self.taskDidComplete = block; } #pragma mark - - (void)setDataTaskDidReceiveResponseBlock:(NSURLSessionResponseDisposition (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response))block { self.dataTaskDidReceiveResponse = block; } - (void)setDataTaskDidBecomeDownloadTaskBlock:(void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask))block { self.dataTaskDidBecomeDownloadTask = block; } - (void)setDataTaskDidReceiveDataBlock:(void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data))block { self.dataTaskDidReceiveData = block; } - (void)setDataTaskWillCacheResponseBlock:(NSCachedURLResponse * (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse))block { self.dataTaskWillCacheResponse = block; } #pragma mark - - (void)setDownloadTaskDidFinishDownloadingBlock:(NSURL * (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location))block { self.downloadTaskDidFinishDownloading = block; } - (void)setDownloadTaskDidWriteDataBlock:(void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite))block { self.downloadTaskDidWriteData = block; } - (void)setDownloadTaskDidResumeBlock:(void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes))block { self.downloadTaskDidResume = block; } #pragma mark - NSObject - (NSString *)description { return [NSString stringWithFormat:@"<%@: %p, session: %@, operationQueue: %@>", NSStringFromClass([self class]), self, self.session, self.operationQueue]; } - (BOOL)respondsToSelector:(SEL)selector { if (selector == @selector(URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:)) { return self.taskWillPerformHTTPRedirection != nil; } else if (selector == @selector(URLSession:dataTask:didReceiveResponse:completionHandler:)) { return self.dataTaskDidReceiveResponse != nil; } else if (selector == @selector(URLSession:dataTask:willCacheResponse:completionHandler:)) { return self.dataTaskWillCacheResponse != nil; } else if (selector == @selector(URLSessionDidFinishEventsForBackgroundURLSession:)) { return self.didFinishEventsForBackgroundURLSession != nil; } return [[self class] instancesRespondToSelector:selector]; } #pragma mark - NSURLSessionDelegate - (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error { if (self.sessionDidBecomeInvalid) { self.sessionDidBecomeInvalid(session, error); } [[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDidInvalidateNotification object:session]; } - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling; __block NSURLCredential *credential = nil; if (self.sessionDidReceiveAuthenticationChallenge) { disposition = self.sessionDidReceiveAuthenticationChallenge(session, challenge, &credential); } else { if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) { credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; if (credential) { disposition = NSURLSessionAuthChallengeUseCredential; } else { disposition = NSURLSessionAuthChallengePerformDefaultHandling; } } else { disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge; } } else { disposition = NSURLSessionAuthChallengePerformDefaultHandling; } } if (completionHandler) { completionHandler(disposition, credential); } } #pragma mark - NSURLSessionTaskDelegate - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest *))completionHandler { NSURLRequest *redirectRequest = request; if (self.taskWillPerformHTTPRedirection) { redirectRequest = self.taskWillPerformHTTPRedirection(session, task, response, request); } if (completionHandler) { completionHandler(redirectRequest); } } - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling; __block NSURLCredential *credential = nil; if (self.taskDidReceiveAuthenticationChallenge) { disposition = self.taskDidReceiveAuthenticationChallenge(session, task, challenge, &credential); } else { if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) { disposition = NSURLSessionAuthChallengeUseCredential; credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; } else { disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge; } } else { disposition = NSURLSessionAuthChallengePerformDefaultHandling; } } if (completionHandler) { completionHandler(disposition, credential); } } - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task needNewBodyStream:(void (^)(NSInputStream *bodyStream))completionHandler { NSInputStream *inputStream = nil; if (self.taskNeedNewBodyStream) { inputStream = self.taskNeedNewBodyStream(session, task); } else if (task.originalRequest.HTTPBodyStream && [task.originalRequest.HTTPBodyStream conformsToProtocol:@protocol(NSCopying)]) { inputStream = [task.originalRequest.HTTPBodyStream copy]; } if (completionHandler) { completionHandler(inputStream); } } - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend { int64_t totalUnitCount = totalBytesExpectedToSend; if(totalUnitCount == NSURLSessionTransferSizeUnknown) { NSString *contentLength = [task.originalRequest valueForHTTPHeaderField:@"Content-Length"]; if(contentLength) { totalUnitCount = (int64_t) [contentLength longLongValue]; } } if (self.taskDidSendBodyData) { self.taskDidSendBodyData(session, task, bytesSent, totalBytesSent, totalUnitCount); } } - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task]; // delegate may be nil when completing a task in the background if (delegate) { [delegate URLSession:session task:task didCompleteWithError:error]; [self removeDelegateForTask:task]; } if (self.taskDidComplete) { self.taskDidComplete(session, task, error); } } #pragma mark - NSURLSessionDataDelegate - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { NSURLSessionResponseDisposition disposition = NSURLSessionResponseAllow; if (self.dataTaskDidReceiveResponse) { disposition = self.dataTaskDidReceiveResponse(session, dataTask, response); } if (completionHandler) { completionHandler(disposition); } } - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask { AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:dataTask]; if (delegate) { [self removeDelegateForTask:dataTask]; [self setDelegate:delegate forTask:downloadTask]; } if (self.dataTaskDidBecomeDownloadTask) { self.dataTaskDidBecomeDownloadTask(session, dataTask, downloadTask); } } - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:dataTask]; [delegate URLSession:session dataTask:dataTask didReceiveData:data]; if (self.dataTaskDidReceiveData) { self.dataTaskDidReceiveData(session, dataTask, data); } } - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask willCacheResponse:(NSCachedURLResponse *)proposedResponse completionHandler:(void (^)(NSCachedURLResponse *cachedResponse))completionHandler { NSCachedURLResponse *cachedResponse = proposedResponse; if (self.dataTaskWillCacheResponse) { cachedResponse = self.dataTaskWillCacheResponse(session, dataTask, proposedResponse); } if (completionHandler) { completionHandler(cachedResponse); } } - (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session { if (self.didFinishEventsForBackgroundURLSession) { dispatch_async(dispatch_get_main_queue(), ^{ self.didFinishEventsForBackgroundURLSession(session); }); } } #pragma mark - NSURLSessionDownloadDelegate - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location { AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:downloadTask]; if (self.downloadTaskDidFinishDownloading) { NSURL *fileURL = self.downloadTaskDidFinishDownloading(session, downloadTask, location); if (fileURL) { delegate.downloadFileURL = fileURL; NSError *error = nil; [[NSFileManager defaultManager] moveItemAtURL:location toURL:fileURL error:&error]; if (error) { [[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDownloadTaskDidFailToMoveFileNotification object:downloadTask userInfo:error.userInfo]; } return; } } if (delegate) { [delegate URLSession:session downloadTask:downloadTask didFinishDownloadingToURL:location]; } } - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite { if (self.downloadTaskDidWriteData) { self.downloadTaskDidWriteData(session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); } } - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes { if (self.downloadTaskDidResume) { self.downloadTaskDidResume(session, downloadTask, fileOffset, expectedTotalBytes); } } #pragma mark - NSSecureCoding + (BOOL)supportsSecureCoding { return YES; } - (instancetype)initWithCoder:(NSCoder *)decoder { NSURLSessionConfiguration *configuration = [decoder decodeObjectOfClass:[NSURLSessionConfiguration class] forKey:@"sessionConfiguration"]; self = [self initWithSessionConfiguration:configuration]; if (!self) { return nil; } return self; } - (void)encodeWithCoder:(NSCoder *)coder { [coder encodeObject:self.session.configuration forKey:@"sessionConfiguration"]; } #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { return [[[self class] allocWithZone:zone] initWithSessionConfiguration:self.session.configuration]; } @end ================================================ FILE: Pods/AFNetworking/LICENSE ================================================ Copyright (c) 2011–2016 Alamofire Software Foundation (http://alamofire.org/) 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. ================================================ FILE: Pods/AFNetworking/README.md ================================================

AFNetworking

[![Build Status](https://travis-ci.org/AFNetworking/AFNetworking.svg)](https://travis-ci.org/AFNetworking/AFNetworking) [![codecov.io](https://codecov.io/github/AFNetworking/AFNetworking/coverage.svg?branch=master)](https://codecov.io/github/AFNetworking/AFNetworking?branch=master) [![CocoaPods Compatible](https://img.shields.io/cocoapods/v/AFNetworking.svg)](https://img.shields.io/cocoapods/v/AFNetworking.svg) [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![Platform](https://img.shields.io/cocoapods/p/AFNetworking.svg?style=flat)](http://cocoadocs.org/docsets/AFNetworking) [![Twitter](https://img.shields.io/badge/twitter-@AFNetworking-blue.svg?style=flat)](http://twitter.com/AFNetworking) AFNetworking is a delightful networking library for iOS and Mac OS X. It's built on top of the [Foundation URL Loading System](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html), extending the powerful high-level networking abstractions built into Cocoa. It has a modular architecture with well-designed, feature-rich APIs that are a joy to use. Perhaps the most important feature of all, however, is the amazing community of developers who use and contribute to AFNetworking every day. AFNetworking powers some of the most popular and critically-acclaimed apps on the iPhone, iPad, and Mac. Choose AFNetworking for your next project, or migrate over your existing projects—you'll be happy you did! ## How To Get Started - [Download AFNetworking](https://github.com/AFNetworking/AFNetworking/archive/master.zip) and try out the included Mac and iPhone example apps - Read the ["Getting Started" guide](https://github.com/AFNetworking/AFNetworking/wiki/Getting-Started-with-AFNetworking), [FAQ](https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ), or [other articles on the Wiki](https://github.com/AFNetworking/AFNetworking/wiki) - Check out the [documentation](http://cocoadocs.org/docsets/AFNetworking/) for a comprehensive look at all of the APIs available in AFNetworking - Read the [AFNetworking 3.0 Migration Guide](https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-3.0-Migration-Guide) for an overview of the architectural changes from 2.0. ## Communication - If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/afnetworking). (Tag 'afnetworking') - If you'd like to **ask a general question**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/afnetworking). - If you **found a bug**, _and can provide steps to reliably reproduce it_, open an issue. - If you **have a feature request**, open an issue. - If you **want to contribute**, submit a pull request. ## Installation AFNetworking supports multiple methods for installing the library in a project. ## Installation with CocoaPods [CocoaPods](http://cocoapods.org) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like AFNetworking in your projects. See the ["Getting Started" guide for more information](https://github.com/AFNetworking/AFNetworking/wiki/Getting-Started-with-AFNetworking). You can install it with the following command: ```bash $ gem install cocoapods ``` > CocoaPods 0.39.0+ is required to build AFNetworking 3.0.0+. #### Podfile To integrate AFNetworking into your Xcode project using CocoaPods, specify it in your `Podfile`: ```ruby source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' pod 'AFNetworking', '~> 3.0' ``` Then, run the following command: ```bash $ pod install ``` ### Installation with Carthage [Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. You can install Carthage with [Homebrew](http://brew.sh/) using the following command: ```bash $ brew update $ brew install carthage ``` To integrate AFNetworking into your Xcode project using Carthage, specify it in your `Cartfile`: ```ogdl github "AFNetworking/AFNetworking" ~> 3.0 ``` Run `carthage` to build the framework and drag the built `AFNetworking.framework` into your Xcode project. ## Requirements | AFNetworking Version | Minimum iOS Target | Minimum OS X Target | Minimum watchOS Target | Minimum tvOS Target | Notes | |:--------------------:|:---------------------------:|:----------------------------:|:----------------------------:|:----------------------------:|:-------------------------------------------------------------------------:| | 3.x | iOS 7 | OS X 10.9 | watchOS 2.0 | tvOS 9.0 | Xcode 7+ is required. `NSURLConnectionOperation` support has been removed. | | 2.6 -> 2.6.3 | iOS 7 | OS X 10.9 | watchOS 2.0 | n/a | Xcode 7+ is required. | | 2.0 -> 2.5.4 | iOS 6 | OS X 10.8 | n/a | n/a | Xcode 5+ is required. `NSURLSession` subspec requires iOS 7 or OS X 10.9. | | 1.x | iOS 5 | Mac OS X 10.7 | n/a | n/a | | 0.10.x | iOS 4 | Mac OS X 10.6 | n/a | n/a | (OS X projects must support [64-bit with modern Cocoa runtime](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtVersionsPlatforms.html)). > Programming in Swift? Try [Alamofire](https://github.com/Alamofire/Alamofire) for a more conventional set of APIs. ## Architecture ### NSURLSession - `AFURLSessionManager` - `AFHTTPSessionManager` ### Serialization * `` - `AFHTTPRequestSerializer` - `AFJSONRequestSerializer` - `AFPropertyListRequestSerializer` * `` - `AFHTTPResponseSerializer` - `AFJSONResponseSerializer` - `AFXMLParserResponseSerializer` - `AFXMLDocumentResponseSerializer` _(Mac OS X)_ - `AFPropertyListResponseSerializer` - `AFImageResponseSerializer` - `AFCompoundResponseSerializer` ### Additional Functionality - `AFSecurityPolicy` - `AFNetworkReachabilityManager` ## Usage ### AFURLSessionManager `AFURLSessionManager` creates and manages an `NSURLSession` object based on a specified `NSURLSessionConfiguration` object, which conforms to ``, ``, ``, and ``. #### Creating a Download Task ```objective-c NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; NSURL *URL = [NSURL URLWithString:@"http://example.com/download.zip"]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) { NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil]; return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]]; } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) { NSLog(@"File downloaded to: %@", filePath); }]; [downloadTask resume]; ``` #### Creating an Upload Task ```objective-c NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; NSURL *URL = [NSURL URLWithString:@"http://example.com/upload"]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"]; NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { if (error) { NSLog(@"Error: %@", error); } else { NSLog(@"Success: %@ %@", response, responseObject); } }]; [uploadTask resume]; ``` #### Creating an Upload Task for a Multi-Part Request, with Progress ```objective-c NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id formData) { [formData appendPartWithFileURL:[NSURL fileURLWithPath:@"file://path/to/image.jpg"] name:@"file" fileName:@"filename.jpg" mimeType:@"image/jpeg" error:nil]; } error:nil]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; NSURLSessionUploadTask *uploadTask; uploadTask = [manager uploadTaskWithStreamedRequest:request progress:^(NSProgress * _Nonnull uploadProgress) { // This is not called back on the main queue. // You are responsible for dispatching to the main queue for UI updates dispatch_async(dispatch_get_main_queue(), ^{ //Update the progress view [progressView setProgress:uploadProgress.fractionCompleted]; }); } completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { if (error) { NSLog(@"Error: %@", error); } else { NSLog(@"%@ %@", response, responseObject); } }]; [uploadTask resume]; ``` #### Creating a Data Task ```objective-c NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; NSURL *URL = [NSURL URLWithString:@"http://httpbin.org/get"]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { if (error) { NSLog(@"Error: %@", error); } else { NSLog(@"%@ %@", response, responseObject); } }]; [dataTask resume]; ``` --- ### Request Serialization Request serializers create requests from URL strings, encoding parameters as either a query string or HTTP body. ```objective-c NSString *URLString = @"http://example.com"; NSDictionary *parameters = @{@"foo": @"bar", @"baz": @[@1, @2, @3]}; ``` #### Query String Parameter Encoding ```objective-c [[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET" URLString:URLString parameters:parameters error:nil]; ``` GET http://example.com?foo=bar&baz[]=1&baz[]=2&baz[]=3 #### URL Form Parameter Encoding ```objective-c [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters error:nil]; ``` POST http://example.com/ Content-Type: application/x-www-form-urlencoded foo=bar&baz[]=1&baz[]=2&baz[]=3 #### JSON Parameter Encoding ```objective-c [[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters error:nil]; ``` POST http://example.com/ Content-Type: application/json {"foo": "bar", "baz": [1,2,3]} --- ### Network Reachability Manager `AFNetworkReachabilityManager` monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces. * Do not use Reachability to determine if the original request should be sent. * You should try to send it. * You can use Reachability to determine when a request should be automatically retried. * Although it may still fail, a Reachability notification that the connectivity is available is a good time to retry something. * Network reachability is a useful tool for determining why a request might have failed. * After a network request has failed, telling the user they're offline is better than giving them a more technical but accurate error, such as "request timed out." See also [WWDC 2012 session 706, "Networking Best Practices."](https://developer.apple.com/videos/play/wwdc2012-706/). #### Shared Network Reachability ```objective-c [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status)); }]; [[AFNetworkReachabilityManager sharedManager] startMonitoring]; ``` --- ### Security Policy `AFSecurityPolicy` evaluates server trust against pinned X.509 certificates and public keys over secure connections. Adding pinned SSL certificates to your app helps prevent man-in-the-middle attacks and other vulnerabilities. Applications dealing with sensitive customer data or financial information are strongly encouraged to route all communication over an HTTPS connection with SSL pinning configured and enabled. #### Allowing Invalid SSL Certificates ```objective-c AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.securityPolicy.allowInvalidCertificates = YES; // not recommended for production ``` --- ## Unit Tests AFNetworking includes a suite of unit tests within the Tests subdirectory. These tests can be run simply be executed the test action on the platform framework you would like to test. ## Credits AFNetworking is owned and maintained by the [Alamofire Software Foundation](http://alamofire.org). AFNetworking was originally created by [Scott Raymond](https://github.com/sco/) and [Mattt Thompson](https://github.com/mattt/) in the development of [Gowalla for iPhone](http://en.wikipedia.org/wiki/Gowalla). AFNetworking's logo was designed by [Alan Defibaugh](http://www.alandefibaugh.com/). And most of all, thanks to AFNetworking's [growing list of contributors](https://github.com/AFNetworking/AFNetworking/contributors). ### Security Disclosure If you believe you have identified a security vulnerability with AFNetworking, you should report it as soon as possible via email to security@alamofire.org. Please do not post it to a public issue tracker. ## License AFNetworking is released under the MIT license. See LICENSE for details. ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/AFAutoPurgingImageCache.h ================================================ // AFAutoPurgingImageCache.h // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #if TARGET_OS_IOS || TARGET_OS_TV #import NS_ASSUME_NONNULL_BEGIN /** The `AFImageCache` protocol defines a set of APIs for adding, removing and fetching images from a cache synchronously. */ @protocol AFImageCache /** Adds the image to the cache with the given identifier. @param image The image to cache. @param identifier The unique identifier for the image in the cache. */ - (void)addImage:(UIImage *)image withIdentifier:(NSString *)identifier; /** Removes the image from the cache matching the given identifier. @param identifier The unique identifier for the image in the cache. @return A BOOL indicating whether or not the image was removed from the cache. */ - (BOOL)removeImageWithIdentifier:(NSString *)identifier; /** Removes all images from the cache. @return A BOOL indicating whether or not all images were removed from the cache. */ - (BOOL)removeAllImages; /** Returns the image in the cache associated with the given identifier. @param identifier The unique identifier for the image in the cache. @return An image for the matching identifier, or nil. */ - (nullable UIImage *)imageWithIdentifier:(NSString *)identifier; @end /** The `ImageRequestCache` protocol extends the `ImageCache` protocol by adding methods for adding, removing and fetching images from a cache given an `NSURLRequest` and additional identifier. */ @protocol AFImageRequestCache /** Adds the image to the cache using an identifier created from the request and additional identifier. @param image The image to cache. @param request The unique URL request identifing the image asset. @param identifier The additional identifier to apply to the URL request to identify the image. */ - (void)addImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier; /** Removes the image from the cache using an identifier created from the request and additional identifier. @param request The unique URL request identifing the image asset. @param identifier The additional identifier to apply to the URL request to identify the image. @return A BOOL indicating whether or not all images were removed from the cache. */ - (BOOL)removeImageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier; /** Returns the image from the cache associated with an identifier created from the request and additional identifier. @param request The unique URL request identifing the image asset. @param identifier The additional identifier to apply to the URL request to identify the image. @return An image for the matching request and identifier, or nil. */ - (nullable UIImage *)imageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(nullable NSString *)identifier; @end /** The `AutoPurgingImageCache` in an in-memory image cache used to store images up to a given memory capacity. When the memory capacity is reached, the image cache is sorted by last access date, then the oldest image is continuously purged until the preferred memory usage after purge is met. Each time an image is accessed through the cache, the internal access date of the image is updated. */ @interface AFAutoPurgingImageCache : NSObject /** The total memory capacity of the cache in bytes. */ @property (nonatomic, assign) UInt64 memoryCapacity; /** The preferred memory usage after purge in bytes. During a purge, images will be purged until the memory capacity drops below this limit. */ @property (nonatomic, assign) UInt64 preferredMemoryUsageAfterPurge; /** The current total memory usage in bytes of all images stored within the cache. */ @property (nonatomic, assign, readonly) UInt64 memoryUsage; /** Initialies the `AutoPurgingImageCache` instance with default values for memory capacity and preferred memory usage after purge limit. `memoryCapcity` defaults to `100 MB`. `preferredMemoryUsageAfterPurge` defaults to `60 MB`. @return The new `AutoPurgingImageCache` instance. */ - (instancetype)init; /** Initialies the `AutoPurgingImageCache` instance with the given memory capacity and preferred memory usage after purge limit. @param memoryCapacity The total memory capacity of the cache in bytes. @param preferredMemoryCapacity The preferred memory usage after purge in bytes. @return The new `AutoPurgingImageCache` instance. */ - (instancetype)initWithMemoryCapacity:(UInt64)memoryCapacity preferredMemoryCapacity:(UInt64)preferredMemoryCapacity; @end NS_ASSUME_NONNULL_END #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/AFAutoPurgingImageCache.m ================================================ // AFAutoPurgingImageCache.m // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #if TARGET_OS_IOS || TARGET_OS_TV #import "AFAutoPurgingImageCache.h" @interface AFCachedImage : NSObject @property (nonatomic, strong) UIImage *image; @property (nonatomic, strong) NSString *identifier; @property (nonatomic, assign) UInt64 totalBytes; @property (nonatomic, strong) NSDate *lastAccessDate; @property (nonatomic, assign) UInt64 currentMemoryUsage; @end @implementation AFCachedImage -(instancetype)initWithImage:(UIImage *)image identifier:(NSString *)identifier { if (self = [self init]) { self.image = image; self.identifier = identifier; CGSize imageSize = CGSizeMake(image.size.width * image.scale, image.size.height * image.scale); CGFloat bytesPerPixel = 4.0; CGFloat bytesPerSize = imageSize.width * imageSize.height; self.totalBytes = (UInt64)bytesPerPixel * (UInt64)bytesPerSize; self.lastAccessDate = [NSDate date]; } return self; } - (UIImage*)accessImage { self.lastAccessDate = [NSDate date]; return self.image; } - (NSString *)description { NSString *descriptionString = [NSString stringWithFormat:@"Idenfitier: %@ lastAccessDate: %@ ", self.identifier, self.lastAccessDate]; return descriptionString; } @end @interface AFAutoPurgingImageCache () @property (nonatomic, strong) NSMutableDictionary *cachedImages; @property (nonatomic, assign) UInt64 currentMemoryUsage; @property (nonatomic, strong) dispatch_queue_t synchronizationQueue; @end @implementation AFAutoPurgingImageCache - (instancetype)init { return [self initWithMemoryCapacity:100 * 1024 * 1024 preferredMemoryCapacity:60 * 1024 * 1024]; } - (instancetype)initWithMemoryCapacity:(UInt64)memoryCapacity preferredMemoryCapacity:(UInt64)preferredMemoryCapacity { if (self = [super init]) { self.memoryCapacity = memoryCapacity; self.preferredMemoryUsageAfterPurge = preferredMemoryCapacity; self.cachedImages = [[NSMutableDictionary alloc] init]; NSString *queueName = [NSString stringWithFormat:@"com.alamofire.autopurgingimagecache-%@", [[NSUUID UUID] UUIDString]]; self.synchronizationQueue = dispatch_queue_create([queueName cStringUsingEncoding:NSASCIIStringEncoding], DISPATCH_QUEUE_CONCURRENT); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllImages) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; } return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (UInt64)memoryUsage { __block UInt64 result = 0; dispatch_sync(self.synchronizationQueue, ^{ result = self.currentMemoryUsage; }); return result; } - (void)addImage:(UIImage *)image withIdentifier:(NSString *)identifier { dispatch_barrier_async(self.synchronizationQueue, ^{ AFCachedImage *cacheImage = [[AFCachedImage alloc] initWithImage:image identifier:identifier]; AFCachedImage *previousCachedImage = self.cachedImages[identifier]; if (previousCachedImage != nil) { self.currentMemoryUsage -= previousCachedImage.totalBytes; } self.cachedImages[identifier] = cacheImage; self.currentMemoryUsage += cacheImage.totalBytes; }); dispatch_barrier_async(self.synchronizationQueue, ^{ if (self.currentMemoryUsage > self.memoryCapacity) { UInt64 bytesToPurge = self.currentMemoryUsage - self.preferredMemoryUsageAfterPurge; NSMutableArray *sortedImages = [NSMutableArray arrayWithArray:self.cachedImages.allValues]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastAccessDate" ascending:YES]; [sortedImages sortUsingDescriptors:@[sortDescriptor]]; UInt64 bytesPurged = 0; for (AFCachedImage *cachedImage in sortedImages) { [self.cachedImages removeObjectForKey:cachedImage.identifier]; bytesPurged += cachedImage.totalBytes; if (bytesPurged >= bytesToPurge) { break ; } } self.currentMemoryUsage -= bytesPurged; } }); } - (BOOL)removeImageWithIdentifier:(NSString *)identifier { __block BOOL removed = NO; dispatch_barrier_sync(self.synchronizationQueue, ^{ AFCachedImage *cachedImage = self.cachedImages[identifier]; if (cachedImage != nil) { [self.cachedImages removeObjectForKey:identifier]; self.currentMemoryUsage -= cachedImage.totalBytes; removed = YES; } }); return removed; } - (BOOL)removeAllImages { __block BOOL removed = NO; dispatch_barrier_sync(self.synchronizationQueue, ^{ if (self.cachedImages.count > 0) { [self.cachedImages removeAllObjects]; self.currentMemoryUsage = 0; removed = YES; } }); return removed; } - (nullable UIImage *)imageWithIdentifier:(NSString *)identifier { __block UIImage *image = nil; dispatch_sync(self.synchronizationQueue, ^{ AFCachedImage *cachedImage = self.cachedImages[identifier]; image = [cachedImage accessImage]; }); return image; } - (void)addImage:(UIImage *)image forRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)identifier { [self addImage:image withIdentifier:[self imageCacheKeyFromURLRequest:request withAdditionalIdentifier:identifier]]; } - (BOOL)removeImageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)identifier { return [self removeImageWithIdentifier:[self imageCacheKeyFromURLRequest:request withAdditionalIdentifier:identifier]]; } - (nullable UIImage *)imageforRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)identifier { return [self imageWithIdentifier:[self imageCacheKeyFromURLRequest:request withAdditionalIdentifier:identifier]]; } - (NSString *)imageCacheKeyFromURLRequest:(NSURLRequest *)request withAdditionalIdentifier:(NSString *)additionalIdentifier { NSString *key = request.URL.absoluteString; if (additionalIdentifier != nil) { key = [key stringByAppendingString:additionalIdentifier]; } return key; } @end #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/AFImageDownloader.h ================================================ // AFImageDownloader.h // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #if TARGET_OS_IOS || TARGET_OS_TV #import #import "AFAutoPurgingImageCache.h" #import "AFHTTPSessionManager.h" NS_ASSUME_NONNULL_BEGIN typedef NS_ENUM(NSInteger, AFImageDownloadPrioritization) { AFImageDownloadPrioritizationFIFO, AFImageDownloadPrioritizationLIFO }; /** The `AFImageDownloadReceipt` is an object vended by the `AFImageDownloader` when starting a data task. It can be used to cancel active tasks running on the `AFImageDownloader` session. As a general rule, image data tasks should be cancelled using the `AFImageDownloadReceipt` instead of calling `cancel` directly on the `task` itself. The `AFImageDownloader` is optimized to handle duplicate task scenarios as well as pending versus active downloads. */ @interface AFImageDownloadReceipt : NSObject /** The data task created by the `AFImageDownloader`. */ @property (nonatomic, strong) NSURLSessionDataTask *task; /** The unique identifier for the success and failure blocks when duplicate requests are made. */ @property (nonatomic, strong) NSUUID *receiptID; @end /** The `AFImageDownloader` class is responsible for downloading images in parallel on a prioritized queue. Incoming downloads are added to the front or back of the queue depending on the download prioritization. Each downloaded image is cached in the underlying `NSURLCache` as well as the in-memory image cache. By default, any download request with a cached image equivalent in the image cache will automatically be served the cached image representation. */ @interface AFImageDownloader : NSObject /** The image cache used to store all downloaded images in. `AFAutoPurgingImageCache` by default. */ @property (nonatomic, strong, nullable) id imageCache; /** The `AFHTTPSessionManager` used to download images. By default, this is configured with an `AFImageResponseSerializer`, and a shared `NSURLCache` for all image downloads. */ @property (nonatomic, strong) AFHTTPSessionManager *sessionManager; /** Defines the order prioritization of incoming download requests being inserted into the queue. `AFImageDownloadPrioritizationFIFO` by default. */ @property (nonatomic, assign) AFImageDownloadPrioritization downloadPrioritizaton; /** The shared default instance of `AFImageDownloader` initialized with default values. */ + (instancetype)defaultInstance; /** Creates a default `NSURLCache` with common usage parameter values. @returns The default `NSURLCache` instance. */ + (NSURLCache *)defaultURLCache; /** Default initializer @return An instance of `AFImageDownloader` initialized with default values. */ - (instancetype)init; /** Initializes the `AFImageDownloader` instance with the given session manager, download prioritization, maximum active download count and image cache. @param sessionManager The session manager to use to download images. @param downloadPrioritization The download prioritization of the download queue. @param maximumActiveDownloads The maximum number of active downloads allowed at any given time. Recommend `4`. @param imageCache The image cache used to store all downloaded images in. @return The new `AFImageDownloader` instance. */ - (instancetype)initWithSessionManager:(AFHTTPSessionManager *)sessionManager downloadPrioritization:(AFImageDownloadPrioritization)downloadPrioritization maximumActiveDownloads:(NSInteger)maximumActiveDownloads imageCache:(nullable id )imageCache; /** Creates a data task using the `sessionManager` instance for the specified URL request. If the same data task is already in the queue or currently being downloaded, the success and failure blocks are appended to the already existing task. Once the task completes, all success or failure blocks attached to the task are executed in the order they were added. @param request The URL request. @param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`. @param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred. @return The image download receipt for the data task if available. `nil` if the image is stored in the cache. cache and the URL request cache policy allows the cache to be used. */ - (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *responseObject))success failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure; /** Creates a data task using the `sessionManager` instance for the specified URL request. If the same data task is already in the queue or currently being downloaded, the success and failure blocks are appended to the already existing task. Once the task completes, all success or failure blocks attached to the task are executed in the order they were added. @param request The URL request. @param receiptID The identifier to use for the download receipt that will be created for this request. This must be a unique identifier that does not represent any other request. @param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`. @param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred. @return The image download receipt for the data task if available. `nil` if the image is stored in the cache. cache and the URL request cache policy allows the cache to be used. */ - (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request withReceiptID:(NSUUID *)receiptID success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *responseObject))success failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure; /** Cancels the data task in the receipt by removing the corresponding success and failure blocks and cancelling the data task if necessary. If the data task is pending in the queue, it will be cancelled if no other success and failure blocks are registered with the data task. If the data task is currently executing or is already completed, the success and failure blocks are removed and will not be called when the task finishes. @param imageDownloadReceipt The image download receipt to cancel. */ - (void)cancelTaskForImageDownloadReceipt:(AFImageDownloadReceipt *)imageDownloadReceipt; @end #endif NS_ASSUME_NONNULL_END ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/AFImageDownloader.m ================================================ // AFImageDownloader.m // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #if TARGET_OS_IOS || TARGET_OS_TV #import "AFImageDownloader.h" #import "AFHTTPSessionManager.h" @interface AFImageDownloaderResponseHandler : NSObject @property (nonatomic, strong) NSUUID *uuid; @property (nonatomic, copy) void (^successBlock)(NSURLRequest*, NSHTTPURLResponse*, UIImage*); @property (nonatomic, copy) void (^failureBlock)(NSURLRequest*, NSHTTPURLResponse*, NSError*); @end @implementation AFImageDownloaderResponseHandler - (instancetype)initWithUUID:(NSUUID *)uuid success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *responseObject))success failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure { if (self = [self init]) { self.uuid = uuid; self.successBlock = success; self.failureBlock = failure; } return self; } - (NSString *)description { return [NSString stringWithFormat: @"UUID: %@", [self.uuid UUIDString]]; } @end @interface AFImageDownloaderMergedTask : NSObject @property (nonatomic, strong) NSString *URLIdentifier; @property (nonatomic, strong) NSUUID *identifier; @property (nonatomic, strong) NSURLSessionDataTask *task; @property (nonatomic, strong) NSMutableArray *responseHandlers; @end @implementation AFImageDownloaderMergedTask - (instancetype)initWithURLIdentifier:(NSString *)URLIdentifier identifier:(NSUUID *)identifier task:(NSURLSessionDataTask *)task { if (self = [self init]) { self.URLIdentifier = URLIdentifier; self.task = task; self.identifier = identifier; self.responseHandlers = [[NSMutableArray alloc] init]; } return self; } - (void)addResponseHandler:(AFImageDownloaderResponseHandler*)handler { [self.responseHandlers addObject:handler]; } - (void)removeResponseHandler:(AFImageDownloaderResponseHandler*)handler { [self.responseHandlers removeObject:handler]; } @end @implementation AFImageDownloadReceipt - (instancetype)initWithReceiptID:(NSUUID *)receiptID task:(NSURLSessionDataTask *)task { if (self = [self init]) { self.receiptID = receiptID; self.task = task; } return self; } @end @interface AFImageDownloader () @property (nonatomic, strong) dispatch_queue_t synchronizationQueue; @property (nonatomic, strong) dispatch_queue_t responseQueue; @property (nonatomic, assign) NSInteger maximumActiveDownloads; @property (nonatomic, assign) NSInteger activeRequestCount; @property (nonatomic, strong) NSMutableArray *queuedMergedTasks; @property (nonatomic, strong) NSMutableDictionary *mergedTasks; @end @implementation AFImageDownloader + (NSURLCache *)defaultURLCache { return [[NSURLCache alloc] initWithMemoryCapacity:20 * 1024 * 1024 diskCapacity:150 * 1024 * 1024 diskPath:@"com.alamofire.imagedownloader"]; } + (NSURLSessionConfiguration *)defaultURLSessionConfiguration { NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; //TODO set the default HTTP headers configuration.HTTPShouldSetCookies = YES; configuration.HTTPShouldUsePipelining = NO; configuration.requestCachePolicy = NSURLRequestUseProtocolCachePolicy; configuration.allowsCellularAccess = YES; configuration.timeoutIntervalForRequest = 60.0; configuration.URLCache = [AFImageDownloader defaultURLCache]; return configuration; } - (instancetype)init { NSURLSessionConfiguration *defaultConfiguration = [self.class defaultURLSessionConfiguration]; AFHTTPSessionManager *sessionManager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:defaultConfiguration]; sessionManager.responseSerializer = [AFImageResponseSerializer serializer]; return [self initWithSessionManager:sessionManager downloadPrioritization:AFImageDownloadPrioritizationFIFO maximumActiveDownloads:4 imageCache:[[AFAutoPurgingImageCache alloc] init]]; } - (instancetype)initWithSessionManager:(AFHTTPSessionManager *)sessionManager downloadPrioritization:(AFImageDownloadPrioritization)downloadPrioritization maximumActiveDownloads:(NSInteger)maximumActiveDownloads imageCache:(id )imageCache { if (self = [super init]) { self.sessionManager = sessionManager; self.downloadPrioritizaton = downloadPrioritization; self.maximumActiveDownloads = maximumActiveDownloads; self.imageCache = imageCache; self.queuedMergedTasks = [[NSMutableArray alloc] init]; self.mergedTasks = [[NSMutableDictionary alloc] init]; self.activeRequestCount = 0; NSString *name = [NSString stringWithFormat:@"com.alamofire.imagedownloader.synchronizationqueue-%@", [[NSUUID UUID] UUIDString]]; self.synchronizationQueue = dispatch_queue_create([name cStringUsingEncoding:NSASCIIStringEncoding], DISPATCH_QUEUE_SERIAL); name = [NSString stringWithFormat:@"com.alamofire.imagedownloader.responsequeue-%@", [[NSUUID UUID] UUIDString]]; self.responseQueue = dispatch_queue_create([name cStringUsingEncoding:NSASCIIStringEncoding], DISPATCH_QUEUE_CONCURRENT); } return self; } + (instancetype)defaultInstance { static AFImageDownloader *sharedInstance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedInstance = [[self alloc] init]; }); return sharedInstance; } - (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request success:(void (^)(NSURLRequest * _Nonnull, NSHTTPURLResponse * _Nullable, UIImage * _Nonnull))success failure:(void (^)(NSURLRequest * _Nonnull, NSHTTPURLResponse * _Nullable, NSError * _Nonnull))failure { return [self downloadImageForURLRequest:request withReceiptID:[NSUUID UUID] success:success failure:failure]; } - (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:(NSURLRequest *)request withReceiptID:(nonnull NSUUID *)receiptID success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *responseObject))success failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure { __block NSURLSessionDataTask *task = nil; dispatch_sync(self.synchronizationQueue, ^{ NSString *URLIdentifier = request.URL.absoluteString; if (URLIdentifier == nil) { if (failure) { NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorBadURL userInfo:nil]; dispatch_async(dispatch_get_main_queue(), ^{ failure(request, nil, error); }); } return; } // 1) Append the success and failure blocks to a pre-existing request if it already exists AFImageDownloaderMergedTask *existingMergedTask = self.mergedTasks[URLIdentifier]; if (existingMergedTask != nil) { AFImageDownloaderResponseHandler *handler = [[AFImageDownloaderResponseHandler alloc] initWithUUID:receiptID success:success failure:failure]; [existingMergedTask addResponseHandler:handler]; task = existingMergedTask.task; return; } // 2) Attempt to load the image from the image cache if the cache policy allows it switch (request.cachePolicy) { case NSURLRequestUseProtocolCachePolicy: case NSURLRequestReturnCacheDataElseLoad: case NSURLRequestReturnCacheDataDontLoad: { UIImage *cachedImage = [self.imageCache imageforRequest:request withAdditionalIdentifier:nil]; if (cachedImage != nil) { if (success) { dispatch_async(dispatch_get_main_queue(), ^{ success(request, nil, cachedImage); }); } return; } break; } default: break; } // 3) Create the request and set up authentication, validation and response serialization NSUUID *mergedTaskIdentifier = [NSUUID UUID]; NSURLSessionDataTask *createdTask; __weak __typeof__(self) weakSelf = self; createdTask = [self.sessionManager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { dispatch_async(self.responseQueue, ^{ __strong __typeof__(weakSelf) strongSelf = weakSelf; AFImageDownloaderMergedTask *mergedTask = self.mergedTasks[URLIdentifier]; if ([mergedTask.identifier isEqual:mergedTaskIdentifier]) { mergedTask = [strongSelf safelyRemoveMergedTaskWithURLIdentifier:URLIdentifier]; if (error) { for (AFImageDownloaderResponseHandler *handler in mergedTask.responseHandlers) { if (handler.failureBlock) { dispatch_async(dispatch_get_main_queue(), ^{ handler.failureBlock(request, (NSHTTPURLResponse*)response, error); }); } } } else { [strongSelf.imageCache addImage:responseObject forRequest:request withAdditionalIdentifier:nil]; for (AFImageDownloaderResponseHandler *handler in mergedTask.responseHandlers) { if (handler.successBlock) { dispatch_async(dispatch_get_main_queue(), ^{ handler.successBlock(request, (NSHTTPURLResponse*)response, responseObject); }); } } } } [strongSelf safelyDecrementActiveTaskCount]; [strongSelf safelyStartNextTaskIfNecessary]; }); }]; // 4) Store the response handler for use when the request completes AFImageDownloaderResponseHandler *handler = [[AFImageDownloaderResponseHandler alloc] initWithUUID:receiptID success:success failure:failure]; AFImageDownloaderMergedTask *mergedTask = [[AFImageDownloaderMergedTask alloc] initWithURLIdentifier:URLIdentifier identifier:mergedTaskIdentifier task:createdTask]; [mergedTask addResponseHandler:handler]; self.mergedTasks[URLIdentifier] = mergedTask; // 5) Either start the request or enqueue it depending on the current active request count if ([self isActiveRequestCountBelowMaximumLimit]) { [self startMergedTask:mergedTask]; } else { [self enqueueMergedTask:mergedTask]; } task = mergedTask.task; }); if (task) { return [[AFImageDownloadReceipt alloc] initWithReceiptID:receiptID task:task]; } else { return nil; } } - (void)cancelTaskForImageDownloadReceipt:(AFImageDownloadReceipt *)imageDownloadReceipt { dispatch_sync(self.synchronizationQueue, ^{ NSString *URLIdentifier = imageDownloadReceipt.task.originalRequest.URL.absoluteString; AFImageDownloaderMergedTask *mergedTask = self.mergedTasks[URLIdentifier]; NSUInteger index = [mergedTask.responseHandlers indexOfObjectPassingTest:^BOOL(AFImageDownloaderResponseHandler * _Nonnull handler, __unused NSUInteger idx, __unused BOOL * _Nonnull stop) { return handler.uuid == imageDownloadReceipt.receiptID; }]; if (index != NSNotFound) { AFImageDownloaderResponseHandler *handler = mergedTask.responseHandlers[index]; [mergedTask removeResponseHandler:handler]; NSString *failureReason = [NSString stringWithFormat:@"ImageDownloader cancelled URL request: %@",imageDownloadReceipt.task.originalRequest.URL.absoluteString]; NSDictionary *userInfo = @{NSLocalizedFailureReasonErrorKey:failureReason}; NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:userInfo]; if (handler.failureBlock) { dispatch_async(dispatch_get_main_queue(), ^{ handler.failureBlock(imageDownloadReceipt.task.originalRequest, nil, error); }); } } if (mergedTask.responseHandlers.count == 0 && mergedTask.task.state == NSURLSessionTaskStateSuspended) { [mergedTask.task cancel]; [self removeMergedTaskWithURLIdentifier:URLIdentifier]; } }); } - (AFImageDownloaderMergedTask*)safelyRemoveMergedTaskWithURLIdentifier:(NSString *)URLIdentifier { __block AFImageDownloaderMergedTask *mergedTask = nil; dispatch_sync(self.synchronizationQueue, ^{ mergedTask = [self removeMergedTaskWithURLIdentifier:URLIdentifier]; }); return mergedTask; } //This method should only be called from safely within the synchronizationQueue - (AFImageDownloaderMergedTask *)removeMergedTaskWithURLIdentifier:(NSString *)URLIdentifier { AFImageDownloaderMergedTask *mergedTask = self.mergedTasks[URLIdentifier]; [self.mergedTasks removeObjectForKey:URLIdentifier]; return mergedTask; } - (void)safelyDecrementActiveTaskCount { dispatch_sync(self.synchronizationQueue, ^{ if (self.activeRequestCount > 0) { self.activeRequestCount -= 1; } }); } - (void)safelyStartNextTaskIfNecessary { dispatch_sync(self.synchronizationQueue, ^{ if ([self isActiveRequestCountBelowMaximumLimit]) { while (self.queuedMergedTasks.count > 0) { AFImageDownloaderMergedTask *mergedTask = [self dequeueMergedTask]; if (mergedTask.task.state == NSURLSessionTaskStateSuspended) { [self startMergedTask:mergedTask]; break; } } } }); } - (void)startMergedTask:(AFImageDownloaderMergedTask *)mergedTask { [mergedTask.task resume]; ++self.activeRequestCount; } - (void)enqueueMergedTask:(AFImageDownloaderMergedTask *)mergedTask { switch (self.downloadPrioritizaton) { case AFImageDownloadPrioritizationFIFO: [self.queuedMergedTasks addObject:mergedTask]; break; case AFImageDownloadPrioritizationLIFO: [self.queuedMergedTasks insertObject:mergedTask atIndex:0]; break; } } - (AFImageDownloaderMergedTask *)dequeueMergedTask { AFImageDownloaderMergedTask *mergedTask = nil; mergedTask = [self.queuedMergedTasks firstObject]; [self.queuedMergedTasks removeObject:mergedTask]; return mergedTask; } - (BOOL)isActiveRequestCountBelowMaximumLimit { return self.activeRequestCount < self.maximumActiveDownloads; } @end #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.h ================================================ // AFNetworkActivityIndicatorManager.h // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #if TARGET_OS_IOS #import NS_ASSUME_NONNULL_BEGIN /** `AFNetworkActivityIndicatorManager` manages the state of the network activity indicator in the status bar. When enabled, it will listen for notifications indicating that a session task has started or finished, and start or stop animating the indicator accordingly. The number of active requests is incremented and decremented much like a stack or a semaphore, and the activity indicator will animate so long as that number is greater than zero. You should enable the shared instance of `AFNetworkActivityIndicatorManager` when your application finishes launching. In `AppDelegate application:didFinishLaunchingWithOptions:` you can do so with the following code: [[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES]; By setting `enabled` to `YES` for `sharedManager`, the network activity indicator will show and hide automatically as requests start and finish. You should not ever need to call `incrementActivityCount` or `decrementActivityCount` yourself. See the Apple Human Interface Guidelines section about the Network Activity Indicator for more information: http://developer.apple.com/library/iOS/#documentation/UserExperience/Conceptual/MobileHIG/UIElementGuidelines/UIElementGuidelines.html#//apple_ref/doc/uid/TP40006556-CH13-SW44 */ NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropriate instead.") @interface AFNetworkActivityIndicatorManager : NSObject /** A Boolean value indicating whether the manager is enabled. If YES, the manager will change status bar network activity indicator according to network operation notifications it receives. The default value is NO. */ @property (nonatomic, assign, getter = isEnabled) BOOL enabled; /** A Boolean value indicating whether the network activity indicator manager is currently active. */ @property (readonly, nonatomic, assign, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible; /** A time interval indicating the minimum duration of networking activity that should occur before the activity indicator is displayed. The default value 1 second. If the network activity indicator should be displayed immediately when network activity occurs, this value should be set to 0 seconds. Apple's HIG describes the following: > Display the network activity indicator to provide feedback when your app accesses the network for more than a couple of seconds. If the operation finishes sooner than that, you don’t have to show the network activity indicator, because the indicator is likely to disappear before users notice its presence. */ @property (nonatomic, assign) NSTimeInterval activationDelay; /** A time interval indicating the duration of time of no networking activity required before the activity indicator is disabled. This allows for continuous display of the network activity indicator across multiple requests. The default value is 0.17 seconds. */ @property (nonatomic, assign) NSTimeInterval completionDelay; /** Returns the shared network activity indicator manager object for the system. @return The systemwide network activity indicator manager. */ + (instancetype)sharedManager; /** Increments the number of active network requests. If this number was zero before incrementing, this will start animating the status bar network activity indicator. */ - (void)incrementActivityCount; /** Decrements the number of active network requests. If this number becomes zero after decrementing, this will stop animating the status bar network activity indicator. */ - (void)decrementActivityCount; /** Set the a custom method to be executed when the network activity indicator manager should be hidden/shown. By default, this is null, and the UIApplication Network Activity Indicator will be managed automatically. If this block is set, it is the responsiblity of the caller to manager the network activity indicator going forward. @param block A block to be executed when the network activity indicator status changes. */ - (void)setNetworkingActivityActionWithBlock:(nullable void (^)(BOOL networkActivityIndicatorVisible))block; @end NS_ASSUME_NONNULL_END #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m ================================================ // AFNetworkActivityIndicatorManager.m // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "AFNetworkActivityIndicatorManager.h" #if TARGET_OS_IOS #import "AFURLSessionManager.h" typedef NS_ENUM(NSInteger, AFNetworkActivityManagerState) { AFNetworkActivityManagerStateNotActive, AFNetworkActivityManagerStateDelayingStart, AFNetworkActivityManagerStateActive, AFNetworkActivityManagerStateDelayingEnd }; static NSTimeInterval const kDefaultAFNetworkActivityManagerActivationDelay = 1.0; static NSTimeInterval const kDefaultAFNetworkActivityManagerCompletionDelay = 0.17; static NSURLRequest * AFNetworkRequestFromNotification(NSNotification *notification) { if ([[notification object] respondsToSelector:@selector(originalRequest)]) { return [(NSURLSessionTask *)[notification object] originalRequest]; } else { return nil; } } typedef void (^AFNetworkActivityActionBlock)(BOOL networkActivityIndicatorVisible); @interface AFNetworkActivityIndicatorManager () @property (readwrite, nonatomic, assign) NSInteger activityCount; @property (readwrite, nonatomic, strong) NSTimer *activationDelayTimer; @property (readwrite, nonatomic, strong) NSTimer *completionDelayTimer; @property (readonly, nonatomic, getter = isNetworkActivityOccurring) BOOL networkActivityOccurring; @property (nonatomic, copy) AFNetworkActivityActionBlock networkActivityActionBlock; @property (nonatomic, assign) AFNetworkActivityManagerState currentState; @property (nonatomic, assign, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible; - (void)updateCurrentStateForNetworkActivityChange; @end @implementation AFNetworkActivityIndicatorManager + (instancetype)sharedManager { static AFNetworkActivityIndicatorManager *_sharedManager = nil; static dispatch_once_t oncePredicate; dispatch_once(&oncePredicate, ^{ _sharedManager = [[self alloc] init]; }); return _sharedManager; } - (instancetype)init { self = [super init]; if (!self) { return nil; } self.currentState = AFNetworkActivityManagerStateNotActive; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidStart:) name:AFNetworkingTaskDidResumeNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidSuspendNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidCompleteNotification object:nil]; self.activationDelay = kDefaultAFNetworkActivityManagerActivationDelay; self.completionDelay = kDefaultAFNetworkActivityManagerCompletionDelay; return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [_activationDelayTimer invalidate]; [_completionDelayTimer invalidate]; } - (void)setEnabled:(BOOL)enabled { _enabled = enabled; if (enabled == NO) { [self setCurrentState:AFNetworkActivityManagerStateNotActive]; } } - (void)setNetworkingActivityActionWithBlock:(void (^)(BOOL networkActivityIndicatorVisible))block { self.networkActivityActionBlock = block; } - (BOOL)isNetworkActivityOccurring { @synchronized(self) { return self.activityCount > 0; } } - (void)setNetworkActivityIndicatorVisible:(BOOL)networkActivityIndicatorVisible { if (_networkActivityIndicatorVisible != networkActivityIndicatorVisible) { [self willChangeValueForKey:@"networkActivityIndicatorVisible"]; @synchronized(self) { _networkActivityIndicatorVisible = networkActivityIndicatorVisible; } [self didChangeValueForKey:@"networkActivityIndicatorVisible"]; if (self.networkActivityActionBlock) { self.networkActivityActionBlock(networkActivityIndicatorVisible); } else { [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:networkActivityIndicatorVisible]; } } } - (void)setActivityCount:(NSInteger)activityCount { @synchronized(self) { _activityCount = activityCount; } dispatch_async(dispatch_get_main_queue(), ^{ [self updateCurrentStateForNetworkActivityChange]; }); } - (void)incrementActivityCount { [self willChangeValueForKey:@"activityCount"]; @synchronized(self) { _activityCount++; } [self didChangeValueForKey:@"activityCount"]; dispatch_async(dispatch_get_main_queue(), ^{ [self updateCurrentStateForNetworkActivityChange]; }); } - (void)decrementActivityCount { [self willChangeValueForKey:@"activityCount"]; @synchronized(self) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" _activityCount = MAX(_activityCount - 1, 0); #pragma clang diagnostic pop } [self didChangeValueForKey:@"activityCount"]; dispatch_async(dispatch_get_main_queue(), ^{ [self updateCurrentStateForNetworkActivityChange]; }); } - (void)networkRequestDidStart:(NSNotification *)notification { if ([AFNetworkRequestFromNotification(notification) URL]) { [self incrementActivityCount]; } } - (void)networkRequestDidFinish:(NSNotification *)notification { if ([AFNetworkRequestFromNotification(notification) URL]) { [self decrementActivityCount]; } } #pragma mark - Internal State Management - (void)setCurrentState:(AFNetworkActivityManagerState)currentState { @synchronized(self) { if (_currentState != currentState) { [self willChangeValueForKey:@"currentState"]; _currentState = currentState; switch (currentState) { case AFNetworkActivityManagerStateNotActive: [self cancelActivationDelayTimer]; [self cancelCompletionDelayTimer]; [self setNetworkActivityIndicatorVisible:NO]; break; case AFNetworkActivityManagerStateDelayingStart: [self startActivationDelayTimer]; break; case AFNetworkActivityManagerStateActive: [self cancelCompletionDelayTimer]; [self setNetworkActivityIndicatorVisible:YES]; break; case AFNetworkActivityManagerStateDelayingEnd: [self startCompletionDelayTimer]; break; } } [self didChangeValueForKey:@"currentState"]; } } - (void)updateCurrentStateForNetworkActivityChange { if (self.enabled) { switch (self.currentState) { case AFNetworkActivityManagerStateNotActive: if (self.isNetworkActivityOccurring) { [self setCurrentState:AFNetworkActivityManagerStateDelayingStart]; } break; case AFNetworkActivityManagerStateDelayingStart: //No op. Let the delay timer finish out. break; case AFNetworkActivityManagerStateActive: if (!self.isNetworkActivityOccurring) { [self setCurrentState:AFNetworkActivityManagerStateDelayingEnd]; } break; case AFNetworkActivityManagerStateDelayingEnd: if (self.isNetworkActivityOccurring) { [self setCurrentState:AFNetworkActivityManagerStateActive]; } break; } } } - (void)startActivationDelayTimer { self.activationDelayTimer = [NSTimer timerWithTimeInterval:self.activationDelay target:self selector:@selector(activationDelayTimerFired) userInfo:nil repeats:NO]; [[NSRunLoop mainRunLoop] addTimer:self.activationDelayTimer forMode:NSRunLoopCommonModes]; } - (void)activationDelayTimerFired { if (self.networkActivityOccurring) { [self setCurrentState:AFNetworkActivityManagerStateActive]; } else { [self setCurrentState:AFNetworkActivityManagerStateNotActive]; } } - (void)startCompletionDelayTimer { [self.completionDelayTimer invalidate]; self.completionDelayTimer = [NSTimer timerWithTimeInterval:self.completionDelay target:self selector:@selector(completionDelayTimerFired) userInfo:nil repeats:NO]; [[NSRunLoop mainRunLoop] addTimer:self.completionDelayTimer forMode:NSRunLoopCommonModes]; } - (void)completionDelayTimerFired { [self setCurrentState:AFNetworkActivityManagerStateNotActive]; } - (void)cancelActivationDelayTimer { [self.activationDelayTimer invalidate]; } - (void)cancelCompletionDelayTimer { [self.completionDelayTimer invalidate]; } @end #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.h ================================================ // UIActivityIndicatorView+AFNetworking.h // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #if TARGET_OS_IOS || TARGET_OS_TV #import /** This category adds methods to the UIKit framework's `UIActivityIndicatorView` class. The methods in this category provide support for automatically starting and stopping animation depending on the loading state of a session task. */ @interface UIActivityIndicatorView (AFNetworking) ///---------------------------------- /// @name Animating for Session Tasks ///---------------------------------- /** Binds the animating state to the state of the specified task. @param task The task. If `nil`, automatic updating from any previously specified operation will be disabled. */ - (void)setAnimatingWithStateOfTask:(nullable NSURLSessionTask *)task; @end #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.m ================================================ // UIActivityIndicatorView+AFNetworking.m // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "UIActivityIndicatorView+AFNetworking.h" #import #if TARGET_OS_IOS || TARGET_OS_TV #import "AFURLSessionManager.h" @interface AFActivityIndicatorViewNotificationObserver : NSObject @property (readonly, nonatomic, weak) UIActivityIndicatorView *activityIndicatorView; - (instancetype)initWithActivityIndicatorView:(UIActivityIndicatorView *)activityIndicatorView; - (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task; @end @implementation UIActivityIndicatorView (AFNetworking) - (AFActivityIndicatorViewNotificationObserver *)af_notificationObserver { AFActivityIndicatorViewNotificationObserver *notificationObserver = objc_getAssociatedObject(self, @selector(af_notificationObserver)); if (notificationObserver == nil) { notificationObserver = [[AFActivityIndicatorViewNotificationObserver alloc] initWithActivityIndicatorView:self]; objc_setAssociatedObject(self, @selector(af_notificationObserver), notificationObserver, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } return notificationObserver; } - (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task { [[self af_notificationObserver] setAnimatingWithStateOfTask:task]; } @end @implementation AFActivityIndicatorViewNotificationObserver - (instancetype)initWithActivityIndicatorView:(UIActivityIndicatorView *)activityIndicatorView { self = [super init]; if (self) { _activityIndicatorView = activityIndicatorView; } return self; } - (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task { NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil]; if (task) { if (task.state != NSURLSessionTaskStateCompleted) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wreceiver-is-weak" #pragma clang diagnostic ignored "-Warc-repeated-use-of-weak" if (task.state == NSURLSessionTaskStateRunning) { [self.activityIndicatorView startAnimating]; } else { [self.activityIndicatorView stopAnimating]; } #pragma clang diagnostic pop [notificationCenter addObserver:self selector:@selector(af_startAnimating) name:AFNetworkingTaskDidResumeNotification object:task]; [notificationCenter addObserver:self selector:@selector(af_stopAnimating) name:AFNetworkingTaskDidCompleteNotification object:task]; [notificationCenter addObserver:self selector:@selector(af_stopAnimating) name:AFNetworkingTaskDidSuspendNotification object:task]; } } } #pragma mark - - (void)af_startAnimating { dispatch_async(dispatch_get_main_queue(), ^{ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wreceiver-is-weak" [self.activityIndicatorView startAnimating]; #pragma clang diagnostic pop }); } - (void)af_stopAnimating { dispatch_async(dispatch_get_main_queue(), ^{ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wreceiver-is-weak" [self.activityIndicatorView stopAnimating]; #pragma clang diagnostic pop }); } #pragma mark - - (void)dealloc { NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil]; } @end #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/UIButton+AFNetworking.h ================================================ // UIButton+AFNetworking.h // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #if TARGET_OS_IOS || TARGET_OS_TV #import NS_ASSUME_NONNULL_BEGIN @class AFImageDownloader; /** This category adds methods to the UIKit framework's `UIButton` class. The methods in this category provide support for loading remote images and background images asynchronously from a URL. @warning Compound values for control `state` (such as `UIControlStateHighlighted | UIControlStateDisabled`) are unsupported. */ @interface UIButton (AFNetworking) ///------------------------------------ /// @name Accessing the Image Downloader ///------------------------------------ /** Set the shared image downloader used to download images. @param imageDownloader The shared image downloader used to download images. */ + (void)setSharedImageDownloader:(AFImageDownloader *)imageDownloader; /** The shared image downloader used to download images. */ + (AFImageDownloader *)sharedImageDownloader; ///-------------------- /// @name Setting Image ///-------------------- /** Asynchronously downloads an image from the specified URL, and sets it as the image for the specified state once the request is finished. Any previous image request for the receiver will be cancelled. If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. @param state The control state. @param url The URL used for the image request. */ - (void)setImageForState:(UIControlState)state withURL:(NSURL *)url; /** Asynchronously downloads an image from the specified URL, and sets it as the image for the specified state once the request is finished. Any previous image request for the receiver will be cancelled. If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. @param state The control state. @param url The URL used for the image request. @param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the button will not change its image until the image request finishes. */ - (void)setImageForState:(UIControlState)state withURL:(NSURL *)url placeholderImage:(nullable UIImage *)placeholderImage; /** Asynchronously downloads an image from the specified URL request, and sets it as the image for the specified state once the request is finished. Any previous image request for the receiver will be cancelled. If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. If a success block is specified, it is the responsibility of the block to set the image of the button before returning. If no success block is specified, the default behavior of setting the image with `setImage:forState:` is applied. @param state The control state. @param urlRequest The URL request used for the image request. @param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the button will not change its image until the image request finishes. @param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`. @param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred. */ - (void)setImageForState:(UIControlState)state withURLRequest:(NSURLRequest *)urlRequest placeholderImage:(nullable UIImage *)placeholderImage success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure; ///------------------------------- /// @name Setting Background Image ///------------------------------- /** Asynchronously downloads an image from the specified URL, and sets it as the background image for the specified state once the request is finished. Any previous background image request for the receiver will be cancelled. If the background image is cached locally, the background image is set immediately, otherwise the specified placeholder background image will be set immediately, and then the remote background image will be set once the request is finished. @param state The control state. @param url The URL used for the background image request. */ - (void)setBackgroundImageForState:(UIControlState)state withURL:(NSURL *)url; /** Asynchronously downloads an image from the specified URL, and sets it as the background image for the specified state once the request is finished. Any previous image request for the receiver will be cancelled. If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. @param state The control state. @param url The URL used for the background image request. @param placeholderImage The background image to be set initially, until the background image request finishes. If `nil`, the button will not change its background image until the background image request finishes. */ - (void)setBackgroundImageForState:(UIControlState)state withURL:(NSURL *)url placeholderImage:(nullable UIImage *)placeholderImage; /** Asynchronously downloads an image from the specified URL request, and sets it as the image for the specified state once the request is finished. Any previous image request for the receiver will be cancelled. If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. If a success block is specified, it is the responsibility of the block to set the image of the button before returning. If no success block is specified, the default behavior of setting the image with `setBackgroundImage:forState:` is applied. @param state The control state. @param urlRequest The URL request used for the image request. @param placeholderImage The background image to be set initially, until the background image request finishes. If `nil`, the button will not change its background image until the background image request finishes. @param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`. @param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred. */ - (void)setBackgroundImageForState:(UIControlState)state withURLRequest:(NSURLRequest *)urlRequest placeholderImage:(nullable UIImage *)placeholderImage success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure; ///------------------------------ /// @name Canceling Image Loading ///------------------------------ /** Cancels any executing image task for the specified control state of the receiver, if one exists. @param state The control state. */ - (void)cancelImageDownloadTaskForState:(UIControlState)state; /** Cancels any executing background image task for the specified control state of the receiver, if one exists. @param state The control state. */ - (void)cancelBackgroundImageDownloadTaskForState:(UIControlState)state; @end NS_ASSUME_NONNULL_END #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/UIButton+AFNetworking.m ================================================ // UIButton+AFNetworking.m // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "UIButton+AFNetworking.h" #import #if TARGET_OS_IOS || TARGET_OS_TV #import "UIImageView+AFNetworking.h" #import "AFImageDownloader.h" @interface UIButton (_AFNetworking) @end @implementation UIButton (_AFNetworking) #pragma mark - static char AFImageDownloadReceiptNormal; static char AFImageDownloadReceiptHighlighted; static char AFImageDownloadReceiptSelected; static char AFImageDownloadReceiptDisabled; static const char * af_imageDownloadReceiptKeyForState(UIControlState state) { switch (state) { case UIControlStateHighlighted: return &AFImageDownloadReceiptHighlighted; case UIControlStateSelected: return &AFImageDownloadReceiptSelected; case UIControlStateDisabled: return &AFImageDownloadReceiptDisabled; case UIControlStateNormal: default: return &AFImageDownloadReceiptNormal; } } - (AFImageDownloadReceipt *)af_imageDownloadReceiptForState:(UIControlState)state { return (AFImageDownloadReceipt *)objc_getAssociatedObject(self, af_imageDownloadReceiptKeyForState(state)); } - (void)af_setImageDownloadReceipt:(AFImageDownloadReceipt *)imageDownloadReceipt forState:(UIControlState)state { objc_setAssociatedObject(self, af_imageDownloadReceiptKeyForState(state), imageDownloadReceipt, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } #pragma mark - static char AFBackgroundImageDownloadReceiptNormal; static char AFBackgroundImageDownloadReceiptHighlighted; static char AFBackgroundImageDownloadReceiptSelected; static char AFBackgroundImageDownloadReceiptDisabled; static const char * af_backgroundImageDownloadReceiptKeyForState(UIControlState state) { switch (state) { case UIControlStateHighlighted: return &AFBackgroundImageDownloadReceiptHighlighted; case UIControlStateSelected: return &AFBackgroundImageDownloadReceiptSelected; case UIControlStateDisabled: return &AFBackgroundImageDownloadReceiptDisabled; case UIControlStateNormal: default: return &AFBackgroundImageDownloadReceiptNormal; } } - (AFImageDownloadReceipt *)af_backgroundImageDownloadReceiptForState:(UIControlState)state { return (AFImageDownloadReceipt *)objc_getAssociatedObject(self, af_backgroundImageDownloadReceiptKeyForState(state)); } - (void)af_setBackgroundImageDownloadReceipt:(AFImageDownloadReceipt *)imageDownloadReceipt forState:(UIControlState)state { objc_setAssociatedObject(self, af_backgroundImageDownloadReceiptKeyForState(state), imageDownloadReceipt, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end #pragma mark - @implementation UIButton (AFNetworking) + (AFImageDownloader *)sharedImageDownloader { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" return objc_getAssociatedObject(self, @selector(sharedImageDownloader)) ?: [AFImageDownloader defaultInstance]; #pragma clang diagnostic pop } + (void)setSharedImageDownloader:(AFImageDownloader *)imageDownloader { objc_setAssociatedObject(self, @selector(sharedImageDownloader), imageDownloader, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } #pragma mark - - (void)setImageForState:(UIControlState)state withURL:(NSURL *)url { [self setImageForState:state withURL:url placeholderImage:nil]; } - (void)setImageForState:(UIControlState)state withURL:(NSURL *)url placeholderImage:(UIImage *)placeholderImage { NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request addValue:@"image/*" forHTTPHeaderField:@"Accept"]; [self setImageForState:state withURLRequest:request placeholderImage:placeholderImage success:nil failure:nil]; } - (void)setImageForState:(UIControlState)state withURLRequest:(NSURLRequest *)urlRequest placeholderImage:(nullable UIImage *)placeholderImage success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure { if ([self isActiveTaskURLEqualToURLRequest:urlRequest forState:state]) { return; } [self cancelImageDownloadTaskForState:state]; AFImageDownloader *downloader = [[self class] sharedImageDownloader]; id imageCache = downloader.imageCache; //Use the image from the image cache if it exists UIImage *cachedImage = [imageCache imageforRequest:urlRequest withAdditionalIdentifier:nil]; if (cachedImage) { if (success) { success(urlRequest, nil, cachedImage); } else { [self setImage:cachedImage forState:state]; } [self af_setImageDownloadReceipt:nil forState:state]; } else { if (placeholderImage) { [self setImage:placeholderImage forState:state]; } __weak __typeof(self)weakSelf = self; NSUUID *downloadID = [NSUUID UUID]; AFImageDownloadReceipt *receipt; receipt = [downloader downloadImageForURLRequest:urlRequest withReceiptID:downloadID success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull responseObject) { __strong __typeof(weakSelf)strongSelf = weakSelf; if ([[strongSelf af_imageDownloadReceiptForState:state].receiptID isEqual:downloadID]) { if (success) { success(request, response, responseObject); } else if(responseObject) { [strongSelf setImage:responseObject forState:state]; } [strongSelf af_setImageDownloadReceipt:nil forState:state]; } } failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) { __strong __typeof(weakSelf)strongSelf = weakSelf; if ([[strongSelf af_imageDownloadReceiptForState:state].receiptID isEqual:downloadID]) { if (failure) { failure(request, response, error); } [strongSelf af_setImageDownloadReceipt:nil forState:state]; } }]; [self af_setImageDownloadReceipt:receipt forState:state]; } } #pragma mark - - (void)setBackgroundImageForState:(UIControlState)state withURL:(NSURL *)url { [self setBackgroundImageForState:state withURL:url placeholderImage:nil]; } - (void)setBackgroundImageForState:(UIControlState)state withURL:(NSURL *)url placeholderImage:(nullable UIImage *)placeholderImage { NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request addValue:@"image/*" forHTTPHeaderField:@"Accept"]; [self setBackgroundImageForState:state withURLRequest:request placeholderImage:placeholderImage success:nil failure:nil]; } - (void)setBackgroundImageForState:(UIControlState)state withURLRequest:(NSURLRequest *)urlRequest placeholderImage:(nullable UIImage *)placeholderImage success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure { if ([self isActiveBackgroundTaskURLEqualToURLRequest:urlRequest forState:state]) { return; } [self cancelBackgroundImageDownloadTaskForState:state]; AFImageDownloader *downloader = [[self class] sharedImageDownloader]; id imageCache = downloader.imageCache; //Use the image from the image cache if it exists UIImage *cachedImage = [imageCache imageforRequest:urlRequest withAdditionalIdentifier:nil]; if (cachedImage) { if (success) { success(urlRequest, nil, cachedImage); } else { [self setBackgroundImage:cachedImage forState:state]; } [self af_setBackgroundImageDownloadReceipt:nil forState:state]; } else { if (placeholderImage) { [self setBackgroundImage:placeholderImage forState:state]; } __weak __typeof(self)weakSelf = self; NSUUID *downloadID = [NSUUID UUID]; AFImageDownloadReceipt *receipt; receipt = [downloader downloadImageForURLRequest:urlRequest withReceiptID:downloadID success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull responseObject) { __strong __typeof(weakSelf)strongSelf = weakSelf; if ([[strongSelf af_backgroundImageDownloadReceiptForState:state].receiptID isEqual:downloadID]) { if (success) { success(request, response, responseObject); } else if(responseObject) { [strongSelf setBackgroundImage:responseObject forState:state]; } [strongSelf af_setBackgroundImageDownloadReceipt:nil forState:state]; } } failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) { __strong __typeof(weakSelf)strongSelf = weakSelf; if ([[strongSelf af_backgroundImageDownloadReceiptForState:state].receiptID isEqual:downloadID]) { if (failure) { failure(request, response, error); } [strongSelf af_setBackgroundImageDownloadReceipt:nil forState:state]; } }]; [self af_setBackgroundImageDownloadReceipt:receipt forState:state]; } } #pragma mark - - (void)cancelImageDownloadTaskForState:(UIControlState)state { AFImageDownloadReceipt *receipt = [self af_imageDownloadReceiptForState:state]; if (receipt != nil) { [[self.class sharedImageDownloader] cancelTaskForImageDownloadReceipt:receipt]; [self af_setImageDownloadReceipt:nil forState:state]; } } - (void)cancelBackgroundImageDownloadTaskForState:(UIControlState)state { AFImageDownloadReceipt *receipt = [self af_backgroundImageDownloadReceiptForState:state]; if (receipt != nil) { [[self.class sharedImageDownloader] cancelTaskForImageDownloadReceipt:receipt]; [self af_setBackgroundImageDownloadReceipt:nil forState:state]; } } - (BOOL)isActiveTaskURLEqualToURLRequest:(NSURLRequest *)urlRequest forState:(UIControlState)state { AFImageDownloadReceipt *receipt = [self af_imageDownloadReceiptForState:state]; return [receipt.task.originalRequest.URL.absoluteString isEqualToString:urlRequest.URL.absoluteString]; } - (BOOL)isActiveBackgroundTaskURLEqualToURLRequest:(NSURLRequest *)urlRequest forState:(UIControlState)state { AFImageDownloadReceipt *receipt = [self af_backgroundImageDownloadReceiptForState:state]; return [receipt.task.originalRequest.URL.absoluteString isEqualToString:urlRequest.URL.absoluteString]; } @end #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/UIImage+AFNetworking.h ================================================ // // UIImage+AFNetworking.h // // // Created by Paulo Ferreira on 08/07/15. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if TARGET_OS_IOS || TARGET_OS_TV #import @interface UIImage (AFNetworking) + (UIImage*) safeImageWithData:(NSData*)data; @end #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.h ================================================ // UIImageView+AFNetworking.h // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #if TARGET_OS_IOS || TARGET_OS_TV #import NS_ASSUME_NONNULL_BEGIN @class AFImageDownloader; /** This category adds methods to the UIKit framework's `UIImageView` class. The methods in this category provide support for loading remote images asynchronously from a URL. */ @interface UIImageView (AFNetworking) ///------------------------------------ /// @name Accessing the Image Downloader ///------------------------------------ /** Set the shared image downloader used to download images. @param imageDownloader The shared image downloader used to download images. */ + (void)setSharedImageDownloader:(AFImageDownloader *)imageDownloader; /** The shared image downloader used to download images. */ + (AFImageDownloader *)sharedImageDownloader; ///-------------------- /// @name Setting Image ///-------------------- /** Asynchronously downloads an image from the specified URL, and sets it once the request is finished. Any previous image request for the receiver will be cancelled. If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. By default, URL requests have a `Accept` header field value of "image / *", a cache policy of `NSURLCacheStorageAllowed` and a timeout interval of 30 seconds, and are set not handle cookies. To configure URL requests differently, use `setImageWithURLRequest:placeholderImage:success:failure:` @param url The URL used for the image request. */ - (void)setImageWithURL:(NSURL *)url; /** Asynchronously downloads an image from the specified URL, and sets it once the request is finished. Any previous image request for the receiver will be cancelled. If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. By default, URL requests have a `Accept` header field value of "image / *", a cache policy of `NSURLCacheStorageAllowed` and a timeout interval of 30 seconds, and are set not handle cookies. To configure URL requests differently, use `setImageWithURLRequest:placeholderImage:success:failure:` @param url The URL used for the image request. @param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the image view will not change its image until the image request finishes. */ - (void)setImageWithURL:(NSURL *)url placeholderImage:(nullable UIImage *)placeholderImage; /** Asynchronously downloads an image from the specified URL request, and sets it once the request is finished. Any previous image request for the receiver will be cancelled. If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. If a success block is specified, it is the responsibility of the block to set the image of the image view before returning. If no success block is specified, the default behavior of setting the image with `self.image = image` is applied. @param urlRequest The URL request used for the image request. @param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the image view will not change its image until the image request finishes. @param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`. @param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred. */ - (void)setImageWithURLRequest:(NSURLRequest *)urlRequest placeholderImage:(nullable UIImage *)placeholderImage success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure; /** Cancels any executing image operation for the receiver, if one exists. */ - (void)cancelImageDownloadTask; @end NS_ASSUME_NONNULL_END #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.m ================================================ // UIImageView+AFNetworking.m // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "UIImageView+AFNetworking.h" #import #if TARGET_OS_IOS || TARGET_OS_TV #import "AFImageDownloader.h" @interface UIImageView (_AFNetworking) @property (readwrite, nonatomic, strong, setter = af_setActiveImageDownloadReceipt:) AFImageDownloadReceipt *af_activeImageDownloadReceipt; @end @implementation UIImageView (_AFNetworking) - (AFImageDownloadReceipt *)af_activeImageDownloadReceipt { return (AFImageDownloadReceipt *)objc_getAssociatedObject(self, @selector(af_activeImageDownloadReceipt)); } - (void)af_setActiveImageDownloadReceipt:(AFImageDownloadReceipt *)imageDownloadReceipt { objc_setAssociatedObject(self, @selector(af_activeImageDownloadReceipt), imageDownloadReceipt, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end #pragma mark - @implementation UIImageView (AFNetworking) + (AFImageDownloader *)sharedImageDownloader { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" return objc_getAssociatedObject(self, @selector(sharedImageDownloader)) ?: [AFImageDownloader defaultInstance]; #pragma clang diagnostic pop } + (void)setSharedImageDownloader:(AFImageDownloader *)imageDownloader { objc_setAssociatedObject(self, @selector(sharedImageDownloader), imageDownloader, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } #pragma mark - - (void)setImageWithURL:(NSURL *)url { [self setImageWithURL:url placeholderImage:nil]; } - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholderImage { NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request addValue:@"image/*" forHTTPHeaderField:@"Accept"]; [self setImageWithURLRequest:request placeholderImage:placeholderImage success:nil failure:nil]; } - (void)setImageWithURLRequest:(NSURLRequest *)urlRequest placeholderImage:(UIImage *)placeholderImage success:(void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure { if ([urlRequest URL] == nil) { [self cancelImageDownloadTask]; self.image = placeholderImage; return; } if ([self isActiveTaskURLEqualToURLRequest:urlRequest]){ return; } [self cancelImageDownloadTask]; AFImageDownloader *downloader = [[self class] sharedImageDownloader]; id imageCache = downloader.imageCache; //Use the image from the image cache if it exists UIImage *cachedImage = [imageCache imageforRequest:urlRequest withAdditionalIdentifier:nil]; if (cachedImage) { if (success) { success(urlRequest, nil, cachedImage); } else { self.image = cachedImage; } [self clearActiveDownloadInformation]; } else { if (placeholderImage) { self.image = placeholderImage; } __weak __typeof(self)weakSelf = self; NSUUID *downloadID = [NSUUID UUID]; AFImageDownloadReceipt *receipt; receipt = [downloader downloadImageForURLRequest:urlRequest withReceiptID:downloadID success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull responseObject) { __strong __typeof(weakSelf)strongSelf = weakSelf; if ([strongSelf.af_activeImageDownloadReceipt.receiptID isEqual:downloadID]) { if (success) { success(request, response, responseObject); } else if(responseObject) { strongSelf.image = responseObject; } [strongSelf clearActiveDownloadInformation]; } } failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) { __strong __typeof(weakSelf)strongSelf = weakSelf; if ([strongSelf.af_activeImageDownloadReceipt.receiptID isEqual:downloadID]) { if (failure) { failure(request, response, error); } [strongSelf clearActiveDownloadInformation]; } }]; self.af_activeImageDownloadReceipt = receipt; } } - (void)cancelImageDownloadTask { if (self.af_activeImageDownloadReceipt != nil) { [[self.class sharedImageDownloader] cancelTaskForImageDownloadReceipt:self.af_activeImageDownloadReceipt]; [self clearActiveDownloadInformation]; } } - (void)clearActiveDownloadInformation { self.af_activeImageDownloadReceipt = nil; } - (BOOL)isActiveTaskURLEqualToURLRequest:(NSURLRequest *)urlRequest { return [self.af_activeImageDownloadReceipt.task.originalRequest.URL.absoluteString isEqualToString:urlRequest.URL.absoluteString]; } @end #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/UIKit+AFNetworking.h ================================================ // UIKit+AFNetworking.h // // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #if TARGET_OS_IOS || TARGET_OS_TV #import #ifndef _UIKIT_AFNETWORKING_ #define _UIKIT_AFNETWORKING_ #if TARGET_OS_IOS #import "AFAutoPurgingImageCache.h" #import "AFImageDownloader.h" #import "AFNetworkActivityIndicatorManager.h" #import "UIRefreshControl+AFNetworking.h" #import "UIWebView+AFNetworking.h" #endif #import "UIActivityIndicatorView+AFNetworking.h" #import "UIButton+AFNetworking.h" #import "UIImageView+AFNetworking.h" #import "UIProgressView+AFNetworking.h" #endif /* _UIKIT_AFNETWORKING_ */ #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/UIProgressView+AFNetworking.h ================================================ // UIProgressView+AFNetworking.h // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #if TARGET_OS_IOS || TARGET_OS_TV #import NS_ASSUME_NONNULL_BEGIN /** This category adds methods to the UIKit framework's `UIProgressView` class. The methods in this category provide support for binding the progress to the upload and download progress of a session task. */ @interface UIProgressView (AFNetworking) ///------------------------------------ /// @name Setting Session Task Progress ///------------------------------------ /** Binds the progress to the upload progress of the specified session task. @param task The session task. @param animated `YES` if the change should be animated, `NO` if the change should happen immediately. */ - (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task animated:(BOOL)animated; /** Binds the progress to the download progress of the specified session task. @param task The session task. @param animated `YES` if the change should be animated, `NO` if the change should happen immediately. */ - (void)setProgressWithDownloadProgressOfTask:(NSURLSessionDownloadTask *)task animated:(BOOL)animated; @end NS_ASSUME_NONNULL_END #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/UIProgressView+AFNetworking.m ================================================ // UIProgressView+AFNetworking.m // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "UIProgressView+AFNetworking.h" #import #if TARGET_OS_IOS || TARGET_OS_TV #import "AFURLSessionManager.h" static void * AFTaskCountOfBytesSentContext = &AFTaskCountOfBytesSentContext; static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedContext; #pragma mark - @implementation UIProgressView (AFNetworking) - (BOOL)af_uploadProgressAnimated { return [(NSNumber *)objc_getAssociatedObject(self, @selector(af_uploadProgressAnimated)) boolValue]; } - (void)af_setUploadProgressAnimated:(BOOL)animated { objc_setAssociatedObject(self, @selector(af_uploadProgressAnimated), @(animated), OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (BOOL)af_downloadProgressAnimated { return [(NSNumber *)objc_getAssociatedObject(self, @selector(af_downloadProgressAnimated)) boolValue]; } - (void)af_setDownloadProgressAnimated:(BOOL)animated { objc_setAssociatedObject(self, @selector(af_downloadProgressAnimated), @(animated), OBJC_ASSOCIATION_RETAIN_NONATOMIC); } #pragma mark - - (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task animated:(BOOL)animated { [task addObserver:self forKeyPath:@"state" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesSentContext]; [task addObserver:self forKeyPath:@"countOfBytesSent" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesSentContext]; [self af_setUploadProgressAnimated:animated]; } - (void)setProgressWithDownloadProgressOfTask:(NSURLSessionDownloadTask *)task animated:(BOOL)animated { [task addObserver:self forKeyPath:@"state" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesReceivedContext]; [task addObserver:self forKeyPath:@"countOfBytesReceived" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesReceivedContext]; [self af_setDownloadProgressAnimated:animated]; } #pragma mark - NSKeyValueObserving - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(__unused NSDictionary *)change context:(void *)context { if (context == AFTaskCountOfBytesSentContext || context == AFTaskCountOfBytesReceivedContext) { if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesSent))]) { if ([object countOfBytesExpectedToSend] > 0) { dispatch_async(dispatch_get_main_queue(), ^{ [self setProgress:[object countOfBytesSent] / ([object countOfBytesExpectedToSend] * 1.0f) animated:self.af_uploadProgressAnimated]; }); } } if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesReceived))]) { if ([object countOfBytesExpectedToReceive] > 0) { dispatch_async(dispatch_get_main_queue(), ^{ [self setProgress:[object countOfBytesReceived] / ([object countOfBytesExpectedToReceive] * 1.0f) animated:self.af_downloadProgressAnimated]; }); } } if ([keyPath isEqualToString:NSStringFromSelector(@selector(state))]) { if ([(NSURLSessionTask *)object state] == NSURLSessionTaskStateCompleted) { @try { [object removeObserver:self forKeyPath:NSStringFromSelector(@selector(state))]; if (context == AFTaskCountOfBytesSentContext) { [object removeObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesSent))]; } if (context == AFTaskCountOfBytesReceivedContext) { [object removeObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesReceived))]; } } @catch (NSException * __unused exception) {} } } } } @end #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/UIRefreshControl+AFNetworking.h ================================================ // UIRefreshControl+AFNetworking.m // // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #if TARGET_OS_IOS #import NS_ASSUME_NONNULL_BEGIN /** This category adds methods to the UIKit framework's `UIRefreshControl` class. The methods in this category provide support for automatically beginning and ending refreshing depending on the loading state of a session task. */ @interface UIRefreshControl (AFNetworking) ///----------------------------------- /// @name Refreshing for Session Tasks ///----------------------------------- /** Binds the refreshing state to the state of the specified task. @param task The task. If `nil`, automatic updating from any previously specified operation will be disabled. */ - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task; @end NS_ASSUME_NONNULL_END #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/UIRefreshControl+AFNetworking.m ================================================ // UIRefreshControl+AFNetworking.m // // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "UIRefreshControl+AFNetworking.h" #import #if TARGET_OS_IOS #import "AFURLSessionManager.h" @interface AFRefreshControlNotificationObserver : NSObject @property (readonly, nonatomic, weak) UIRefreshControl *refreshControl; - (instancetype)initWithActivityRefreshControl:(UIRefreshControl *)refreshControl; - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task; @end @implementation UIRefreshControl (AFNetworking) - (AFRefreshControlNotificationObserver *)af_notificationObserver { AFRefreshControlNotificationObserver *notificationObserver = objc_getAssociatedObject(self, @selector(af_notificationObserver)); if (notificationObserver == nil) { notificationObserver = [[AFRefreshControlNotificationObserver alloc] initWithActivityRefreshControl:self]; objc_setAssociatedObject(self, @selector(af_notificationObserver), notificationObserver, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } return notificationObserver; } - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task { [[self af_notificationObserver] setRefreshingWithStateOfTask:task]; } @end @implementation AFRefreshControlNotificationObserver - (instancetype)initWithActivityRefreshControl:(UIRefreshControl *)refreshControl { self = [super init]; if (self) { _refreshControl = refreshControl; } return self; } - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task { NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil]; if (task) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wreceiver-is-weak" #pragma clang diagnostic ignored "-Warc-repeated-use-of-weak" if (task.state == NSURLSessionTaskStateRunning) { [self.refreshControl beginRefreshing]; [notificationCenter addObserver:self selector:@selector(af_beginRefreshing) name:AFNetworkingTaskDidResumeNotification object:task]; [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidCompleteNotification object:task]; [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidSuspendNotification object:task]; } else { [self.refreshControl endRefreshing]; } #pragma clang diagnostic pop } } #pragma mark - - (void)af_beginRefreshing { dispatch_async(dispatch_get_main_queue(), ^{ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wreceiver-is-weak" [self.refreshControl beginRefreshing]; #pragma clang diagnostic pop }); } - (void)af_endRefreshing { dispatch_async(dispatch_get_main_queue(), ^{ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wreceiver-is-weak" [self.refreshControl endRefreshing]; #pragma clang diagnostic pop }); } #pragma mark - - (void)dealloc { NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil]; [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil]; } @end #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.h ================================================ // UIWebView+AFNetworking.h // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #if TARGET_OS_IOS #import NS_ASSUME_NONNULL_BEGIN @class AFHTTPSessionManager; /** This category adds methods to the UIKit framework's `UIWebView` class. The methods in this category provide increased control over the request cycle, including progress monitoring and success / failure handling. @discussion When using these category methods, make sure to assign `delegate` for the web view, which implements `–webView:shouldStartLoadWithRequest:navigationType:` appropriately. This allows for tapped links to be loaded through AFNetworking, and can ensure that `canGoBack` & `canGoForward` update their values correctly. */ @interface UIWebView (AFNetworking) /** The session manager used to download all requests. */ @property (nonatomic, strong) AFHTTPSessionManager *sessionManager; /** Asynchronously loads the specified request. @param request A URL request identifying the location of the content to load. This must not be `nil`. @param progress A progress object monitoring the current download progress. @param success A block object to be executed when the request finishes loading successfully. This block returns the HTML string to be loaded by the web view, and takes two arguments: the response, and the response string. @param failure A block object to be executed when the data task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred. */ - (void)loadRequest:(NSURLRequest *)request progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress success:(nullable NSString * (^)(NSHTTPURLResponse *response, NSString *HTML))success failure:(nullable void (^)(NSError *error))failure; /** Asynchronously loads the data associated with a particular request with a specified MIME type and text encoding. @param request A URL request identifying the location of the content to load. This must not be `nil`. @param MIMEType The MIME type of the content. Defaults to the content type of the response if not specified. @param textEncodingName The IANA encoding name, as in `utf-8` or `utf-16`. Defaults to the response text encoding if not specified. @param progress A progress object monitoring the current download progress. @param success A block object to be executed when the request finishes loading successfully. This block returns the data to be loaded by the web view and takes two arguments: the response, and the downloaded data. @param failure A block object to be executed when the data task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred. */ - (void)loadRequest:(NSURLRequest *)request MIMEType:(nullable NSString *)MIMEType textEncodingName:(nullable NSString *)textEncodingName progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress success:(nullable NSData * (^)(NSHTTPURLResponse *response, NSData *data))success failure:(nullable void (^)(NSError *error))failure; @end NS_ASSUME_NONNULL_END #endif ================================================ FILE: Pods/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.m ================================================ // UIWebView+AFNetworking.m // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "UIWebView+AFNetworking.h" #import #if TARGET_OS_IOS #import "AFHTTPSessionManager.h" #import "AFURLResponseSerialization.h" #import "AFURLRequestSerialization.h" @interface UIWebView (_AFNetworking) @property (readwrite, nonatomic, strong, setter = af_setURLSessionTask:) NSURLSessionDataTask *af_URLSessionTask; @end @implementation UIWebView (_AFNetworking) - (NSURLSessionDataTask *)af_URLSessionTask { return (NSURLSessionDataTask *)objc_getAssociatedObject(self, @selector(af_URLSessionTask)); } - (void)af_setURLSessionTask:(NSURLSessionDataTask *)af_URLSessionTask { objc_setAssociatedObject(self, @selector(af_URLSessionTask), af_URLSessionTask, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end #pragma mark - @implementation UIWebView (AFNetworking) - (AFHTTPSessionManager *)sessionManager { static AFHTTPSessionManager *_af_defaultHTTPSessionManager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _af_defaultHTTPSessionManager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; _af_defaultHTTPSessionManager.requestSerializer = [AFHTTPRequestSerializer serializer]; _af_defaultHTTPSessionManager.responseSerializer = [AFHTTPResponseSerializer serializer]; }); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" return objc_getAssociatedObject(self, @selector(sessionManager)) ?: _af_defaultHTTPSessionManager; #pragma clang diagnostic pop } - (void)setSessionManager:(AFHTTPSessionManager *)sessionManager { objc_setAssociatedObject(self, @selector(sessionManager), sessionManager, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (AFHTTPResponseSerializer *)responseSerializer { static AFHTTPResponseSerializer *_af_defaultResponseSerializer = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _af_defaultResponseSerializer = [AFHTTPResponseSerializer serializer]; }); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wgnu" return objc_getAssociatedObject(self, @selector(responseSerializer)) ?: _af_defaultResponseSerializer; #pragma clang diagnostic pop } - (void)setResponseSerializer:(AFHTTPResponseSerializer *)responseSerializer { objc_setAssociatedObject(self, @selector(responseSerializer), responseSerializer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } #pragma mark - - (void)loadRequest:(NSURLRequest *)request progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress success:(NSString * (^)(NSHTTPURLResponse *response, NSString *HTML))success failure:(void (^)(NSError *error))failure { [self loadRequest:request MIMEType:nil textEncodingName:nil progress:progress success:^NSData *(NSHTTPURLResponse *response, NSData *data) { NSStringEncoding stringEncoding = NSUTF8StringEncoding; if (response.textEncodingName) { CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)response.textEncodingName); if (encoding != kCFStringEncodingInvalidId) { stringEncoding = CFStringConvertEncodingToNSStringEncoding(encoding); } } NSString *string = [[NSString alloc] initWithData:data encoding:stringEncoding]; if (success) { string = success(response, string); } return [string dataUsingEncoding:stringEncoding]; } failure:failure]; } - (void)loadRequest:(NSURLRequest *)request MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)textEncodingName progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress success:(NSData * (^)(NSHTTPURLResponse *response, NSData *data))success failure:(void (^)(NSError *error))failure { NSParameterAssert(request); if (self.af_URLSessionTask.state == NSURLSessionTaskStateRunning || self.af_URLSessionTask.state == NSURLSessionTaskStateSuspended) { [self.af_URLSessionTask cancel]; } self.af_URLSessionTask = nil; __weak __typeof(self)weakSelf = self; NSURLSessionDataTask *dataTask; dataTask = [self.sessionManager GET:request.URL.absoluteString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) { __strong __typeof(weakSelf) strongSelf = weakSelf; if (success) { success((NSHTTPURLResponse *)task.response, responseObject); } [strongSelf loadData:responseObject MIMEType:MIMEType textEncodingName:textEncodingName baseURL:[task.currentRequest URL]]; if ([strongSelf.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) { [strongSelf.delegate webViewDidFinishLoad:strongSelf]; } } failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) { if (failure) { failure(error); } }]; self.af_URLSessionTask = dataTask; if (progress != nil) { *progress = [self.sessionManager downloadProgressForTask:dataTask]; } [self.af_URLSessionTask resume]; if ([self.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) { [self.delegate webViewDidStartLoad:self]; } } @end #endif ================================================ FILE: Pods/Bolts/Bolts/Common/BFCancellationToken.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import #import NS_ASSUME_NONNULL_BEGIN /*! A block that will be called when a token is cancelled. */ typedef void(^BFCancellationBlock)(); /*! The consumer view of a CancellationToken. Propagates notification that operations should be canceled. A BFCancellationToken has methods to inspect whether the token has been cancelled. */ @interface BFCancellationToken : NSObject /*! Whether cancellation has been requested for this token source. */ @property (nonatomic, assign, readonly, getter=isCancellationRequested) BOOL cancellationRequested; /*! Register a block to be notified when the token is cancelled. If the token is already cancelled the delegate will be notified immediately. */ - (BFCancellationTokenRegistration *)registerCancellationObserverWithBlock:(BFCancellationBlock)block; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/Common/BFCancellationToken.m ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "BFCancellationToken.h" #import "BFCancellationTokenRegistration.h" NS_ASSUME_NONNULL_BEGIN @interface BFCancellationToken () @property (nullable, nonatomic, strong) NSMutableArray *registrations; @property (nonatomic, strong) NSObject *lock; @property (nonatomic) BOOL disposed; @end @interface BFCancellationTokenRegistration (BFCancellationToken) + (instancetype)registrationWithToken:(BFCancellationToken *)token delegate:(BFCancellationBlock)delegate; - (void)notifyDelegate; @end @implementation BFCancellationToken @synthesize cancellationRequested = _cancellationRequested; #pragma mark - Initializer - (instancetype)init { self = [super init]; if (!self) return self; _registrations = [NSMutableArray array]; _lock = [NSObject new]; return self; } #pragma mark - Custom Setters/Getters - (BOOL)isCancellationRequested { @synchronized(self.lock) { [self throwIfDisposed]; return _cancellationRequested; } } - (void)cancel { NSArray *registrations; @synchronized(self.lock) { [self throwIfDisposed]; if (_cancellationRequested) { return; } [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(cancelPrivate) object:nil]; _cancellationRequested = YES; registrations = [self.registrations copy]; } [self notifyCancellation:registrations]; } - (void)notifyCancellation:(NSArray *)registrations { for (BFCancellationTokenRegistration *registration in registrations) { [registration notifyDelegate]; } } - (BFCancellationTokenRegistration *)registerCancellationObserverWithBlock:(BFCancellationBlock)block { @synchronized(self.lock) { BFCancellationTokenRegistration *registration = [BFCancellationTokenRegistration registrationWithToken:self delegate:[block copy]]; [self.registrations addObject:registration]; return registration; } } - (void)unregisterRegistration:(BFCancellationTokenRegistration *)registration { @synchronized(self.lock) { [self throwIfDisposed]; [self.registrations removeObject:registration]; } } // Delay on a non-public method to prevent interference with a user calling performSelector or // cancelPreviousPerformRequestsWithTarget on the public method - (void)cancelPrivate { [self cancel]; } - (void)cancelAfterDelay:(int)millis { [self throwIfDisposed]; if (millis < -1) { [NSException raise:NSInvalidArgumentException format:@"Delay must be >= -1"]; } if (millis == 0) { [self cancel]; return; } @synchronized(self.lock) { [self throwIfDisposed]; [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(cancelPrivate) object:nil]; if (self.cancellationRequested) { return; } if (millis != -1) { double delay = (double)millis / 1000; [self performSelector:@selector(cancelPrivate) withObject:nil afterDelay:delay]; } } } - (void)dispose { @synchronized(self.lock) { if (self.disposed) { return; } [self.registrations makeObjectsPerformSelector:@selector(dispose)]; self.registrations = nil; self.disposed = YES; } } - (void)throwIfDisposed { if (self.disposed) { [NSException raise:NSInternalInconsistencyException format:@"Object already disposed"]; } } @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/Common/BFCancellationTokenRegistration.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import NS_ASSUME_NONNULL_BEGIN /*! Represents the registration of a cancellation observer with a cancellation token. Can be used to unregister the observer at a later time. */ @interface BFCancellationTokenRegistration : NSObject /*! Removes the cancellation observer registered with the token and releases all resources associated with this registration. */ - (void)dispose; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/Common/BFCancellationTokenRegistration.m ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "BFCancellationTokenRegistration.h" #import "BFCancellationToken.h" NS_ASSUME_NONNULL_BEGIN @interface BFCancellationTokenRegistration () @property (nonatomic, weak) BFCancellationToken *token; @property (nullable, nonatomic, strong) BFCancellationBlock cancellationObserverBlock; @property (nonatomic, strong) NSObject *lock; @property (nonatomic) BOOL disposed; @end @interface BFCancellationToken (BFCancellationTokenRegistration) - (void)unregisterRegistration:(BFCancellationTokenRegistration *)registration; @end @implementation BFCancellationTokenRegistration + (instancetype)registrationWithToken:(BFCancellationToken *)token delegate:(BFCancellationBlock)delegate { BFCancellationTokenRegistration *registration = [BFCancellationTokenRegistration new]; registration.token = token; registration.cancellationObserverBlock = delegate; return registration; } - (instancetype)init { self = [super init]; if (!self) return self; _lock = [NSObject new]; return self; } - (void)dispose { @synchronized(self.lock) { if (self.disposed) { return; } self.disposed = YES; } BFCancellationToken *token = self.token; if (token != nil) { [token unregisterRegistration:self]; self.token = nil; } self.cancellationObserverBlock = nil; } - (void)notifyDelegate { @synchronized(self.lock) { [self throwIfDisposed]; self.cancellationObserverBlock(); } } - (void)throwIfDisposed { NSAssert(!self.disposed, @"Object already disposed"); } @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/Common/BFCancellationTokenSource.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import NS_ASSUME_NONNULL_BEGIN @class BFCancellationToken; /*! BFCancellationTokenSource represents the producer side of a CancellationToken. Signals to a CancellationToken that it should be canceled. It is a cancellation token that also has methods for changing the state of a token by cancelling it. */ @interface BFCancellationTokenSource : NSObject /*! Creates a new cancellation token source. */ + (instancetype)cancellationTokenSource; /*! The cancellation token associated with this CancellationTokenSource. */ @property (nonatomic, strong, readonly) BFCancellationToken *token; /*! Whether cancellation has been requested for this token source. */ @property (nonatomic, assign, readonly, getter=isCancellationRequested) BOOL cancellationRequested; /*! Cancels the token if it has not already been cancelled. */ - (void)cancel; /*! Schedules a cancel operation on this CancellationTokenSource after the specified number of milliseconds. @param millis The number of milliseconds to wait before completing the returned task. If delay is `0` the cancel is executed immediately. If delay is `-1` any scheduled cancellation is stopped. */ - (void)cancelAfterDelay:(int)millis; /*! Releases all resources associated with this token source, including disposing of all registrations. */ - (void)dispose; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/Common/BFCancellationTokenSource.m ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "BFCancellationTokenSource.h" #import "BFCancellationToken.h" NS_ASSUME_NONNULL_BEGIN @interface BFCancellationToken (BFCancellationTokenSource) - (void)cancel; - (void)cancelAfterDelay:(int)millis; - (void)dispose; - (void)throwIfDisposed; @end @implementation BFCancellationTokenSource #pragma mark - Initializer - (instancetype)init { self = [super init]; if (!self) return self; _token = [BFCancellationToken new]; return self; } + (instancetype)cancellationTokenSource { return [BFCancellationTokenSource new]; } #pragma mark - Custom Setters/Getters - (BOOL)isCancellationRequested { return _token.isCancellationRequested; } - (void)cancel { [_token cancel]; } - (void)cancelAfterDelay:(int)millis { [_token cancelAfterDelay:millis]; } - (void)dispose { [_token dispose]; } @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/Common/BFExecutor.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import NS_ASSUME_NONNULL_BEGIN /*! An object that can run a given block. */ @interface BFExecutor : NSObject /*! Returns a default executor, which runs continuations immediately until the call stack gets too deep, then dispatches to a new GCD queue. */ + (instancetype)defaultExecutor; /*! Returns an executor that runs continuations on the thread where the previous task was completed. */ + (instancetype)immediateExecutor; /*! Returns an executor that runs continuations on the main thread. */ + (instancetype)mainThreadExecutor; /*! Returns a new executor that uses the given block to execute continuations. @param block The block to use. */ + (instancetype)executorWithBlock:(void(^)(void(^block)()))block; /*! Returns a new executor that runs continuations on the given queue. @param queue The instance of `dispatch_queue_t` to dispatch all continuations onto. */ + (instancetype)executorWithDispatchQueue:(dispatch_queue_t)queue; /*! Returns a new executor that runs continuations on the given queue. @param queue The instance of `NSOperationQueue` to run all continuations on. */ + (instancetype)executorWithOperationQueue:(NSOperationQueue *)queue; /*! Runs the given block using this executor's particular strategy. @param block The block to execute. */ - (void)execute:(void(^)())block; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/Common/BFExecutor.m ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "BFExecutor.h" #import NS_ASSUME_NONNULL_BEGIN /*! Get the remaining stack-size of the current thread. @param totalSize The total stack size of the current thread. @return The remaining size, in bytes, available to the current thread. @note This function cannot be inlined, as otherwise the internal implementation could fail to report the proper remaining stack space. */ __attribute__((noinline)) static size_t remaining_stack_size(size_t *restrict totalSize) { pthread_t currentThread = pthread_self(); // NOTE: We must store stack pointers as uint8_t so that the pointer math is well-defined uint8_t *endStack = pthread_get_stackaddr_np(currentThread); *totalSize = pthread_get_stacksize_np(currentThread); // NOTE: If the function is inlined, this value could be incorrect uint8_t *frameAddr = __builtin_frame_address(0); return (*totalSize) - (endStack - frameAddr); } @interface BFExecutor () @property (nonatomic, copy) void(^block)(void(^block)()); @end @implementation BFExecutor #pragma mark - Executor methods + (instancetype)defaultExecutor { static BFExecutor *defaultExecutor = NULL; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ defaultExecutor = [self executorWithBlock:^void(void(^block)()) { // We prefer to run everything possible immediately, so that there is callstack information // when debugging. However, we don't want the stack to get too deep, so if the remaining stack space // is less than 10% of the total space, we dispatch to another GCD queue. size_t totalStackSize = 0; size_t remainingStackSize = remaining_stack_size(&totalStackSize); if (remainingStackSize < (totalStackSize / 10)) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block); } else { @autoreleasepool { block(); } } }]; }); return defaultExecutor; } + (instancetype)immediateExecutor { static BFExecutor *immediateExecutor = NULL; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ immediateExecutor = [self executorWithBlock:^void(void(^block)()) { block(); }]; }); return immediateExecutor; } + (instancetype)mainThreadExecutor { static BFExecutor *mainThreadExecutor = NULL; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ mainThreadExecutor = [self executorWithBlock:^void(void(^block)()) { if (![NSThread isMainThread]) { dispatch_async(dispatch_get_main_queue(), block); } else { @autoreleasepool { block(); } } }]; }); return mainThreadExecutor; } + (instancetype)executorWithBlock:(void(^)(void(^block)()))block { return [[self alloc] initWithBlock:block]; } + (instancetype)executorWithDispatchQueue:(dispatch_queue_t)queue { return [self executorWithBlock:^void(void(^block)()) { dispatch_async(queue, block); }]; } + (instancetype)executorWithOperationQueue:(NSOperationQueue *)queue { return [self executorWithBlock:^void(void(^block)()) { [queue addOperation:[NSBlockOperation blockOperationWithBlock:block]]; }]; } #pragma mark - Initializer - (instancetype)initWithBlock:(void(^)(void(^block)()))block { self = [super init]; if (!self) return self; _block = block; return self; } #pragma mark - Execution - (void)execute:(void(^)())block { self.block(block); } @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/Common/BFTask+Exceptions.h ================================================ /* * Copyright (c) 2016, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ #pragma once #import NS_ASSUME_NONNULL_BEGIN /** Returns whether all instances of `BFTask` should automatically @try/@catch exceptions in continuation blocks. Default: `YES`. @return Boolean value indicating whether exceptions are being caught. */ extern BOOL BFTaskCatchesExceptions(void) __attribute__((deprecated("This is temporary API and will be removed in a future release."))); /** Set whether all instances of `BFTask` should automatically @try/@catch exceptions in continuation blocks. Default: `YES`. @param catchExceptions Boolean value indicating whether exceptions shoudl be caught. */ extern void BFTaskSetCatchesExceptions(BOOL catchExceptions) __attribute__((deprecated("This is a temporary API and will be removed in a future release."))); NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/Common/BFTask+Exceptions.m ================================================ /* * Copyright (c) 2016, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ #import "BFTask+Exceptions.h" NS_ASSUME_NONNULL_BEGIN static BOOL taskCatchExceptions = YES; BOOL BFTaskCatchesExceptions(void) { return taskCatchExceptions; } void BFTaskSetCatchesExceptions(BOOL catchExceptions) { taskCatchExceptions = catchExceptions; } NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/Common/BFTask.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import #import NS_ASSUME_NONNULL_BEGIN /*! Error domain used if there was multiple errors on . */ extern NSString *const BFTaskErrorDomain; /*! An error code used for , if there were multiple errors. */ extern NSInteger const kBFMultipleErrorsError; /*! An exception that is thrown if there was multiple exceptions on . @deprecated `BFTask` exception handling is deprecated and will be removed in a future release. */ extern NSString *const BFTaskMultipleExceptionsException __attribute__((deprecated("`BFTask` exception handling is deprecated and will be removed in a future release."))); /*! An error userInfo key used if there were multiple errors on . Value type is `NSArray *`. */ extern NSString *const BFTaskMultipleErrorsUserInfoKey; /*! An error userInfo key used if there were multiple exceptions on . Value type is `NSArray *`. @deprecated `BFTask` exception handling is deprecated and will be removed in a future release. */ extern NSString *const BFTaskMultipleExceptionsUserInfoKey __attribute__((deprecated("`BFTask` exception handling is deprecated and will be removed in a future release."))); @class BFExecutor; @class BFTask; /*! The consumer view of a Task. A BFTask has methods to inspect the state of the task, and to add continuations to be run once the task is complete. */ @interface BFTask<__covariant ResultType> : NSObject /*! A block that can act as a continuation for a task. */ typedef __nullable id(^BFContinuationBlock)(BFTask *t); /*! Creates a task that is already completed with the given result. @param result The result for the task. */ + (instancetype)taskWithResult:(nullable ResultType)result; /*! Creates a task that is already completed with the given error. @param error The error for the task. */ + (instancetype)taskWithError:(NSError *)error; /*! Creates a task that is already completed with the given exception. @param exception The exception for the task. @deprecated `BFTask` exception handling is deprecated and will be removed in a future release. */ + (instancetype)taskWithException:(NSException *)exception __attribute__((deprecated("`BFTask` exception handling is deprecated and will be removed in a future release."))); /*! Creates a task that is already cancelled. */ + (instancetype)cancelledTask; /*! Returns a task that will be completed (with result == nil) once all of the input tasks have completed. @param tasks An `NSArray` of the tasks to use as an input. */ + (instancetype)taskForCompletionOfAllTasks:(nullable NSArray *)tasks; /*! Returns a task that will be completed once all of the input tasks have completed. If all tasks complete successfully without being faulted or cancelled the result will be an `NSArray` of all task results in the order they were provided. @param tasks An `NSArray` of the tasks to use as an input. */ + (instancetype)taskForCompletionOfAllTasksWithResults:(nullable NSArray *)tasks; /*! Returns a task that will be completed once there is at least one successful task. The first task to successuly complete will set the result, all other tasks results are ignored. @param tasks An `NSArray` of the tasks to use as an input. */ + (instancetype)taskForCompletionOfAnyTask:(nullable NSArray *)tasks; /*! Returns a task that will be completed a certain amount of time in the future. @param millis The approximate number of milliseconds to wait before the task will be finished (with result == nil). */ + (instancetype)taskWithDelay:(int)millis; /*! Returns a task that will be completed a certain amount of time in the future. @param millis The approximate number of milliseconds to wait before the task will be finished (with result == nil). @param token The cancellation token (optional). */ + (instancetype)taskWithDelay:(int)millis cancellationToken:(nullable BFCancellationToken *)token; /*! Returns a task that will be completed after the given block completes with the specified executor. @param executor A BFExecutor responsible for determining how the continuation block will be run. @param block The block to immediately schedule to run with the given executor. @returns A task that will be completed after block has run. If block returns a BFTask, then the task returned from this method will not be completed until that task is completed. */ + (instancetype)taskFromExecutor:(BFExecutor *)executor withBlock:(nullable id (^)())block; // Properties that will be set on the task once it is completed. /*! The result of a successful task. */ @property (nullable, nonatomic, strong, readonly) ResultType result; /*! The error of a failed task. */ @property (nullable, nonatomic, strong, readonly) NSError *error; /*! The exception of a failed task. @deprecated `BFTask` exception handling is deprecated and will be removed in a future release. */ @property (nullable, nonatomic, strong, readonly) NSException *exception __attribute__((deprecated("`BFTask` exception handling is deprecated and will be removed in a future release."))); /*! Whether this task has been cancelled. */ @property (nonatomic, assign, readonly, getter=isCancelled) BOOL cancelled; /*! Whether this task has completed due to an error or exception. */ @property (nonatomic, assign, readonly, getter=isFaulted) BOOL faulted; /*! Whether this task has completed. */ @property (nonatomic, assign, readonly, getter=isCompleted) BOOL completed; /*! Enqueues the given block to be run once this task is complete. This method uses a default execution strategy. The block will be run on the thread where the previous task completes, unless the the stack depth is too deep, in which case it will be run on a dispatch queue with default priority. @param block The block to be run once this task is complete. @returns A task that will be completed after block has run. If block returns a BFTask, then the task returned from this method will not be completed until that task is completed. */ - (BFTask *)continueWithBlock:(BFContinuationBlock)block; /*! Enqueues the given block to be run once this task is complete. This method uses a default execution strategy. The block will be run on the thread where the previous task completes, unless the the stack depth is too deep, in which case it will be run on a dispatch queue with default priority. @param block The block to be run once this task is complete. @param cancellationToken The cancellation token (optional). @returns A task that will be completed after block has run. If block returns a BFTask, then the task returned from this method will not be completed until that task is completed. */ - (BFTask *)continueWithBlock:(BFContinuationBlock)block cancellationToken:(nullable BFCancellationToken *)cancellationToken; /*! Enqueues the given block to be run once this task is complete. @param executor A BFExecutor responsible for determining how the continuation block will be run. @param block The block to be run once this task is complete. @returns A task that will be completed after block has run. If block returns a BFTask, then the task returned from this method will not be completed until that task is completed. */ - (BFTask *)continueWithExecutor:(BFExecutor *)executor withBlock:(BFContinuationBlock)block; /*! Enqueues the given block to be run once this task is complete. @param executor A BFExecutor responsible for determining how the continuation block will be run. @param block The block to be run once this task is complete. @param cancellationToken The cancellation token (optional). @returns A task that will be completed after block has run. If block returns a BFTask, then the task returned from his method will not be completed until that task is completed. */ - (BFTask *)continueWithExecutor:(BFExecutor *)executor block:(BFContinuationBlock)block cancellationToken:(nullable BFCancellationToken *)cancellationToken; /*! Identical to continueWithBlock:, except that the block is only run if this task did not produce a cancellation, error, or exception. If it did, then the failure will be propagated to the returned task. @param block The block to be run once this task is complete. @returns A task that will be completed after block has run. If block returns a BFTask, then the task returned from this method will not be completed until that task is completed. */ - (BFTask *)continueWithSuccessBlock:(BFContinuationBlock)block; /*! Identical to continueWithBlock:, except that the block is only run if this task did not produce a cancellation, error, or exception. If it did, then the failure will be propagated to the returned task. @param block The block to be run once this task is complete. @param cancellationToken The cancellation token (optional). @returns A task that will be completed after block has run. If block returns a BFTask, then the task returned from this method will not be completed until that task is completed. */ - (BFTask *)continueWithSuccessBlock:(BFContinuationBlock)block cancellationToken:(nullable BFCancellationToken *)cancellationToken; /*! Identical to continueWithExecutor:withBlock:, except that the block is only run if this task did not produce a cancellation, error, or exception. If it did, then the failure will be propagated to the returned task. @param executor A BFExecutor responsible for determining how the continuation block will be run. @param block The block to be run once this task is complete. @returns A task that will be completed after block has run. If block returns a BFTask, then the task returned from this method will not be completed until that task is completed. */ - (BFTask *)continueWithExecutor:(BFExecutor *)executor withSuccessBlock:(BFContinuationBlock)block; /*! Identical to continueWithExecutor:withBlock:, except that the block is only run if this task did not produce a cancellation, error, or exception. If it did, then the failure will be propagated to the returned task. @param executor A BFExecutor responsible for determining how the continuation block will be run. @param block The block to be run once this task is complete. @param cancellationToken The cancellation token (optional). @returns A task that will be completed after block has run. If block returns a BFTask, then the task returned from this method will not be completed until that task is completed. */ - (BFTask *)continueWithExecutor:(BFExecutor *)executor successBlock:(BFContinuationBlock)block cancellationToken:(nullable BFCancellationToken *)cancellationToken; /*! Waits until this operation is completed. This method is inefficient and consumes a thread resource while it's running. It should be avoided. This method logs a warning message if it is used on the main thread. */ - (void)waitUntilFinished; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/Common/BFTask.m ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "BFTask.h" #import #import "Bolts.h" #import "BFTask+Exceptions.h" NS_ASSUME_NONNULL_BEGIN __attribute__ ((noinline)) void warnBlockingOperationOnMainThread() { NSLog(@"Warning: A long-running operation is being executed on the main thread. \n" " Break on warnBlockingOperationOnMainThread() to debug."); } NSString *const BFTaskErrorDomain = @"bolts"; NSInteger const kBFMultipleErrorsError = 80175001; NSString *const BFTaskMultipleExceptionsException = @"BFMultipleExceptionsException"; NSString *const BFTaskMultipleErrorsUserInfoKey = @"errors"; NSString *const BFTaskMultipleExceptionsUserInfoKey = @"exceptions"; @interface BFTask () { id _result; NSError *_error; NSException *_exception; } @property (nonatomic, assign, readwrite, getter=isCancelled) BOOL cancelled; @property (nonatomic, assign, readwrite, getter=isFaulted) BOOL faulted; @property (nonatomic, assign, readwrite, getter=isCompleted) BOOL completed; @property (nonatomic, strong) NSObject *lock; @property (nonatomic, strong) NSCondition *condition; @property (nonatomic, strong) NSMutableArray *callbacks; @end @implementation BFTask #pragma mark - Initializer - (instancetype)init { self = [super init]; if (!self) return self; _lock = [[NSObject alloc] init]; _condition = [[NSCondition alloc] init]; _callbacks = [NSMutableArray array]; return self; } - (instancetype)initWithResult:(id)result { self = [super init]; if (!self) return self; [self trySetResult:result]; return self; } - (instancetype)initWithError:(NSError *)error { self = [super init]; if (!self) return self; [self trySetError:error]; return self; } - (instancetype)initWithException:(NSException *)exception { self = [super init]; if (!self) return self; [self trySetException:exception]; return self; } - (instancetype)initCancelled { self = [super init]; if (!self) return self; [self trySetCancelled]; return self; } #pragma mark - Task Class methods + (instancetype)taskWithResult:(nullable id)result { return [[self alloc] initWithResult:result]; } + (instancetype)taskWithError:(NSError *)error { return [[self alloc] initWithError:error]; } + (instancetype)taskWithException:(NSException *)exception { return [[self alloc] initWithException:exception]; } + (instancetype)cancelledTask { return [[self alloc] initCancelled]; } + (instancetype)taskForCompletionOfAllTasks:(nullable NSArray *)tasks { __block int32_t total = (int32_t)tasks.count; if (total == 0) { return [self taskWithResult:nil]; } __block int32_t cancelled = 0; NSObject *lock = [[NSObject alloc] init]; NSMutableArray *errors = [NSMutableArray array]; NSMutableArray *exceptions = [NSMutableArray array]; BFTaskCompletionSource *tcs = [BFTaskCompletionSource taskCompletionSource]; for (BFTask *task in tasks) { [task continueWithBlock:^id(BFTask *t) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" if (t.exception) { @synchronized (lock) { [exceptions addObject:t.exception]; #pragma clang diagnostic pop } } else if (t.error) { @synchronized (lock) { [errors addObject:t.error]; } } else if (t.cancelled) { OSAtomicIncrement32Barrier(&cancelled); } if (OSAtomicDecrement32Barrier(&total) == 0) { if (exceptions.count > 0) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" if (exceptions.count == 1) { tcs.exception = [exceptions firstObject]; } else { NSException *exception = [NSException exceptionWithName:BFTaskMultipleExceptionsException reason:@"There were multiple exceptions." userInfo:@{ BFTaskMultipleExceptionsUserInfoKey: exceptions }]; tcs.exception = exception; } #pragma clang diagnostic pop } else if (errors.count > 0) { if (errors.count == 1) { tcs.error = [errors firstObject]; } else { NSError *error = [NSError errorWithDomain:BFTaskErrorDomain code:kBFMultipleErrorsError userInfo:@{ BFTaskMultipleErrorsUserInfoKey: errors }]; tcs.error = error; } } else if (cancelled > 0) { [tcs cancel]; } else { tcs.result = nil; } } return nil; }]; } return tcs.task; } + (instancetype)taskForCompletionOfAllTasksWithResults:(nullable NSArray *)tasks { return [[self taskForCompletionOfAllTasks:tasks] continueWithSuccessBlock:^id(BFTask *task) { return [tasks valueForKey:@"result"]; }]; } + (instancetype)taskForCompletionOfAnyTask:(nullable NSArray *)tasks { __block int32_t total = (int32_t)tasks.count; if (total == 0) { return [self taskWithResult:nil]; } __block int completed = 0; __block int32_t cancelled = 0; NSObject *lock = [NSObject new]; NSMutableArray *errors = [NSMutableArray new]; NSMutableArray *exceptions = [NSMutableArray new]; BFTaskCompletionSource *source = [BFTaskCompletionSource taskCompletionSource]; for (BFTask *task in tasks) { [task continueWithBlock:^id(BFTask *t) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" if (t.exception != nil) { @synchronized(lock) { [exceptions addObject:t.exception]; #pragma clang diagnostic pop } } else if (t.error != nil) { @synchronized(lock) { [errors addObject:t.error]; } } else if (t.cancelled) { OSAtomicIncrement32Barrier(&cancelled); } else { if(OSAtomicCompareAndSwap32Barrier(0, 1, &completed)) { [source setResult:t.result]; } } if (OSAtomicDecrement32Barrier(&total) == 0 && OSAtomicCompareAndSwap32Barrier(0, 1, &completed)) { if (cancelled > 0) { [source cancel]; } else if (exceptions.count > 0) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" if (exceptions.count == 1) { source.exception = exceptions.firstObject; } else { NSException *exception = [NSException exceptionWithName:BFTaskMultipleExceptionsException reason:@"There were multiple exceptions." userInfo:@{ BFTaskMultipleExceptionsUserInfoKey: exceptions }]; source.exception = exception; #pragma clang diagnostic pop } } else if (errors.count > 0) { if (errors.count == 1) { source.error = errors.firstObject; } else { NSError *error = [NSError errorWithDomain:BFTaskErrorDomain code:kBFMultipleErrorsError userInfo:@{ @"errors": errors }]; source.error = error; } } } // Abort execution of per tasks continuations return nil; }]; } return source.task; } + (instancetype)taskWithDelay:(int)millis { BFTaskCompletionSource *tcs = [BFTaskCompletionSource taskCompletionSource]; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, millis * NSEC_PER_MSEC); dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){ tcs.result = nil; }); return tcs.task; } + (instancetype)taskWithDelay:(int)millis cancellationToken:(nullable BFCancellationToken *)token { if (token.cancellationRequested) { return [BFTask cancelledTask]; } BFTaskCompletionSource *tcs = [BFTaskCompletionSource taskCompletionSource]; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, millis * NSEC_PER_MSEC); dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){ if (token.cancellationRequested) { [tcs cancel]; return; } tcs.result = nil; }); return tcs.task; } + (instancetype)taskFromExecutor:(BFExecutor *)executor withBlock:(nullable id (^)())block { return [[self taskWithResult:nil] continueWithExecutor:executor withBlock:^id(BFTask *task) { return block(); }]; } #pragma mark - Custom Setters/Getters - (nullable id)result { @synchronized(self.lock) { return _result; } } - (BOOL)trySetResult:(nullable id)result { @synchronized(self.lock) { if (self.completed) { return NO; } self.completed = YES; _result = result; [self runContinuations]; return YES; } } - (nullable NSError *)error { @synchronized(self.lock) { return _error; } } - (BOOL)trySetError:(NSError *)error { @synchronized(self.lock) { if (self.completed) { return NO; } self.completed = YES; self.faulted = YES; _error = error; [self runContinuations]; return YES; } } - (nullable NSException *)exception { @synchronized(self.lock) { return _exception; } } - (BOOL)trySetException:(NSException *)exception { @synchronized(self.lock) { if (self.completed) { return NO; } self.completed = YES; self.faulted = YES; _exception = exception; [self runContinuations]; return YES; } } - (BOOL)isCancelled { @synchronized(self.lock) { return _cancelled; } } - (BOOL)isFaulted { @synchronized(self.lock) { return _faulted; } } - (BOOL)trySetCancelled { @synchronized(self.lock) { if (self.completed) { return NO; } self.completed = YES; self.cancelled = YES; [self runContinuations]; return YES; } } - (BOOL)isCompleted { @synchronized(self.lock) { return _completed; } } - (void)runContinuations { @synchronized(self.lock) { [self.condition lock]; [self.condition broadcast]; [self.condition unlock]; for (void (^callback)() in self.callbacks) { callback(); } [self.callbacks removeAllObjects]; } } #pragma mark - Chaining methods - (BFTask *)continueWithExecutor:(BFExecutor *)executor withBlock:(BFContinuationBlock)block { return [self continueWithExecutor:executor block:block cancellationToken:nil]; } - (BFTask *)continueWithExecutor:(BFExecutor *)executor block:(BFContinuationBlock)block cancellationToken:(nullable BFCancellationToken *)cancellationToken { BFTaskCompletionSource *tcs = [BFTaskCompletionSource taskCompletionSource]; // Capture all of the state that needs to used when the continuation is complete. dispatch_block_t executionBlock = ^{ if (cancellationToken.cancellationRequested) { [tcs cancel]; return; } id result = nil; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" if (BFTaskCatchesExceptions()) { @try { result = block(self); } @catch (NSException *exception) { NSLog(@"[Bolts] Warning: `BFTask` caught an exception in the continuation block." @" This behavior is discouraged and will be removed in a future release." @" Caught Exception: %@", exception); tcs.exception = exception; return; } } else { result = block(self); } #pragma clang diagnostic pop if ([result isKindOfClass:[BFTask class]]) { id (^setupWithTask) (BFTask *) = ^id(BFTask *task) { if (cancellationToken.cancellationRequested || task.cancelled) { [tcs cancel]; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" } else if (task.exception) { tcs.exception = task.exception; #pragma clang diagnostic pop } else if (task.error) { tcs.error = task.error; } else { tcs.result = task.result; } return nil; }; BFTask *resultTask = (BFTask *)result; if (resultTask.completed) { setupWithTask(resultTask); } else { [resultTask continueWithBlock:setupWithTask]; } } else { tcs.result = result; } }; BOOL completed; @synchronized(self.lock) { completed = self.completed; if (!completed) { [self.callbacks addObject:[^{ [executor execute:executionBlock]; } copy]]; } } if (completed) { [executor execute:executionBlock]; } return tcs.task; } - (BFTask *)continueWithBlock:(BFContinuationBlock)block { return [self continueWithExecutor:[BFExecutor defaultExecutor] block:block cancellationToken:nil]; } - (BFTask *)continueWithBlock:(BFContinuationBlock)block cancellationToken:(nullable BFCancellationToken *)cancellationToken { return [self continueWithExecutor:[BFExecutor defaultExecutor] block:block cancellationToken:cancellationToken]; } - (BFTask *)continueWithExecutor:(BFExecutor *)executor withSuccessBlock:(BFContinuationBlock)block { return [self continueWithExecutor:executor successBlock:block cancellationToken:nil]; } - (BFTask *)continueWithExecutor:(BFExecutor *)executor successBlock:(BFContinuationBlock)block cancellationToken:(nullable BFCancellationToken *)cancellationToken { if (cancellationToken.cancellationRequested) { return [BFTask cancelledTask]; } return [self continueWithExecutor:executor block:^id(BFTask *task) { if (task.faulted || task.cancelled) { return task; } else { return block(task); } } cancellationToken:cancellationToken]; } - (BFTask *)continueWithSuccessBlock:(BFContinuationBlock)block { return [self continueWithExecutor:[BFExecutor defaultExecutor] successBlock:block cancellationToken:nil]; } - (BFTask *)continueWithSuccessBlock:(BFContinuationBlock)block cancellationToken:(nullable BFCancellationToken *)cancellationToken { return [self continueWithExecutor:[BFExecutor defaultExecutor] successBlock:block cancellationToken:cancellationToken]; } #pragma mark - Syncing Task (Avoid it) - (void)warnOperationOnMainThread { warnBlockingOperationOnMainThread(); } - (void)waitUntilFinished { if ([NSThread isMainThread]) { [self warnOperationOnMainThread]; } @synchronized(self.lock) { if (self.completed) { return; } [self.condition lock]; } // TODO: (nlutsenko) Restructure this to use Bolts-Swift thread access synchronization architecture // In the meantime, it's absolutely safe to get `_completed` aka an ivar, as long as it's a `BOOL` aka less than word size. while (!_completed) { [self.condition wait]; } [self.condition unlock]; } #pragma mark - NSObject - (NSString *)description { // Acquire the data from the locked properties BOOL completed; BOOL cancelled; BOOL faulted; NSString *resultDescription = nil; @synchronized(self.lock) { completed = self.completed; cancelled = self.cancelled; faulted = self.faulted; resultDescription = completed ? [NSString stringWithFormat:@" result = %@", self.result] : @""; } // Description string includes status information and, if available, the // result since in some ways this is what a promise actually "is". return [NSString stringWithFormat:@"<%@: %p; completed = %@; cancelled = %@; faulted = %@;%@>", NSStringFromClass([self class]), self, completed ? @"YES" : @"NO", cancelled ? @"YES" : @"NO", faulted ? @"YES" : @"NO", resultDescription]; } @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/Common/BFTaskCompletionSource.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import NS_ASSUME_NONNULL_BEGIN @class BFTask; /*! A BFTaskCompletionSource represents the producer side of tasks. It is a task that also has methods for changing the state of the task by settings its completion values. */ @interface BFTaskCompletionSource<__covariant ResultType> : NSObject /*! Creates a new unfinished task. */ + (instancetype)taskCompletionSource; /*! The task associated with this TaskCompletionSource. */ @property (nonatomic, strong, readonly) BFTask *task; /*! Completes the task by setting the result. Attempting to set this for a completed task will raise an exception. @param result The result of the task. */ - (void)setResult:(nullable ResultType)result; /*! Completes the task by setting the error. Attempting to set this for a completed task will raise an exception. @param error The error for the task. */ - (void)setError:(NSError *)error; /*! Completes the task by setting an exception. Attempting to set this for a completed task will raise an exception. @param exception The exception for the task. @deprecated `BFTask` exception handling is deprecated and will be removed in a future release. */ - (void)setException:(NSException *)exception __attribute__((deprecated("`BFTask` exception handling is deprecated and will be removed in a future release."))); /*! Completes the task by marking it as cancelled. Attempting to set this for a completed task will raise an exception. */ - (void)cancel; /*! Sets the result of the task if it wasn't already completed. @returns whether the new value was set. */ - (BOOL)trySetResult:(nullable ResultType)result; /*! Sets the error of the task if it wasn't already completed. @param error The error for the task. @returns whether the new value was set. */ - (BOOL)trySetError:(NSError *)error; /*! Sets the exception of the task if it wasn't already completed. @param exception The exception for the task. @returns whether the new value was set. @deprecated `BFTask` exception handling is deprecated and will be removed in a future release. */ - (BOOL)trySetException:(NSException *)exception __attribute__((deprecated("`BFTask` exception handling is deprecated and will be removed in a future release."))); /*! Sets the cancellation state of the task if it wasn't already completed. @returns whether the new value was set. */ - (BOOL)trySetCancelled; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/Common/BFTaskCompletionSource.m ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "BFTaskCompletionSource.h" #import "BFTask.h" NS_ASSUME_NONNULL_BEGIN @interface BFTask (BFTaskCompletionSource) - (BOOL)trySetResult:(nullable id)result; - (BOOL)trySetError:(NSError *)error; - (BOOL)trySetException:(NSException *)exception; - (BOOL)trySetCancelled; @end @implementation BFTaskCompletionSource #pragma mark - Initializer + (instancetype)taskCompletionSource { return [[self alloc] init]; } - (instancetype)init { self = [super init]; if (!self) return self; _task = [[BFTask alloc] init]; return self; } #pragma mark - Custom Setters/Getters - (void)setResult:(nullable id)result { if (![self.task trySetResult:result]) { [NSException raise:NSInternalInconsistencyException format:@"Cannot set the result on a completed task."]; } } - (void)setError:(NSError *)error { if (![self.task trySetError:error]) { [NSException raise:NSInternalInconsistencyException format:@"Cannot set the error on a completed task."]; } } - (void)setException:(NSException *)exception { if (![self.task trySetException:exception]) { [NSException raise:NSInternalInconsistencyException format:@"Cannot set the exception on a completed task."]; } } - (void)cancel { if (![self.task trySetCancelled]) { [NSException raise:NSInternalInconsistencyException format:@"Cannot cancel a completed task."]; } } - (BOOL)trySetResult:(nullable id)result { return [self.task trySetResult:result]; } - (BOOL)trySetError:(NSError *)error { return [self.task trySetError:error]; } - (BOOL)trySetException:(NSException *)exception { return [self.task trySetException:exception]; } - (BOOL)trySetCancelled { return [self.task trySetCancelled]; } @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/Common/Bolts.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import #import #import #import #import #import #import #if __has_include() && TARGET_OS_IPHONE && !TARGET_OS_WATCH && !TARGET_OS_TV #import #import #import #import #import #import #import #import #import #endif NS_ASSUME_NONNULL_BEGIN /** A string containing the version of the Bolts Framework used by the current application. */ extern NSString *const BoltsFrameworkVersionString; NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/Common/Bolts.m ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "Bolts.h" NS_ASSUME_NONNULL_BEGIN NSString *const BoltsFrameworkVersionString = @"1.8.4"; NS_ASSUME_NONNULL_END ================================================ FILE: Pods/Bolts/Bolts/iOS/BFAppLink.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import /*! The version of the App Link protocol that this library supports */ FOUNDATION_EXPORT NSString *const BFAppLinkVersion; /*! Contains App Link metadata relevant for navigation on this device derived from the HTML at a given URL. */ @interface BFAppLink : NSObject /*! Creates a BFAppLink with the given list of BFAppLinkTargets and target URL. Generally, this will only be used by implementers of the BFAppLinkResolving protocol, as these implementers will produce App Link metadata for a given URL. @param sourceURL the URL from which this App Link is derived @param targets an ordered list of BFAppLinkTargets for this platform derived from App Link metadata. @param webURL the fallback web URL, if any, for the app link. */ + (instancetype)appLinkWithSourceURL:(NSURL *)sourceURL targets:(NSArray *)targets webURL:(NSURL *)webURL; /*! The URL from which this BFAppLink was derived */ @property (nonatomic, strong, readonly) NSURL *sourceURL; /*! The ordered list of targets applicable to this platform that will be used for navigation. */ @property (nonatomic, copy, readonly) NSArray *targets; /*! The fallback web URL to use if no targets are installed on this device. */ @property (nonatomic, strong, readonly) NSURL *webURL; @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFAppLink.m ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "BFAppLink_Internal.h" NSString *const BFAppLinkDataParameterName = @"al_applink_data"; NSString *const BFAppLinkTargetKeyName = @"target_url"; NSString *const BFAppLinkUserAgentKeyName = @"user_agent"; NSString *const BFAppLinkExtrasKeyName = @"extras"; NSString *const BFAppLinkRefererAppLink = @"referer_app_link"; NSString *const BFAppLinkRefererAppName = @"app_name"; NSString *const BFAppLinkRefererUrl = @"url"; NSString *const BFAppLinkVersionKeyName = @"version"; NSString *const BFAppLinkVersion = @"1.0"; @interface BFAppLink () @property (nonatomic, strong, readwrite) NSURL *sourceURL; @property (nonatomic, copy, readwrite) NSArray *targets; @property (nonatomic, strong, readwrite) NSURL *webURL; @property (nonatomic, assign, readwrite, getter=isBackToReferrer) BOOL backToReferrer; @end @implementation BFAppLink + (instancetype)appLinkWithSourceURL:(NSURL *)sourceURL targets:(NSArray *)targets webURL:(NSURL *)webURL isBackToReferrer:(BOOL)isBackToReferrer { BFAppLink *link = [[self alloc] initWithIsBackToReferrer:isBackToReferrer]; link.sourceURL = sourceURL; link.targets = [targets copy]; link.webURL = webURL; return link; } + (instancetype)appLinkWithSourceURL:(NSURL *)sourceURL targets:(NSArray *)targets webURL:(NSURL *)webURL { return [self appLinkWithSourceURL:sourceURL targets:targets webURL:webURL isBackToReferrer:NO]; } - (BFAppLink *)initWithIsBackToReferrer:(BOOL)backToReferrer { if ((self = [super init])) { _backToReferrer = backToReferrer; } return self; } @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFAppLinkNavigation.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import #import /*! The result of calling navigate on a BFAppLinkNavigation */ typedef NS_ENUM(NSInteger, BFAppLinkNavigationType) { /*! Indicates that the navigation failed and no app was opened */ BFAppLinkNavigationTypeFailure, /*! Indicates that the navigation succeeded by opening the URL in the browser */ BFAppLinkNavigationTypeBrowser, /*! Indicates that the navigation succeeded by opening the URL in an app on the device */ BFAppLinkNavigationTypeApp }; @protocol BFAppLinkResolving; @class BFTask; /*! Represents a pending request to navigate to an App Link. Most developers will simply use navigateToURLInBackground: to open a URL, but developers can build custom requests with additional navigation and app data attached to them by creating BFAppLinkNavigations themselves. */ @interface BFAppLinkNavigation : NSObject /*! The extras for the AppLinkNavigation. This will generally contain application-specific data that should be passed along with the request, such as advertiser or affiliate IDs or other such metadata relevant on this device. */ @property (nonatomic, copy, readonly) NSDictionary *extras; /*! The al_applink_data for the AppLinkNavigation. This will generally contain data common to navigation attempts such as back-links, user agents, and other information that may be used in routing and handling an App Link request. */ @property (nonatomic, copy, readonly) NSDictionary *appLinkData; /*! The AppLink to navigate to */ @property (nonatomic, strong, readonly) BFAppLink *appLink; /*! Creates an AppLinkNavigation with the given link, extras, and App Link data */ + (instancetype)navigationWithAppLink:(BFAppLink *)appLink extras:(NSDictionary *)extras appLinkData:(NSDictionary *)appLinkData; /*! Creates an NSDictionary with the correct format for iOS callback URLs, to be used as 'appLinkData' argument in the call to navigationWithAppLink:extras:appLinkData: */ + (NSDictionary *)callbackAppLinkDataForAppWithName:(NSString *)appName url:(NSString *)url; /*! Performs the navigation */ - (BFAppLinkNavigationType)navigate:(NSError **)error; /*! Returns a BFAppLink for the given URL */ + (BFTask *)resolveAppLinkInBackground:(NSURL *)destination; /*! Returns a BFAppLink for the given URL using the given App Link resolution strategy */ + (BFTask *)resolveAppLinkInBackground:(NSURL *)destination resolver:(id)resolver; /*! Navigates to a BFAppLink and returns whether it opened in-app or in-browser */ + (BFAppLinkNavigationType)navigateToAppLink:(BFAppLink *)link error:(NSError **)error; /*! Returns a BFAppLinkNavigationType based on a BFAppLink. It's essentially a no-side-effect version of navigateToAppLink:error:, allowing apps to determine flow based on the link type (e.g. open an internal web view instead of going straight to the browser for regular links.) */ + (BFAppLinkNavigationType)navigationTypeForLink:(BFAppLink *)link; /*! Return navigation type for current instance. No-side-effect version of navigate: */ - (BFAppLinkNavigationType)navigationType; /*! Navigates to a URL (an asynchronous action) and returns a BFNavigationType */ + (BFTask *)navigateToURLInBackground:(NSURL *)destination; /*! Navigates to a URL (an asynchronous action) using the given App Link resolution strategy and returns a BFNavigationType */ + (BFTask *)navigateToURLInBackground:(NSURL *)destination resolver:(id)resolver; /*! Gets the default resolver to be used for App Link resolution. If the developer has not set one explicitly, a basic, built-in resolver will be used. */ + (id)defaultResolver; /*! Sets the default resolver to be used for App Link resolution. Setting this to nil will revert the default resolver to the basic, built-in resolver provided by Bolts. */ + (void)setDefaultResolver:(id)resolver; @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFAppLinkNavigation.m ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "BFAppLinkNavigation.h" #import #import "BFMeasurementEvent_Internal.h" #import "BFAppLink_Internal.h" FOUNDATION_EXPORT NSString *const BFAppLinkDataParameterName; FOUNDATION_EXPORT NSString *const BFAppLinkTargetKeyName; FOUNDATION_EXPORT NSString *const BFAppLinkUserAgentKeyName; FOUNDATION_EXPORT NSString *const BFAppLinkExtrasKeyName; FOUNDATION_EXPORT NSString *const BFAppLinkVersionKeyName; FOUNDATION_EXPORT NSString *const BFAppLinkRefererAppLink; FOUNDATION_EXPORT NSString *const BFAppLinkRefererAppName; FOUNDATION_EXPORT NSString *const BFAppLinkRefererUrl; static id defaultResolver; @interface BFAppLinkNavigation () @property (nonatomic, copy, readwrite) NSDictionary *extras; @property (nonatomic, copy, readwrite) NSDictionary *appLinkData; @property (nonatomic, strong, readwrite) BFAppLink *appLink; @end @implementation BFAppLinkNavigation + (instancetype)navigationWithAppLink:(BFAppLink *)appLink extras:(NSDictionary *)extras appLinkData:(NSDictionary *)appLinkData { BFAppLinkNavigation *navigation = [[self alloc] init]; navigation.appLink = appLink; navigation.extras = extras; navigation.appLinkData = appLinkData; return navigation; } + (NSDictionary *)callbackAppLinkDataForAppWithName:(NSString *)appName url:(NSString *)url { return @{BFAppLinkRefererAppLink: @{BFAppLinkRefererAppName: appName, BFAppLinkRefererUrl: url}}; } - (NSString *)stringByEscapingQueryString:(NSString *)string { #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0 || __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_9 return [string stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; #else return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)string, NULL, (CFStringRef) @":/?#[]@!$&'()*+,;=", kCFStringEncodingUTF8)); #endif } - (NSURL *)appLinkURLWithTargetURL:(NSURL *)targetUrl error:(NSError **)error { NSMutableDictionary *appLinkData = [NSMutableDictionary dictionaryWithDictionary:self.appLinkData ?: @{}]; // Add applink protocol data if (!appLinkData[BFAppLinkUserAgentKeyName]) { appLinkData[BFAppLinkUserAgentKeyName] = [NSString stringWithFormat:@"Bolts iOS %@", BoltsFrameworkVersionString]; } if (!appLinkData[BFAppLinkVersionKeyName]) { appLinkData[BFAppLinkVersionKeyName] = BFAppLinkVersion; } appLinkData[BFAppLinkTargetKeyName] = [self.appLink.sourceURL absoluteString]; appLinkData[BFAppLinkExtrasKeyName] = self.extras ?: @{}; // JSON-ify the applink data NSError *jsonError = nil; NSData *jsonBlob = [NSJSONSerialization dataWithJSONObject:appLinkData options:0 error:&jsonError]; if (!jsonError) { NSString *jsonString = [[NSString alloc] initWithData:jsonBlob encoding:NSUTF8StringEncoding]; NSString *encoded = [self stringByEscapingQueryString:jsonString]; NSString *endUrlString = [NSString stringWithFormat:@"%@%@%@=%@", [targetUrl absoluteString], targetUrl.query ? @"&" : @"?", BFAppLinkDataParameterName, encoded]; return [NSURL URLWithString:endUrlString]; } else { if (error) { *error = jsonError; } // If there was an error encoding the app link data, fail hard. return nil; } } - (BFAppLinkNavigationType)navigate:(NSError **)error { NSURL *openedURL = nil; NSError *encodingError = nil; BFAppLinkNavigationType retType = BFAppLinkNavigationTypeFailure; // Find the first eligible/launchable target in the BFAppLink. for (BFAppLinkTarget *target in self.appLink.targets) { NSURL *appLinkAppURL = [self appLinkURLWithTargetURL:target.URL error:&encodingError]; if (encodingError || !appLinkAppURL) { if (error) { *error = encodingError; } } else if ([[UIApplication sharedApplication] openURL:appLinkAppURL]) { retType = BFAppLinkNavigationTypeApp; openedURL = appLinkAppURL; break; } } if (!openedURL && self.appLink.webURL) { // Fall back to opening the url in the browser if available. NSURL *appLinkBrowserURL = [self appLinkURLWithTargetURL:self.appLink.webURL error:&encodingError]; if (encodingError || !appLinkBrowserURL) { // If there was an error encoding the app link data, fail hard. if (error) { *error = encodingError; } } else if ([[UIApplication sharedApplication] openURL:appLinkBrowserURL]) { // This was a browser navigation. retType = BFAppLinkNavigationTypeBrowser; openedURL = appLinkBrowserURL; } } [self postAppLinkNavigateEventNotificationWithTargetURL:openedURL error:error ? *error : nil type:retType]; return retType; } - (void)postAppLinkNavigateEventNotificationWithTargetURL:(NSURL *)outputURL error:(NSError *)error type:(BFAppLinkNavigationType)type { NSString *const EVENT_YES_VAL = @"1"; NSString *const EVENT_NO_VAL = @"0"; NSMutableDictionary *logData = [[NSMutableDictionary alloc] init]; NSString *outputURLScheme = [outputURL scheme]; NSString *outputURLString = [outputURL absoluteString]; if (outputURLScheme) { logData[@"outputURLScheme"] = outputURLScheme; } if (outputURLString) { logData[@"outputURL"] = outputURLString; } NSString *sourceURLString = [self.appLink.sourceURL absoluteString]; NSString *sourceURLHost = [self.appLink.sourceURL host]; NSString *sourceURLScheme = [self.appLink.sourceURL scheme]; if (sourceURLString) { logData[@"sourceURL"] = sourceURLString; } if (sourceURLHost) { logData[@"sourceHost"] = sourceURLHost; } if (sourceURLScheme) { logData[@"sourceScheme"] = sourceURLScheme; } if ([error localizedDescription]) { logData[@"error"] = [error localizedDescription]; } NSString *success = nil; //no NSString *linkType = nil; // unknown; switch (type) { case BFAppLinkNavigationTypeFailure: success = EVENT_NO_VAL; linkType = @"fail"; break; case BFAppLinkNavigationTypeBrowser: success = EVENT_YES_VAL; linkType = @"web"; break; case BFAppLinkNavigationTypeApp: success = EVENT_YES_VAL; linkType = @"app"; break; default: break; } if (success) { logData[@"success"] = success; } if (linkType) { logData[@"type"] = linkType; } if ([self.appLink isBackToReferrer]) { [BFMeasurementEvent postNotificationForEventName:BFAppLinkNavigateBackToReferrerEventName args:logData]; } else { [BFMeasurementEvent postNotificationForEventName:BFAppLinkNavigateOutEventName args:logData]; } } + (BFTask *)resolveAppLinkInBackground:(NSURL *)destination resolver:(id)resolver { return [resolver appLinkFromURLInBackground:destination]; } + (BFTask *)resolveAppLinkInBackground:(NSURL *)destination { return [self resolveAppLinkInBackground:destination resolver:[self defaultResolver]]; } + (BFTask *)navigateToURLInBackground:(NSURL *)destination { return [self navigateToURLInBackground:destination resolver:[self defaultResolver]]; } + (BFTask *)navigateToURLInBackground:(NSURL *)destination resolver:(id)resolver { BFTask *resolutionTask = [self resolveAppLinkInBackground:destination resolver:resolver]; return [resolutionTask continueWithExecutor:[BFExecutor mainThreadExecutor] withSuccessBlock:^id(BFTask *task) { NSError *error = nil; BFAppLinkNavigationType result = [self navigateToAppLink:task.result error:&error]; if (error) { return [BFTask taskWithError:error]; } else { return @(result); } }]; } + (BFAppLinkNavigationType)navigateToAppLink:(BFAppLink *)link error:(NSError **)error { return [[BFAppLinkNavigation navigationWithAppLink:link extras:nil appLinkData:nil] navigate:error]; } + (BFAppLinkNavigationType)navigationTypeForLink:(BFAppLink *)link { return [[self navigationWithAppLink:link extras:nil appLinkData:nil] navigationType]; } - (BFAppLinkNavigationType)navigationType { BFAppLinkTarget *eligibleTarget = nil; for (BFAppLinkTarget *target in self.appLink.targets) { if ([[UIApplication sharedApplication] canOpenURL:target.URL]) { eligibleTarget = target; break; } } if (eligibleTarget != nil) { NSURL *appLinkURL = [self appLinkURLWithTargetURL:eligibleTarget.URL error:nil]; if (appLinkURL != nil) { return BFAppLinkNavigationTypeApp; } else { return BFAppLinkNavigationTypeFailure; } } if (self.appLink.webURL != nil) { NSURL *appLinkURL = [self appLinkURLWithTargetURL:eligibleTarget.URL error:nil]; if (appLinkURL != nil) { return BFAppLinkNavigationTypeBrowser; } else { return BFAppLinkNavigationTypeFailure; } } return BFAppLinkNavigationTypeFailure; } + (id)defaultResolver { if (defaultResolver) { return defaultResolver; } return [BFWebViewAppLinkResolver sharedInstance]; } + (void)setDefaultResolver:(id)resolver { defaultResolver = resolver; } @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFAppLinkResolving.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import @class BFTask; /*! Implement this protocol to provide an alternate strategy for resolving App Links that may include pre-fetching, caching, or querying for App Link data from an index provided by a service provider. */ @protocol BFAppLinkResolving /*! Asynchronously resolves App Link data for a given URL. @param url The URL to resolve into an App Link. @returns A BFTask that will return a BFAppLink for the given URL. */ - (BFTask *)appLinkFromURLInBackground:(NSURL *)url; @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFAppLinkReturnToRefererController.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import #import #import @class BFAppLink; @class BFAppLinkReturnToRefererController; /*! Protocol that a class can implement in order to be notified when the user has navigated back to the referer of an App Link. */ @protocol BFAppLinkReturnToRefererControllerDelegate @optional /*! Called when the user has tapped to navigate, but before the navigation has been performed. */ - (void)returnToRefererController:(BFAppLinkReturnToRefererController *)controller willNavigateToAppLink:(BFAppLink *)appLink; /*! Called after the navigation has been attempted, with an indication of whether the referer app link was successfully opened. */ - (void)returnToRefererController:(BFAppLinkReturnToRefererController *)controller didNavigateToAppLink:(BFAppLink *)url type:(BFAppLinkNavigationType)type; @end /*! A controller class that implements default behavior for a BFAppLinkReturnToRefererView, including the ability to display the view above the navigation bar for navigation-based apps. */ @interface BFAppLinkReturnToRefererController : NSObject /*! The delegate that will be notified when the user navigates back to the referer. */ @property (nonatomic, weak) id delegate; /*! The BFAppLinkReturnToRefererView this controller is controlling. */ @property (nonatomic, strong) BFAppLinkReturnToRefererView *view; /*! Initializes a controller suitable for controlling a BFAppLinkReturnToRefererView that is to be displayed contained within another UIView (i.e., not displayed above the navigation bar). */ - (instancetype)init; /*! Initializes a controller suitable for controlling a BFAppLinkReturnToRefererView that is to be displayed displayed above the navigation bar. */ - (instancetype)initForDisplayAboveNavController:(UINavigationController *)navController; /*! Removes the view entirely from the navigation controller it is currently displayed in. */ - (void)removeFromNavController; /*! Shows the BFAppLinkReturnToRefererView with the specified referer information. If nil or missing data, the view will not be displayed. */ - (void)showViewForRefererAppLink:(BFAppLink *)refererAppLink; /*! Shows the BFAppLinkReturnToRefererView with referer information extracted from the specified URL. If nil or missing referer App Link data, the view will not be displayed. */ - (void)showViewForRefererURL:(NSURL *)url; /*! Closes the view, possibly animating it. */ - (void)closeViewAnimated:(BOOL)animated; @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFAppLinkReturnToRefererController.m ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "BFAppLinkReturnToRefererController.h" #import "BFAppLink.h" #import "BFAppLinkReturnToRefererView_Internal.h" #import "BFURL_Internal.h" static const CFTimeInterval kBFViewAnimationDuration = 0.25f; @implementation BFAppLinkReturnToRefererController { UINavigationController *_navigationController; BFAppLinkReturnToRefererView *_view; } #pragma mark - Object lifecycle - (instancetype)init { return [self initForDisplayAboveNavController:nil]; } - (instancetype)initForDisplayAboveNavController:(UINavigationController *)navController { self = [super init]; if (self) { _navigationController = navController; if (_navigationController != nil) { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(statusBarFrameWillChange:) name:UIApplicationWillChangeStatusBarFrameNotification object:nil]; [nc addObserver:self selector:@selector(statusBarFrameDidChange:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil]; [nc addObserver:self selector:@selector(orientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil]; } } return self; } - (void)dealloc { _view.delegate = nil; [[NSNotificationCenter defaultCenter] removeObserver:self]; } #pragma mark - Public API - (BFAppLinkReturnToRefererView *)view { if (!_view) { self.view = [[BFAppLinkReturnToRefererView alloc] initWithFrame:CGRectZero]; if (_navigationController) { [_navigationController.view addSubview:_view]; } } return _view; } - (void)setView:(BFAppLinkReturnToRefererView *)view { if (_view != view) { _view.delegate = nil; } _view = view; _view.delegate = self; if (_navigationController) { _view.includeStatusBarInSize = BFIncludeStatusBarInSizeAlways; } } - (void)showViewForRefererAppLink:(BFAppLink *)refererAppLink { self.view.refererAppLink = refererAppLink; [_view sizeToFit]; if (_navigationController) { if (!_view.closed) { dispatch_async(dispatch_get_main_queue(), ^{ [self moveNavigationBar]; }); } } } - (void)showViewForRefererURL:(NSURL *)url { BFAppLink *appLink = [BFURL URLForRenderBackToReferrerBarURL:url].appLinkReferer; [self showViewForRefererAppLink:appLink]; } - (void)removeFromNavController { if (_navigationController) { [_view removeFromSuperview]; _navigationController = nil; } } #pragma mark - BFAppLinkReturnToRefererViewDelegate - (void)returnToRefererViewDidTapInsideCloseButton:(BFAppLinkReturnToRefererView *)view { [self closeViewAnimated:YES explicitlyClosed:YES]; } - (void)returnToRefererViewDidTapInsideLink:(BFAppLinkReturnToRefererView *)view link:(BFAppLink *)link { [self openRefererAppLink:link]; [self closeViewAnimated:NO explicitlyClosed:NO]; } #pragma mark - Private - (void)statusBarFrameWillChange:(NSNotification *)notification { NSValue *rectValue = [[notification userInfo] valueForKey:UIApplicationStatusBarFrameUserInfoKey]; CGRect newFrame; [rectValue getValue:&newFrame]; if (_navigationController && !_view.closed) { if (CGRectGetHeight(newFrame) == 40) { UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState; [UIView animateWithDuration:kBFViewAnimationDuration delay:0.0 options:options animations:^{ _view.frame = CGRectMake(0.0, 0.0, CGRectGetWidth(_view.bounds), 0.0); } completion:nil]; } } } - (void)statusBarFrameDidChange:(NSNotification *)notification { NSValue *rectValue = [[notification userInfo] valueForKey:UIApplicationStatusBarFrameUserInfoKey]; CGRect newFrame; [rectValue getValue:&newFrame]; if (_navigationController && !_view.closed) { if (CGRectGetHeight(newFrame) == 40) { UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState; [UIView animateWithDuration:kBFViewAnimationDuration delay:0.0 options:options animations:^{ [_view sizeToFit]; [self moveNavigationBar]; } completion:nil]; } } } - (void)orientationDidChange:(NSNotificationCenter *)notification { if (_navigationController && !_view.closed && CGRectGetHeight(_view.bounds) > 0) { dispatch_async(dispatch_get_main_queue(), ^{ [self moveNavigationBar]; }); } } - (void)moveNavigationBar { if (_view.closed || !_view.refererAppLink) { return; } [self updateNavigationBarY:CGRectGetHeight(_view.bounds)]; } - (void)updateNavigationBarY:(CGFloat)y { UINavigationBar *navigationBar = _navigationController.navigationBar; CGRect navigationBarFrame = navigationBar.frame; CGFloat oldContainerViewY = CGRectGetMaxY(navigationBarFrame); navigationBarFrame.origin.y = y; navigationBar.frame = navigationBarFrame; CGFloat dy = CGRectGetMaxY(navigationBarFrame) - oldContainerViewY; UIView *containerView = _navigationController.visibleViewController.view.superview; containerView.frame = UIEdgeInsetsInsetRect(containerView.frame, UIEdgeInsetsMake(dy, 0.0, 0.0, 0.0)); } - (void)closeViewAnimated:(BOOL)animated { [self closeViewAnimated:animated explicitlyClosed:YES]; } - (void)closeViewAnimated:(BOOL)animated explicitlyClosed:(BOOL)explicitlyClosed { void (^closer)(void) = ^{ if (_navigationController) { [self updateNavigationBarY:_view.statusBarHeight]; } CGRect frame = _view.frame; frame.size.height = 0.0; _view.frame = frame; }; if (animated) { [UIView animateWithDuration:kBFViewAnimationDuration animations:^{ closer(); } completion:^(BOOL finished) { if (explicitlyClosed) { _view.closed = YES; } }]; } else { closer(); if (explicitlyClosed) { _view.closed = YES; } } } - (void)openRefererAppLink:(BFAppLink *)refererAppLink { if (refererAppLink) { id delegate = _delegate; if ([delegate respondsToSelector:@selector(returnToRefererController:willNavigateToAppLink:)]) { [delegate returnToRefererController:self willNavigateToAppLink:refererAppLink]; } NSError *error = nil; BFAppLinkNavigationType type = [BFAppLinkNavigation navigateToAppLink:refererAppLink error:&error]; if ([delegate respondsToSelector:@selector(returnToRefererController:didNavigateToAppLink:type:)]) { [delegate returnToRefererController:self didNavigateToAppLink:refererAppLink type:type]; } } } @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFAppLinkReturnToRefererView.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import #import #import @class BFAppLinkReturnToRefererView; @class BFURL; typedef NS_ENUM(NSUInteger, BFIncludeStatusBarInSize) { BFIncludeStatusBarInSizeNever, BFIncludeStatusBarInSizeIOS7AndLater, BFIncludeStatusBarInSizeAlways, }; /*! Protocol that a class can implement in order to be notified when the user has navigated back to the referer of an App Link. */ @protocol BFAppLinkReturnToRefererViewDelegate /*! Called when the user has tapped inside the close button. */ - (void)returnToRefererViewDidTapInsideCloseButton:(BFAppLinkReturnToRefererView *)view; /*! Called when the user has tapped inside the App Link portion of the view. */ - (void)returnToRefererViewDidTapInsideLink:(BFAppLinkReturnToRefererView *)view link:(BFAppLink *)link; @end /*! Provides a UIView that displays a button allowing users to navigate back to the application that launched the App Link currently being handled, if the App Link contained referer data. The user can also close the view by clicking a close button rather than navigating away. If the view is provided an App Link that does not contain referer data, it will have zero size and no UI will be displayed. */ @interface BFAppLinkReturnToRefererView : UIView /*! The delegate that will be notified when the user navigates back to the referer. */ @property (nonatomic, weak) id delegate; /*! The color of the text label and close button. */ @property (nonatomic, strong) UIColor *textColor; @property (nonatomic, strong) BFAppLink *refererAppLink; /*! Indicates whether to extend the size of the view to include the current status bar size, for use in scenarios where the view might extend under the status bar on iOS 7 and above; this property has no effect on earlier versions of iOS. */ @property (nonatomic, assign) BFIncludeStatusBarInSize includeStatusBarInSize; /*! Indicates whether the user has closed the view by clicking the close button. */ @property (nonatomic, assign) BOOL closed; @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFAppLinkReturnToRefererView.m ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "BFAppLinkReturnToRefererView.h" #import "BFAppLink.h" #import "BFAppLinkTarget.h" static const CGFloat BFMarginX = 8.5f; static const CGFloat BFMarginY = 8.5f; static NSString *const BFRefererAppLink = @"referer_app_link"; static NSString *const BFRefererAppName = @"app_name"; static NSString *const BFRefererUrl = @"url"; static const CGFloat BFCloseButtonWidth = 12.0; static const CGFloat BFCloseButtonHeight = 12.0; @interface BFAppLinkReturnToRefererView () @property (nonatomic, strong) UILabel *labelView; @property (nonatomic, strong) UIButton *closeButton; @property (nonatomic, strong) UITapGestureRecognizer *insideTapGestureRecognizer; @end @implementation BFAppLinkReturnToRefererView { BOOL _explicitlyHidden; } #pragma mark - Initialization - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self commonInit]; [self sizeToFit]; } return self; } - (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { [self commonInit]; } return self; } - (void)commonInit { // Initialization code _includeStatusBarInSize = BFIncludeStatusBarInSizeIOS7AndLater; // iOS 7 system blue color self.backgroundColor = [UIColor colorWithRed:0.0f green:122.0f / 255.0f blue:1.0f alpha:1.0f]; self.textColor = [UIColor whiteColor]; self.clipsToBounds = YES; [self initViews]; } - (void)initViews { if (!_labelView && !_closeButton) { _closeButton = [UIButton buttonWithType:UIButtonTypeCustom]; _closeButton.backgroundColor = [UIColor clearColor]; _closeButton.userInteractionEnabled = YES; _closeButton.clipsToBounds = YES; _closeButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin; _closeButton.contentMode = UIViewContentModeCenter; [_closeButton addTarget:self action:@selector(closeButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:_closeButton]; _labelView = [[UILabel alloc] initWithFrame:CGRectZero]; _labelView.font = [UIFont systemFontOfSize:[UIFont smallSystemFontSize]]; _labelView.textColor = [UIColor whiteColor]; _labelView.backgroundColor = [UIColor clearColor]; #ifdef __IPHONE_6_0 _labelView.textAlignment = NSTextAlignmentCenter; #else _labelView.textAlignment = UITextAlignmentCenter; #endif _labelView.clipsToBounds = YES; [self updateLabelText]; [self addSubview:_labelView]; _insideTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapInside:)]; _labelView.userInteractionEnabled = YES; [_labelView addGestureRecognizer:_insideTapGestureRecognizer]; [self updateColors]; } } #pragma mark - Layout - (CGSize)intrinsicContentSize { CGSize size = self.bounds.size; if (_closed || !self.hasRefererData) { size.height = 0.0; } else { CGSize labelSize = [_labelView sizeThatFits:size]; size = CGSizeMake(size.width, labelSize.height + 2 * BFMarginY + self.statusBarHeight); } return size; } - (void)layoutSubviews { [super layoutSubviews]; CGRect bounds = self.bounds; _labelView.preferredMaxLayoutWidth = _labelView.bounds.size.width; CGSize labelSize = [_labelView sizeThatFits:bounds.size]; _labelView.frame = CGRectMake(BFMarginX, CGRectGetMaxY(bounds) - labelSize.height - 1.5f * BFMarginY, CGRectGetMaxX(bounds) - BFCloseButtonWidth - 3 * BFMarginX, labelSize.height + BFMarginY); _closeButton.frame = CGRectMake(CGRectGetMaxX(bounds) - BFCloseButtonWidth - 2 * BFMarginX, _labelView.center.y - BFCloseButtonHeight / 2.0f - BFMarginY, BFCloseButtonWidth + 2 * BFMarginX, BFCloseButtonHeight + 2 * BFMarginY); } - (CGSize)sizeThatFits:(CGSize)size { if (_closed || !self.hasRefererData) { size = CGSizeMake(size.width, 0.0); } else { CGSize labelSize = [_labelView sizeThatFits:size]; size = CGSizeMake(size.width, labelSize.height + 2 * BFMarginY + self.statusBarHeight); } return size; } - (CGFloat)statusBarHeight { UIApplication *application = [UIApplication sharedApplication]; BOOL include; switch (_includeStatusBarInSize) { case BFIncludeStatusBarInSizeAlways: include = YES; break; case BFIncludeStatusBarInSizeIOS7AndLater: { float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue]; include = (systemVersion >= 7.0); break; } case BFIncludeStatusBarInSizeNever: include = NO; break; } if (include && !application.statusBarHidden) { BOOL landscape = UIInterfaceOrientationIsLandscape(application.statusBarOrientation); CGRect statusBarFrame = application.statusBarFrame; return landscape ? CGRectGetWidth(statusBarFrame) : CGRectGetHeight(statusBarFrame); } return 0; } #pragma mark - Public API - (void)setIncludeStatusBarInSize:(BFIncludeStatusBarInSize)includeStatusBarInSize { _includeStatusBarInSize = includeStatusBarInSize; [self setNeedsLayout]; [self invalidateIntrinsicContentSize]; } - (void)setTextColor:(UIColor *)textColor { _textColor = textColor; [self updateColors]; } - (void)setRefererAppLink:(BFAppLink *)refererAppLink { _refererAppLink = refererAppLink; [self updateLabelText]; [self updateHidden]; [self invalidateIntrinsicContentSize]; } - (void)setClosed:(BOOL)closed { if (_closed != closed) { _closed = closed; [self updateHidden]; [self invalidateIntrinsicContentSize]; } } - (void)setHidden:(BOOL)hidden { _explicitlyHidden = hidden; [self updateHidden]; } #pragma mark - Private - (void)updateLabelText { NSString *appName = (_refererAppLink && _refererAppLink.targets[0]) ? [_refererAppLink.targets[0] appName] : nil; _labelView.text = [self localizedLabelForReferer:appName]; } - (void)updateColors { UIImage *closeButtonImage = [self drawCloseButtonImageWithColor:_textColor]; _labelView.textColor = _textColor; [_closeButton setImage:closeButtonImage forState:UIControlStateNormal]; } - (UIImage *)drawCloseButtonImageWithColor:(UIColor *)color { UIGraphicsBeginImageContextWithOptions(CGSizeMake(BFCloseButtonWidth, BFCloseButtonHeight), NO, 0.0f); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetStrokeColorWithColor(context, [color CGColor]); CGContextSetFillColorWithColor(context, [color CGColor]); CGContextSetLineWidth(context, 1.25f); CGFloat inset = 0.5f; CGContextMoveToPoint(context, inset, inset); CGContextAddLineToPoint(context, BFCloseButtonWidth - inset, BFCloseButtonHeight - inset); CGContextStrokePath(context); CGContextMoveToPoint(context, BFCloseButtonWidth - inset, inset); CGContextAddLineToPoint(context, inset, BFCloseButtonHeight - inset); CGContextStrokePath(context); UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return result; } - (NSString *)localizedLabelForReferer:(NSString *)refererName { if (!refererName) { return nil; } NSString *format = NSLocalizedString(@"Touch to return to %1$@", @"Format for the string to return to a calling app."); return [NSString stringWithFormat:format, refererName]; } - (BOOL)hasRefererData { return _refererAppLink && _refererAppLink.targets[0]; } - (void)closeButtonTapped:(id)sender { [_delegate returnToRefererViewDidTapInsideCloseButton:self]; } - (void)onTapInside:(UIGestureRecognizer *)sender { [_delegate returnToRefererViewDidTapInsideLink:self link:_refererAppLink]; } - (void)updateHidden { [super setHidden:_explicitlyHidden || _closed || !self.hasRefererData]; } @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFAppLinkTarget.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import /*! Represents a target defined in App Link metadata, consisting of at least a URL, and optionally an App Store ID and name. */ @interface BFAppLinkTarget : NSObject /*! Creates a BFAppLinkTarget with the given app site and target URL. */ + (instancetype)appLinkTargetWithURL:(NSURL *)url appStoreId:(NSString *)appStoreId appName:(NSString *)appName; /*! The URL prefix for this app link target */ @property (nonatomic, strong, readonly) NSURL *URL; /*! The app ID for the app store */ @property (nonatomic, copy, readonly) NSString *appStoreId; /*! The name of the app */ @property (nonatomic, copy, readonly) NSString *appName; @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFAppLinkTarget.m ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "BFAppLinkTarget.h" @interface BFAppLinkTarget () @property (nonatomic, strong, readwrite) NSURL *URL; @property (nonatomic, copy, readwrite) NSString *appStoreId; @property (nonatomic, copy, readwrite) NSString *appName; @end @implementation BFAppLinkTarget + (instancetype)appLinkTargetWithURL:(NSURL *)url appStoreId:(NSString *)appStoreId appName:(NSString *)appName { BFAppLinkTarget *target = [[self alloc] init]; target.URL = url; target.appStoreId = appStoreId; target.appName = appName; return target; } @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFMeasurementEvent.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import /*! The name of the notification posted by BFMeasurementEvent */ FOUNDATION_EXPORT NSString *const BFMeasurementEventNotificationName; /*! Defines keys in the userInfo object for the notification named BFMeasurementEventNotificationName */ /*! The string field for the name of the event */ FOUNDATION_EXPORT NSString *const BFMeasurementEventNameKey; /*! The dictionary field for the arguments of the event */ FOUNDATION_EXPORT NSString *const BFMeasurementEventArgsKey; /*! Bolts Events raised by BFMeasurementEvent for Applink */ /*! The name of the event posted when [BFURL URLWithURL:] is called successfully. This represents the successful parsing of an app link URL. */ FOUNDATION_EXPORT NSString *const BFAppLinkParseEventName; /*! The name of the event posted when [BFURL URLWithInboundURL:] is called successfully. This represents parsing an inbound app link URL from a different application */ FOUNDATION_EXPORT NSString *const BFAppLinkNavigateInEventName; /*! The event raised when the user navigates from your app to other apps */ FOUNDATION_EXPORT NSString *const BFAppLinkNavigateOutEventName; /*! The event raised when the user navigates out from your app and back to the referrer app. e.g when the user leaves your app after tapping the back-to-referrer navigation bar */ FOUNDATION_EXPORT NSString *const BFAppLinkNavigateBackToReferrerEventName; @interface BFMeasurementEvent : NSObject @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFMeasurementEvent.m ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "BFMeasurementEvent_Internal.h" NSString *const BFMeasurementEventNotificationName = @"com.parse.bolts.measurement_event"; NSString *const BFMeasurementEventNameKey = @"event_name"; NSString *const BFMeasurementEventArgsKey = @"event_args"; /* app Link Event raised by this BFURL */ NSString *const BFAppLinkParseEventName = @"al_link_parse"; NSString *const BFAppLinkNavigateInEventName = @"al_nav_in"; /*! AppLink events raised in this class */ NSString *const BFAppLinkNavigateOutEventName = @"al_nav_out"; NSString *const BFAppLinkNavigateBackToReferrerEventName = @"al_ref_back_out"; __attribute__((noinline)) void warnOnMissingEventName() { NSLog(@"Warning: Missing event name when logging bolts measurement event. \n" " Ignoring this event in logging."); } @implementation BFMeasurementEvent { NSString *_name; NSDictionary *_args; } - (void)postNotification { if (!_name) { warnOnMissingEventName(); return; } NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; NSDictionary *userInfo = @{BFMeasurementEventNameKey : _name, BFMeasurementEventArgsKey : _args}; [center postNotificationName:BFMeasurementEventNotificationName object:self userInfo:userInfo]; } - (instancetype)initEventWithName:(NSString *)name args:(NSDictionary *)args { if ((self = [super init])) { _name = name; _args = args ? args : @{}; } return self; } + (void)postNotificationForEventName:(NSString *)name args:(NSDictionary *)args { [[[self alloc] initEventWithName:name args:args] postNotification]; } @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFURL.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import @class BFAppLink; /*! Provides a set of utilities for working with NSURLs, such as parsing of query parameters and handling for App Link requests. */ @interface BFURL : NSObject /*! Creates a link target from a raw URL. On success, this posts the BFAppLinkParseEventName measurement event. If you are constructing the BFURL within your application delegate's application:openURL:sourceApplication:annotation:, you should instead use URLWithInboundURL:sourceApplication: to support better BFMeasurementEvent notifications @param url The instance of `NSURL` to create BFURL from. */ + (BFURL *)URLWithURL:(NSURL *)url; /*! Creates a link target from a raw URL received from an external application. This is typically called from the app delegate's application:openURL:sourceApplication:annotation: and will post the BFAppLinkNavigateInEventName measurement event. @param url The instance of `NSURL` to create BFURL from. @param sourceApplication the bundle ID of the app that is requesting your app to open the URL. The same sourceApplication in application:openURL:sourceApplication:annotation: */ + (BFURL *)URLWithInboundURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication; /*! Gets the target URL. If the link is an App Link, this is the target of the App Link. Otherwise, it is the url that created the target. */ @property (nonatomic, strong, readonly) NSURL *targetURL; /*! Gets the query parameters for the target, parsed into an NSDictionary. */ @property (nonatomic, strong, readonly) NSDictionary *targetQueryParameters; /*! If this link target is an App Link, this is the data found in al_applink_data. Otherwise, it is nil. */ @property (nonatomic, strong, readonly) NSDictionary *appLinkData; /*! If this link target is an App Link, this is the data found in extras. */ @property (nonatomic, strong, readonly) NSDictionary *appLinkExtras; /*! The App Link indicating how to navigate back to the referer app, if any. */ @property (nonatomic, strong, readonly) BFAppLink *appLinkReferer; /*! The URL that was used to create this BFURL. */ @property (nonatomic, strong, readonly) NSURL *inputURL; /*! The query parameters of the inputURL, parsed into an NSDictionary. */ @property (nonatomic, strong, readonly) NSDictionary *inputQueryParameters; @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFURL.m ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "BFURL_Internal.h" #import "BFAppLink_Internal.h" #import "BFAppLinkTarget.h" #import "BFMeasurementEvent_Internal.h" @implementation BFURL - (instancetype)initWithURL:(NSURL *)url forOpenInboundURL:(BOOL)forOpenURLEvent sourceApplication:(NSString *)sourceApplication forRenderBackToReferrerBar:(BOOL)forRenderBackToReferrerBar { self = [super init]; if (!self) return nil; _inputURL = url; _targetURL = url; // Parse the query string parameters for the base URL NSDictionary *baseQuery = [BFURL queryParametersForURL:url]; _inputQueryParameters = baseQuery; _targetQueryParameters = baseQuery; // Check for applink_data NSString *appLinkDataString = baseQuery[BFAppLinkDataParameterName]; if (appLinkDataString) { // Try to parse the JSON NSError *error = nil; NSDictionary *applinkData = [NSJSONSerialization JSONObjectWithData:[appLinkDataString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&error]; if (!error && [applinkData isKindOfClass:[NSDictionary class]]) { // If the version is not specified, assume it is 1. NSString *version = applinkData[BFAppLinkVersionKeyName] ?: @"1.0"; NSString *target = applinkData[BFAppLinkTargetKeyName]; if ([version isKindOfClass:[NSString class]] && [version isEqual:BFAppLinkVersion]) { // There's applink data! The target should actually be the applink target. _appLinkData = applinkData; id applinkExtras = applinkData[BFAppLinkExtrasKeyName]; if (applinkExtras && [applinkExtras isKindOfClass:[NSDictionary class]]) { _appLinkExtras = applinkExtras; } _targetURL = ([target isKindOfClass:[NSString class]] ? [NSURL URLWithString:target] : url); _targetQueryParameters = [BFURL queryParametersForURL:_targetURL]; NSDictionary *refererAppLink = _appLinkData[BFAppLinkRefererAppLink]; NSString *refererURLString = refererAppLink[BFAppLinkRefererUrl]; NSString *refererAppName = refererAppLink[BFAppLinkRefererAppName]; if (refererURLString && refererAppName) { BFAppLinkTarget *appLinkTarget = [BFAppLinkTarget appLinkTargetWithURL:[NSURL URLWithString:refererURLString] appStoreId:nil appName:refererAppName]; _appLinkReferer = [BFAppLink appLinkWithSourceURL:[NSURL URLWithString:refererURLString] targets:@[ appLinkTarget ] webURL:nil isBackToReferrer:YES]; } // Raise Measurement Event NSString *const EVENT_YES_VAL = @"1"; NSString *const EVENT_NO_VAL = @"0"; NSMutableDictionary *logData = [[NSMutableDictionary alloc] init]; logData[@"version"] = version; if (refererURLString) { logData[@"refererURL"] = refererURLString; } if (refererAppName) { logData[@"refererAppName"] = refererAppName; } if (sourceApplication) { logData[@"sourceApplication"] = sourceApplication; } if ([_targetURL absoluteString]) { logData[@"targetURL"] = [_targetURL absoluteString]; } if ([_inputURL absoluteString]) { logData[@"inputURL"] = [_inputURL absoluteString]; } if ([_inputURL scheme]) { logData[@"inputURLScheme"] = [_inputURL scheme]; } logData[@"forRenderBackToReferrerBar"] = forRenderBackToReferrerBar ? EVENT_YES_VAL : EVENT_NO_VAL; logData[@"forOpenUrl"] = forOpenURLEvent ? EVENT_YES_VAL : EVENT_NO_VAL; [BFMeasurementEvent postNotificationForEventName:BFAppLinkParseEventName args:logData]; if (forOpenURLEvent) { [BFMeasurementEvent postNotificationForEventName:BFAppLinkNavigateInEventName args:logData]; } } } } return self; } + (BFURL *)URLWithURL:(NSURL *)url { return [[BFURL alloc] initWithURL:url forOpenInboundURL:NO sourceApplication:nil forRenderBackToReferrerBar:NO]; } + (BFURL *)URLWithInboundURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication { return [[BFURL alloc] initWithURL:url forOpenInboundURL:YES sourceApplication:sourceApplication forRenderBackToReferrerBar:NO]; } + (BFURL *)URLForRenderBackToReferrerBarURL:(NSURL *)url { return [[BFURL alloc] initWithURL:url forOpenInboundURL:NO sourceApplication:nil forRenderBackToReferrerBar:YES]; } + (NSString *)decodeURLString:(NSString *)string { return (NSString *)CFBridgingRelease(CFURLCreateStringByReplacingPercentEscapes(NULL, (CFStringRef)string, CFSTR(""))); } + (NSDictionary *)queryParametersForURL:(NSURL *)url { NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; NSString *query = url.query; if ([query isEqualToString:@""]) { return @{}; } NSArray *queryComponents = [query componentsSeparatedByString:@"&"]; for (NSString *component in queryComponents) { NSRange equalsLocation = [component rangeOfString:@"="]; if (equalsLocation.location == NSNotFound) { // There's no equals, so associate the key with NSNull parameters[[self decodeURLString:component]] = [NSNull null]; } else { NSString *key = [self decodeURLString:[component substringToIndex:equalsLocation.location]]; NSString *value = [self decodeURLString:[component substringFromIndex:equalsLocation.location + 1]]; parameters[key] = value; } } return [NSDictionary dictionaryWithDictionary:parameters]; } @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFWebViewAppLinkResolver.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import #import /*! A reference implementation for an App Link resolver that uses a hidden UIWebView to parse the HTML containing App Link metadata. */ @interface BFWebViewAppLinkResolver : NSObject /*! Gets the instance of a BFWebViewAppLinkResolver. */ + (instancetype)sharedInstance; @end ================================================ FILE: Pods/Bolts/Bolts/iOS/BFWebViewAppLinkResolver.m ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import #import "BFWebViewAppLinkResolver.h" #import "BFAppLink.h" #import "BFAppLinkTarget.h" #import "BFTask.h" #import "BFTaskCompletionSource.h" #import "BFExecutor.h" // Defines JavaScript to extract app link tags from HTML content static NSString *const BFWebViewAppLinkResolverTagExtractionJavaScript = @"" "(function() {" " var metaTags = document.getElementsByTagName('meta');" " var results = [];" " for (var i = 0; i < metaTags.length; i++) {" " var property = metaTags[i].getAttribute('property');" " if (property && property.substring(0, 'al:'.length) === 'al:') {" " var tag = { \"property\": metaTags[i].getAttribute('property') };" " if (metaTags[i].hasAttribute('content')) {" " tag['content'] = metaTags[i].getAttribute('content');" " }" " results.push(tag);" " }" " }" " return JSON.stringify(results);" "})()"; static NSString *const BFWebViewAppLinkResolverIOSURLKey = @"url"; static NSString *const BFWebViewAppLinkResolverIOSAppStoreIdKey = @"app_store_id"; static NSString *const BFWebViewAppLinkResolverIOSAppNameKey = @"app_name"; static NSString *const BFWebViewAppLinkResolverDictionaryValueKey = @"_value"; static NSString *const BFWebViewAppLinkResolverPreferHeader = @"Prefer-Html-Meta-Tags"; static NSString *const BFWebViewAppLinkResolverMetaTagPrefix = @"al"; static NSString *const BFWebViewAppLinkResolverWebKey = @"web"; static NSString *const BFWebViewAppLinkResolverIOSKey = @"ios"; static NSString *const BFWebViewAppLinkResolverIPhoneKey = @"iphone"; static NSString *const BFWebViewAppLinkResolverIPadKey = @"ipad"; static NSString *const BFWebViewAppLinkResolverWebURLKey = @"url"; static NSString *const BFWebViewAppLinkResolverShouldFallbackKey = @"should_fallback"; @interface BFWebViewAppLinkResolverWebViewDelegate : NSObject @property (nonatomic, copy) void (^didFinishLoad)(UIWebView *webView); @property (nonatomic, copy) void (^didFailLoadWithError)(UIWebView *webView, NSError *error); @property (nonatomic, assign) BOOL hasLoaded; @end @implementation BFWebViewAppLinkResolverWebViewDelegate - (void)webViewDidFinishLoad:(UIWebView *)webView { if (self.didFinishLoad) { self.didFinishLoad(webView); } } - (void)webViewDidStartLoad:(UIWebView *)webView { } - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { if (self.didFailLoadWithError) { self.didFailLoadWithError(webView, error); } } - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { if (self.hasLoaded) { // Consider loading a second resource to be "success", since it indicates an inner frame // or redirect is happening. We can run the tag extraction script at this point. self.didFinishLoad(webView); return NO; } self.hasLoaded = YES; return YES; } @end @implementation BFWebViewAppLinkResolver + (instancetype)sharedInstance { static id instance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[self alloc] init]; }); return instance; } - (BFTask *)followRedirects:(NSURL *)url { // This task will be resolved with either the redirect NSURL // or a dictionary with the response data to be returned. BFTaskCompletionSource *tcs = [BFTaskCompletionSource taskCompletionSource]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request setValue:BFWebViewAppLinkResolverMetaTagPrefix forHTTPHeaderField:BFWebViewAppLinkResolverPreferHeader]; void (^completion)(NSURLResponse *response, NSData *data, NSError *error) = ^(NSURLResponse *response, NSData *data, NSError *error) { if (error) { [tcs setError:error]; return; } if ([response isKindOfClass:[NSHTTPURLResponse class]]) { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; // NSURLConnection usually follows redirects automatically, but the // documentation is unclear what the default is. This helps it along. if (httpResponse.statusCode >= 300 && httpResponse.statusCode < 400) { NSString *redirectString = httpResponse.allHeaderFields[@"Location"]; NSURL *redirectURL = [NSURL URLWithString:redirectString]; [tcs setResult:redirectURL]; return; } } [tcs setResult:@{ @"response" : response, @"data" : data }]; }; #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0 || __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_9 NSURLSession *session = [NSURLSession sharedSession]; [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { completion(response, data, error); }] resume]; #else [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:completion]; #endif return [tcs.task continueWithSuccessBlock:^id(BFTask *task) { // If we redirected, just keep recursing. if ([task.result isKindOfClass:[NSURL class]]) { return [self followRedirects:task.result]; } return task; }]; } - (BFTask *)appLinkFromURLInBackground:(NSURL *)url { return [[self followRedirects:url] continueWithExecutor:[BFExecutor mainThreadExecutor] withSuccessBlock:^id(BFTask *task) { NSData *responseData = task.result[@"data"]; NSHTTPURLResponse *response = task.result[@"response"]; BFTaskCompletionSource *tcs = [BFTaskCompletionSource taskCompletionSource]; UIWebView *webView = [[UIWebView alloc] init]; BFWebViewAppLinkResolverWebViewDelegate *listener = [[BFWebViewAppLinkResolverWebViewDelegate alloc] init]; __block BFWebViewAppLinkResolverWebViewDelegate *retainedListener = listener; listener.didFinishLoad = ^(UIWebView *view) { if (retainedListener) { NSDictionary *ogData = [self getALDataFromLoadedPage:view]; [view removeFromSuperview]; view.delegate = nil; retainedListener = nil; [tcs setResult:[self appLinkFromALData:ogData destination:url]]; } }; listener.didFailLoadWithError = ^(UIWebView* view, NSError *error) { if (retainedListener) { [view removeFromSuperview]; view.delegate = nil; retainedListener = nil; [tcs setError:error]; } }; webView.delegate = listener; webView.hidden = YES; [webView loadData:responseData MIMEType:response.MIMEType textEncodingName:response.textEncodingName baseURL:response.URL]; UIWindow *window = [UIApplication sharedApplication].windows.firstObject; [window addSubview:webView]; return tcs.task; }]; } /* Builds up a data structure filled with the app link data from the meta tags on a page. The structure of this object is a dictionary where each key holds an array of app link data dictionaries. Values are stored in a key called "_value". */ - (NSDictionary *)parseALData:(NSArray *)dataArray { NSMutableDictionary *al = [NSMutableDictionary dictionary]; for (NSDictionary *tag in dataArray) { NSString *name = tag[@"property"]; if (![name isKindOfClass:[NSString class]]) { continue; } NSArray *nameComponents = [name componentsSeparatedByString:@":"]; if (![nameComponents[0] isEqualToString:BFWebViewAppLinkResolverMetaTagPrefix]) { continue; } NSMutableDictionary *root = al; for (int i = 1; i < nameComponents.count; i++) { NSMutableArray *children = root[nameComponents[i]]; if (!children) { children = [NSMutableArray array]; root[nameComponents[i]] = children; } NSMutableDictionary *child = children.lastObject; if (!child || i == nameComponents.count - 1) { child = [NSMutableDictionary dictionary]; [children addObject:child]; } root = child; } if (tag[@"content"]) { root[BFWebViewAppLinkResolverDictionaryValueKey] = tag[@"content"]; } } return al; } - (NSDictionary *)getALDataFromLoadedPage:(UIWebView *)webView { // Run some JavaScript in the webview to fetch the meta tags. NSString *jsonString = [webView stringByEvaluatingJavaScriptFromString:BFWebViewAppLinkResolverTagExtractionJavaScript]; NSError *error = nil; NSArray *arr = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&error]; return [self parseALData:arr]; } /* Converts app link data into a BFAppLink containing the targets relevant for this platform. */ - (BFAppLink *)appLinkFromALData:(NSDictionary *)appLinkDict destination:(NSURL *)destination { NSMutableArray *linkTargets = [NSMutableArray array]; NSArray *platformData = nil; switch (UI_USER_INTERFACE_IDIOM()) { case UIUserInterfaceIdiomPad: platformData = @[ appLinkDict[BFWebViewAppLinkResolverIPadKey] ?: @{}, appLinkDict[BFWebViewAppLinkResolverIOSKey] ?: @{} ]; break; case UIUserInterfaceIdiomPhone: platformData = @[ appLinkDict[BFWebViewAppLinkResolverIPhoneKey] ?: @{}, appLinkDict[BFWebViewAppLinkResolverIOSKey] ?: @{} ]; break; #ifdef __TVOS_9_0 case UIUserInterfaceIdiomTV: #endif #ifdef __IPHONE_9_3 case UIUserInterfaceIdiomCarPlay: #endif case UIUserInterfaceIdiomUnspecified: default: // Future-proofing. Other User Interface idioms should only hit ios. platformData = @[ appLinkDict[BFWebViewAppLinkResolverIOSKey] ?: @{} ]; break; } for (NSArray *platformObjects in platformData) { for (NSDictionary *platformDict in platformObjects) { // The schema requires a single url/app store id/app name, // but we could find multiple of them. We'll make a best effort // to interpret this data. NSArray *urls = platformDict[BFWebViewAppLinkResolverIOSURLKey]; NSArray *appStoreIds = platformDict[BFWebViewAppLinkResolverIOSAppStoreIdKey]; NSArray *appNames = platformDict[BFWebViewAppLinkResolverIOSAppNameKey]; NSUInteger maxCount = MAX(urls.count, MAX(appStoreIds.count, appNames.count)); for (NSUInteger i = 0; i < maxCount; i++) { NSString *urlString = urls[i][BFWebViewAppLinkResolverDictionaryValueKey]; NSURL *url = urlString ? [NSURL URLWithString:urlString] : nil; NSString *appStoreId = appStoreIds[i][BFWebViewAppLinkResolverDictionaryValueKey]; NSString *appName = appNames[i][BFWebViewAppLinkResolverDictionaryValueKey]; BFAppLinkTarget *target = [BFAppLinkTarget appLinkTargetWithURL:url appStoreId:appStoreId appName:appName]; [linkTargets addObject:target]; } } } NSDictionary *webDict = appLinkDict[BFWebViewAppLinkResolverWebKey][0]; NSString *webUrlString = webDict[BFWebViewAppLinkResolverWebURLKey][0][BFWebViewAppLinkResolverDictionaryValueKey]; NSString *shouldFallbackString = webDict[BFWebViewAppLinkResolverShouldFallbackKey][0][BFWebViewAppLinkResolverDictionaryValueKey]; NSURL *webUrl = destination; if (shouldFallbackString && [@[ @"no", @"false", @"0" ] containsObject:[shouldFallbackString lowercaseString]]) { webUrl = nil; } if (webUrl && webUrlString) { webUrl = [NSURL URLWithString:webUrlString]; } return [BFAppLink appLinkWithSourceURL:destination targets:linkTargets webURL:webUrl]; } @end ================================================ FILE: Pods/Bolts/Bolts/iOS/Internal/BFAppLinkReturnToRefererView_Internal.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import @interface BFAppLinkReturnToRefererView (Internal) - (CGFloat)statusBarHeight; @end ================================================ FILE: Pods/Bolts/Bolts/iOS/Internal/BFAppLink_Internal.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import FOUNDATION_EXPORT NSString *const BFAppLinkDataParameterName; FOUNDATION_EXPORT NSString *const BFAppLinkTargetKeyName; FOUNDATION_EXPORT NSString *const BFAppLinkUserAgentKeyName; FOUNDATION_EXPORT NSString *const BFAppLinkExtrasKeyName; FOUNDATION_EXPORT NSString *const BFAppLinkVersionKeyName; FOUNDATION_EXPORT NSString *const BFAppLinkRefererAppLink; FOUNDATION_EXPORT NSString *const BFAppLinkRefererAppName; FOUNDATION_EXPORT NSString *const BFAppLinkRefererUrl; @interface BFAppLink (Internal) + (instancetype)appLinkWithSourceURL:(NSURL *)sourceURL targets:(NSArray *)targets webURL:(NSURL *)webURL isBackToReferrer:(BOOL)isBackToReferrer; /*! return if this AppLink is to go back to referrer. */ @property (nonatomic, assign, readonly, getter=isBackToReferrer) BOOL backToReferrer; @end ================================================ FILE: Pods/Bolts/Bolts/iOS/Internal/BFMeasurementEvent_Internal.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import /*! Provides methods for posting notifications from the Bolts framework */ @interface BFMeasurementEvent (Internal) + (void)postNotificationForEventName:(NSString *)name args:(NSDictionary *)args; @end ================================================ FILE: Pods/Bolts/Bolts/iOS/Internal/BFURL_Internal.h ================================================ /* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import @interface BFURL (Internal) + (BFURL *)URLForRenderBackToReferrerBarURL:(NSURL *)url; @end ================================================ FILE: Pods/Bolts/LICENSE ================================================ BSD License For Bolts software Copyright (c) 2013-present, Facebook, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name Facebook nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: Pods/Bolts/README.md ================================================ Bolts ============ [![Build Status](https://img.shields.io/travis/BoltsFramework/Bolts-ObjC/master.svg?style=flat)](https://travis-ci.org/BoltsFramework/Bolts-ObjC) [![Coverage Status](https://codecov.io/github/BoltsFramework/Bolts-ObjC/coverage.svg?branch=master)](https://codecov.io/github/BoltsFramework/Bolts-ObjC?branch=master) [![Pod Platform](https://img.shields.io/cocoapods/p/Bolts.svg?style=flat)](https://cocoapods.org/pods/Bolts) [![Pod License](https://img.shields.io/cocoapods/l/Bolts.svg?style=flat)](https://github.com/BoltsFramework/Bolts-ObjC/blob/master/LICENSE) [![Reference Status](https://www.versioneye.com/objective-c/bolts/reference_badge.svg?style=flat)](https://www.versioneye.com/objective-c/bolts/references) [![Pod Version](https://img.shields.io/cocoapods/v/Bolts.svg?style=flat)](https://cocoapods.org/pods/Bolts) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) Bolts is a collection of low-level libraries designed to make developing mobile apps easier. Bolts was designed by Parse and Facebook for our own internal use, and we have decided to open source these libraries to make them available to others. Using these libraries does not require using any Parse services. Nor do they require having a Parse or Facebook developer account. Bolts includes: * "Tasks", which make organization of complex asynchronous code more manageable. A task is kind of like a JavaScript Promise, but available for iOS and Android. * An implementation of the [App Links protocol](http://applinks.org/), helping you link to content in other apps and handle incoming deep-links. For more information, see the [Bolts iOS API Reference](http://boltsframework.github.io/docs/ios/). # Tasks To build a truly responsive iOS application, you must keep long-running operations off of the UI thread, and be careful to avoid blocking anything the UI thread might be waiting on. This means you will need to execute various operations in the background. To make this easier, we've added a class called `BFTask`. A task represents the result of an asynchronous operation. Typically, a `BFTask` is returned from an asynchronous function and gives the ability to continue processing the result of the task. When a task is returned from a function, it's already begun doing its job. A task is not tied to a particular threading model: it represents the work being done, not where it is executing. Tasks have many advantages over other methods of asynchronous programming, such as callbacks. `BFTask` is not a replacement for `NSOperation` or GCD. In fact, they play well together. But tasks do fill in some gaps that those technologies don't address. * `BFTask` takes care of managing dependencies for you. Unlike using `NSOperation` for dependency management, you don't have to declare all dependencies before starting a `BFTask`. For example, imagine you need to save a set of objects and each one may or may not require saving child objects. With an `NSOperation`, you would normally have to create operations for each of the child saves ahead of time. But you don't always know before you start the work whether that's going to be necessary. That can make managing dependencies with `NSOperation` very painful. Even in the best case, you have to create your dependencies before the operations that depend on them, which results in code that appears in a different order than it executes. With `BFTask`, you can decide during your operation's work whether there will be subtasks and return the other task in just those cases. * `BFTasks` release their dependencies. `NSOperation` strongly retains its dependencies, so if you have a queue of ordered operations and sequence them using dependencies, you have a leak, because every operation gets retained forever. `BFTasks` release their callbacks as soon as they are run, so everything cleans up after itself. This can reduce memory use, and simplify memory management. * `BFTasks` keep track of the state of finished tasks: It tracks whether there was a returned value, the task was cancelled, or if an error occurred. It also has convenience methods for propagating errors. With `NSOperation`, you have to build all of this stuff yourself. * `BFTasks` don't depend on any particular threading model. So it's easy to have some tasks perform their work with an operation queue, while others perform work using blocks with GCD. These tasks can depend on each other seamlessly. * Performing several tasks in a row will not create nested "pyramid" code as you would get when using only callbacks. * `BFTasks` are fully composable, allowing you to perform branching, parallelism, and complex error handling, without the spaghetti code of having many named callbacks. * You can arrange task-based code in the order that it executes, rather than having to split your logic across scattered callback functions. For the examples in this doc, assume there are async versions of some common Parse methods, called `saveAsync:` and `findAsync:` which return a `Task`. In a later section, we'll show how to define these functions yourself. ## The `continueWithBlock` Method Every `BFTask` has a method named `continueWithBlock:` which takes a continuation block. A continuation is a block that will be executed when the task is complete. You can then inspect the task to check if it was successful and to get its result. ```objective-c // Objective-C [[self saveAsync:obj] continueWithBlock:^id(BFTask *task) { if (task.isCancelled) { // the save was cancelled. } else if (task.error) { // the save failed. } else { // the object was saved successfully. PFObject *object = task.result; } return nil; }]; ``` ```swift // Swift self.saveAsync(obj).continueWithBlock { (task: BFTask!) -> BFTask in if task.isCancelled() { // the save was cancelled. } else if task.error != nil { // the save failed. } else { // the object was saved successfully. var object = task.result() as PFObject } } ``` BFTasks use Objective-C blocks, so the syntax should be pretty straightforward. Let's look closer at the types involved with an example. ```objective-c // Objective-C /** * Gets an NSString asynchronously. */ - (BFTask *)getStringAsync { // Let's suppose getNumberAsync returns a BFTask whose result is an NSNumber. return [[self getNumberAsync] continueWithBlock:^id(BFTask *task) { // This continuation block takes the NSNumber BFTask as input, // and provides an NSString as output. NSNumber *number = task.result; return [NSString stringWithFormat:@"%@", number]; )]; } ``` ```swift // Swift /** * Gets an NSString asynchronously. */ func getStringAsync() -> BFTask { //Let's suppose getNumberAsync returns a BFTask whose result is an NSNumber. return self.getNumberAsync().continueWithBlock { (task: BFTask!) -> NSString in // This continuation block takes the NSNumber BFTask as input, // and provides an NSString as output. let number = task.result() as NSNumber return NSString(format:"%@", number) } } ``` In many cases, you only want to do more work if the previous task was successful, and propagate any errors or cancellations to be dealt with later. To do this, use the `continueWithSuccessBlock:` method instead of `continueWithBlock:`. ```objective-c // Objective-C [[self saveAsync:obj] continueWithSuccessBlock:^id(BFTask *task) { // the object was saved successfully. return nil; }]; ``` ```swift // Swift self.saveAsync(obj).continueWithSuccessBlock { (task: BFTask!) -> AnyObject! in // the object was saved successfully. return nil } ``` ## Chaining Tasks Together BFTasks are a little bit magical, in that they let you chain them without nesting. If you return a BFTask from `continueWithBlock:`, then the task returned by `continueWithBlock:` will not be considered finished until the new task returned from the new continuation block. This lets you perform multiple actions without incurring the pyramid code you would get with callbacks. Likewise, you can return a `BFTask` from `continueWithSuccessBlock:`. So, return a `BFTask` to do more asynchronous work. ```objective-c // Objective-C PFQuery *query = [PFQuery queryWithClassName:@"Student"]; [query orderByDescending:@"gpa"]; [[[[[self findAsync:query] continueWithSuccessBlock:^id(BFTask *task) { NSArray *students = task.result; PFObject *valedictorian = [students objectAtIndex:0]; [valedictorian setObject:@YES forKey:@"valedictorian"]; return [self saveAsync:valedictorian]; }] continueWithSuccessBlock:^id(BFTask *task) { PFObject *valedictorian = task.result; return [self findAsync:query]; }] continueWithSuccessBlock:^id(BFTask *task) { NSArray *students = task.result; PFObject *salutatorian = [students objectAtIndex:1]; [salutatorian setObject:@YES forKey:@"salutatorian"]; return [self saveAsync:salutatorian]; }] continueWithSuccessBlock:^id(BFTask *task) { // Everything is done! return nil; }]; ``` ```swift // Swift var query = PFQuery(className:"Student") query.orderByDescending("gpa") findAsync(query).continueWithSuccessBlock { (task: BFTask!) -> BFTask in let students = task.result() as NSArray var valedictorian = students.objectAtIndex(0) as PFObject valedictorian["valedictorian"] = true return self.saveAsync(valedictorian) }.continueWithSuccessBlock { (task: BFTask!) -> BFTask in var valedictorian = task.result() as PFObject return self.findAsync(query) }.continueWithSuccessBlock { (task: BFTask!) -> BFTask in let students = task.result() as NSArray var salutatorian = students.objectAtIndex(1) as PFObject salutatorian["salutatorian"] = true return self.saveAsync(salutatorian) }.continueWithSuccessBlock { (task: BFTask!) -> AnyObject! in // Everything is done! return nil } ``` ## Error Handling By carefully choosing whether to call `continueWithBlock:` or `continueWithSuccessBlock:`, you can control how errors are propagated in your application. Using `continueWithBlock:` lets you handle errors by transforming them or dealing with them. You can think of failed tasks kind of like throwing an exception. In fact, if you throw an exception inside a continuation, the resulting task will be faulted with that exception. ```objective-c // Objective-C PFQuery *query = [PFQuery queryWithClassName:@"Student"]; [query orderByDescending:@"gpa"]; [[[[[self findAsync:query] continueWithSuccessBlock:^id(BFTask *task) { NSArray *students = task.result; PFObject *valedictorian = [students objectAtIndex:0]; [valedictorian setObject:@YES forKey:@"valedictorian"]; // Force this callback to fail. return [BFTask taskWithError:[NSError errorWithDomain:@"example.com" code:-1 userInfo:nil]]; }] continueWithSuccessBlock:^id(BFTask *task) { // Now this continuation will be skipped. PFQuery *valedictorian = task.result; return [self findAsync:query]; }] continueWithBlock:^id(BFTask *task) { if (task.error) { // This error handler WILL be called. // The error will be the NSError returned above. // Let's handle the error by returning a new value. // The task will be completed with nil as its value. return nil; } // This will also be skipped. NSArray *students = task.result; PFObject *salutatorian = [students objectAtIndex:1]; [salutatorian setObject:@YES forKey:@"salutatorian"]; return [self saveAsync:salutatorian]; }] continueWithSuccessBlock:^id(BFTask *task) { // Everything is done! This gets called. // The task's result is nil. return nil; }]; ``` ```swift // Swift var query = PFQuery(className:"Student") query.orderByDescending("gpa") findAsync(query).continueWithSuccessBlock { (task: BFTask!) -> BFTask in let students = task.result() as NSArray var valedictorian = students.objectAtIndex(0) as PFObject valedictorian["valedictorian"] = true //Force this callback to fail. return BFTask(error:NSError(domain:"example.com", code:-1, userInfo: nil)) }.continueWithSuccessBlock { (task: BFTask!) -> AnyObject! in //Now this continuation will be skipped. var valedictorian = task.result() as PFObject return self.findAsync(query) }.continueWithBlock { (task: BFTask!) -> AnyObject! in if task.error != nil { // This error handler WILL be called. // The error will be the NSError returned above. // Let's handle the error by returning a new value. // The task will be completed with nil as its value. return nil } // This will also be skipped. let students = task.result() as NSArray var salutatorian = students.objectAtIndex(1) as PFObject salutatorian["salutatorian"] = true return self.saveAsync(salutatorian) }.continueWithSuccessBlock { (task: BFTask!) -> AnyObject! in // Everything is done! This gets called. // The tasks result is nil. return nil } ``` It's often convenient to have a long chain of success callbacks with only one error handler at the end. ## Creating Tasks When you're getting started, you can just use the tasks returned from methods like `findAsync:` or `saveAsync:`. However, for more advanced scenarios, you may want to make your own tasks. To do that, you create a `BFTaskCompletionSource`. This object will let you create a new `BFTask`, and control whether it gets marked as finished or cancelled. After you create a `BFTaskCompletionSource`, you'll need to call `setResult:`, `setError:`, or `cancel` to trigger its continuations. ```objective-c // Objective-C - (BFTask *)successAsync { BFTaskCompletionSource *successful = [BFTaskCompletionSource taskCompletionSource]; [successful setResult:@"The good result."]; return successful.task; } - (BFTask *)failAsync { BFTaskCompletionSource *failed = [BFTaskCompletionSource taskCompletionSource]; [failed setError:[NSError errorWithDomain:@"example.com" code:-1 userInfo:nil]]; return failed.task; } ``` ```swift // Swift func successAsync() -> BFTask { var successful = BFTaskCompletionSource() successful.setResult("The good result.") return successful.task } func failAsync() -> BFTask { var failed = BFTaskCompletionSource() failed.setError(NSError(domain:"example.com", code:-1, userInfo:nil)) return failed.task } ``` If you know the result of a task at the time it is created, there are some convenience methods you can use. ```objective-c // Objective-C BFTask *successful = [BFTask taskWithResult:@"The good result."]; BFTask *failed = [BFTask taskWithError:anError]; ``` ```swift // Swift let successful = BFTask(result:"The good result") let failed = BFTask(error:anError) ``` ## Creating Async Methods With these tools, it's easy to make your own asynchronous functions that return tasks. For example, you can make a task-based version of `fetchAsync:` easily. ```objective-c // Objective-C - (BFTask *) fetchAsync:(PFObject *)object { BFTaskCompletionSource *task = [BFTaskCompletionSource taskCompletionSource]; [object fetchInBackgroundWithBlock:^(PFObject *object, NSError *error) { if (!error) { [task setResult:object]; } else { [task setError:error]; } }]; return task.task; } ``` ```swift // Swift func fetchAsync(object: PFObject) -> BFTask { var task = BFTaskCompletionSource() object.fetchInBackgroundWithBlock { (object: PFObject?, error: NSError?) -> Void in if error == nil { task.setResult(object) } else { task.setError(error) } } return task.task } ``` It's similarly easy to create `saveAsync:`, `findAsync:` or `deleteAsync:`. ## Tasks in Series `BFTasks` are convenient when you want to do a series of tasks in a row, each one waiting for the previous to finish. For example, imagine you want to delete all of the comments on your blog. ```objective-c // Objective-C PFQuery *query = [PFQuery queryWithClassName:@"Comments"]; [query whereKey:@"post" equalTo:@123]; [[[self findAsync:query] continueWithBlock:^id(BFTask *task) { NSArray *results = task.result; // Create a trivial completed task as a base case. BFTask *task = [BFTask taskWithResult:nil]; for (PFObject *result in results) { // For each item, extend the task with a function to delete the item. task = [task continueWithBlock:^id(BFTask *task) { // Return a task that will be marked as completed when the delete is finished. return [self deleteAsync:result]; }]; } return task; }] continueWithBlock:^id(BFTask *task) { // Every comment was deleted. return nil; }]; ``` ```swift // Swift var query = PFQuery(className:"Comments") query.whereKey("post", equalTo:123) findAsync(query).continueWithBlock { (task: BFTask!) -> BFTask in let results = task.result() as NSArray // Create a trivial completed task as a base case. let task = BFTask(result:nil) for result : PFObject in results { // For each item, extend the task with a function to delete the item. task = task.continueWithBlock { (task: BFTask!) -> BFTask in return self.deleteAsync(result) } } return task }.continueWithBlock { (task: BFTask!) -> AnyObject! in // Every comment was deleted. return nil } ``` ## Tasks in Parallel You can also perform several tasks in parallel, using the `taskForCompletionOfAllTasks:` method. You can start multiple operations at once, and use `taskForCompletionOfAllTasks:` to create a new task that will be marked as completed when all of its input tasks are completed. The new task will be successful only if all of the passed-in tasks succeed. Performing operations in parallel will be faster than doing them serially, but may consume more system resources and bandwidth. ```objective-c // Objective-C PFQuery *query = [PFQuery queryWithClassName:@"Comments"]; [query whereKey:@"post" equalTo:@123]; [[[self findAsync:query] continueWithBlock:^id(BFTask *results) { // Collect one task for each delete into an array. NSMutableArray *tasks = [NSMutableArray array]; for (PFObject *result in results) { // Start this delete immediately and add its task to the list. [tasks addObject:[self deleteAsync:result]]; } // Return a new task that will be marked as completed when all of the deletes are // finished. return [BFTask taskForCompletionOfAllTasks:tasks]; }] continueWithBlock:^id(BFTask *task) { // Every comment was deleted. return nil; }]; ``` ```swift // Swift var query = PFQuery(className:"Comments") query.whereKey("post", equalTo:123) findAsync(query).continueWithBlock { (task: BFTask!) -> BFTask in // Collect one task for each delete into an array. var tasks = NSMutableArray.array() var results = task.result() as NSArray for result : PFObject! in results { // Start this delete immediately and add its task to the list. tasks.addObject(self.deleteAsync(result)) } // Return a new task that will be marked as completed when all of the deletes // are finished. return BFTask(forCompletionOfAllTasks:tasks) }.continueWithBlock { (task: BFTask!) -> AnyObject! in // Every comment was deleted. return nil } ``` ## Task Executors Both `continueWithBlock:` and `continueWithSuccessBlock:` methods have another form that takes an instance of `BFExecutor`. These are `continueWithExecutor:withBlock:` and `continueWithExecutor:withSuccessBlock:`. These methods allow you to control how the continuation is executed. The default executor will dispatch to GCD, but you can provide your own executor to schedule work onto a different thread. For example, if you want to continue with work on the UI thread: ```objective-c // Create a BFExecutor that uses the main thread. BFExecutor *myExecutor = [BFExecutor executorWithBlock:^void(void(^block)()) { dispatch_async(dispatch_get_main_queue(), block); }]; // And use the Main Thread Executor like this. The executor applies only to the new // continuation being passed into continueWithBlock. [[self fetchAsync:object] continueWithExecutor:myExecutor withBlock:^id(BFTask *task) { myTextView.text = [object objectForKey:@"name"]; }]; ``` For common cases, such as dispatching on the main thread, we have provided default implementations of `BFExecutor`. These include `defaultExecutor`, `immediateExecutor`, `mainThreadExecutor`, `executorWithDispatchQueue:`, and `executorWithOperationQueue:`. For example: ```objective-c // Continue on the Main Thread, using a built-in executor. [[self fetchAsync:object] continueWithExecutor:[BFExecutor mainThreadExecutor] withBlock:^id(BFTask *task) { myTextView.text = [object objectForKey:@"name"]; }]; ``` ## Task Cancellation It's generally bad design to keep track of the `BFTaskCompletionSource` for cancellation. A better model is to create a "cancellation token" at the top level, and pass that to each async function that you want to be part of the same "cancelable operation". Then, in your continuation blocks, you can check whether the cancellation token has been cancelled and bail out early by returning a `[BFTask cancelledTask]`. For example: ```objective-c - (void)doSomethingComplicatedAsync:(MYCancellationToken *)cancellationToken { [[self doSomethingAsync:cancellationToken] continueWithBlock:^{ if (cancellationToken.isCancelled) { return [BFTask cancelledTask]; } // Do something that takes a while. return result; }]; } // Somewhere else. MYCancellationToken *cancellationToken = [[MYCancellationToken alloc] init]; [obj doSomethingComplicatedAsync:cancellationToken]; // When you get bored... [cancellationToken cancel]; ``` **Note:** The cancellation token implementation should be thread-safe. We are likely to add some concept like this to Bolts at some point in the future. # App Links [App Links](http://applinks.org/) provide a cross-platform mechanism that allows a developer to define and publish a deep-linking scheme for their content, allowing other apps to link directly to an experience optimized for the device they are running on. Whether you are building an app that receives incoming links or one that may link out to other apps' content, Bolts provides tools to simplify implementation of the [App Links protocol](http://applinks.org/documentation). ## Handling an App Link The most common case will be making your app receive App Links. In-linking will allow your users to quickly access the richest, most native-feeling presentation of linked content on their devices. Bolts makes it easy to handle an inbound App Link (as well as general inbound deep-links) by providing utilities for processing an incoming URL. For example, you can use the `BFURL` utility class to parse an incoming URL in your `AppDelegate`: ```objective-c - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { BFURL *parsedUrl = [BFURL URLWithInboundURL:url sourceApplication:sourceApplication]; // Use the target URL from the App Link to locate content. if ([parsedUrl.targetURL.pathComponents[1] isEqualToString:@"profiles"]) { // Open a profile viewer. } // You can also check the query string easily. NSString *query = parsedUrl.targetQueryParameters[@"query"]; // Apps that have existing deep-linking support and map their App Links to existing // deep-linking functionality may instead want to perform these operations on the input URL. // Use the target URL from the App Link to locate content. if ([parsedUrl.inputURL.pathComponents[1] isEqualToString:@"profiles"]) { // Open a profile viewer. } // You can also check the query string easily. NSString *query = parsedUrl.inputQueryParameters[@"query"]; // Apps can easily check the Extras and App Link data from the App Link as well. NSString *fbAccessToken = parsedUrl.appLinkExtras[@"fb_access_token"]; NSDictionary *refererData = parsedUrl.appLinkExtras[@"referer"]; } ``` ## Navigating to a URL Following an App Link allows your app to provide the best user experience (as defined by the receiving app) when a user navigates to a link. Bolts makes this process simple, automating the steps required to follow a link: 1. Resolve the App Link by getting the App Link metadata from the HTML at the URL specified. 2. Step through App Link targets relevant to the device being used, checking whether the app that can handle the target is present on the device. 3. If an app is present, build a URL with the appropriate al_applink_data specified and navigate to that URL. 4. Otherwise, open the browser with the original URL specified. In the simplest case, it takes just one line of code to navigate to a URL that may have an App Link: ```objective-c [BFAppLinkNavigation navigateToURLInBackground:url]; ``` ### Adding App and Navigation Data Under most circumstances, the data that will need to be passed along to an app during a navigation will be contained in the URL itself, so that whether or not the app is actually installed on the device, users are taken to the correct content. Occasionally, however, apps will want to pass along data that is relevant for app-to-app navigation, or will want to augment the App Link protocol with information that might be used by the app to adjust how the app should behave (e.g. showing a link back to the referring app). If you want to take advantage of these features, you can break apart the navigation process. First, you must have an App Link to which you wish to navigate: ```objective-c [[BFAppLinkNavigation resolveAppLinkInBackground:url] continueWithSuccessBlock:^id(BFTask *task) { BFAppLink *link = task.result; }]; ``` Then, you can build an App Link request with any additional data you would like and navigate: ```objective-c BFAppLinkNavigation *navigation = [BFAppLinkNavigation navigationWithAppLink:link extras:@{ @"access_token": @"t0kEn" } appLinkData:@{ @"ref": @"12345" }]; NSError *error = nil; [navigation navigate:&error]; ``` ### Resolving App Link Metadata Bolts allows for custom App Link resolution, which may be used as a performance optimization (e.g. caching the metadata) or as a mechanism to allow developers to use a centralized index for obtaining App Link metadata. A custom App Link resolver just needs to be able to take a URL and return a `BFAppLink` containing the ordered list of `BFAppLinkTarget`s that are applicable for this device. Bolts provides one of these out of the box that performs this resolution on the device using a hidden UIWebView. You can use any resolver that implements the `BFAppLinkResolving` protocol by using one of the overloads on `BFAppLinkNavigation`: ```objective-c [BFAppLinkNavigation navigateToURLInBackground:url resolver:resolver]; ``` Alternatively, a you can swap out the default resolver to be used by the built-in APIs: ```objective-c [BFAppLinkNavigation setDefaultResolver:resolver]; [BFAppLinkNavigation navigateToURLInBackground:url]; ``` ## App Link Return-to-Referer View When an application is opened via an App Link, a banner allowing the user to "Touch to return to " should be displayed. The `BFAppLinkReturnToRefererView` provides this functionality. It will take an incoming App Link and parse the referer information to display the appropriate calling app name. ```objective-c - (void)viewDidLoad { [super viewDidLoad]; // Perform other view initialization. self.returnToRefererController = [[BFAppLinkReturnToRefererController alloc] init]; // self.returnToRefererView is a BFAppLinkReturnToRefererView. // You may initialize the view either by loading it from a NIB or programmatically. self.returnToRefererController.view = self.returnToRefererView; // If you have a UINavigationController in the view, then the bar must be shown above it. [self.returnToRefererController] } ``` The following code assumes that the view controller has an `openedAppLinkURL` `NSURL` property that has already been populated with the URL used to open the app. You can then do something like this to show the view: ```objective-c - (void)viewWillAppear { [super viewWillAppear]; // Show only if you have a back AppLink. [self.returnToRefererController showViewForRefererURL:self.openedAppLinkURL]; } ``` In a navigation-controller view hierarchy, the banner should be displayed above the navigation bar, and `BFAppLinkReturnToRefererController` provides an `initForDisplayAboveNavController` method to assist with this. ## Analytics Bolts introduces Measurement Event. App Links posts three different Measurement Event notifications to the application, which can be caught and integrated with existing analytics components in your application. * `al_nav_out` — Raised when your app switches out to an App Links URL. * `al_nav_in` — Raised when your app opens an incoming App Links URL. * `al_ref_back_out` — Raised when your app returns back the referrer app using the built-in top navigation back bar view. ### Listen for App Links Measurement Events There are other analytics tools that are integrated with Bolts' App Links events, but you can also listen for these events yourself: ```objective-c [[NSNotificationCenter defaultCenter] addObserverForName:BFMeasurementEventNotificationName object:nil queue:nil usingBlock:^(NSNotification *note) { NSDictionary *event = note.userInfo; NSDictionary *eventData = event[BFMeasurementEventArgsKey]; // Integrate to your logging/analytics component. }]; ``` ### App Links Event Fields App Links Measurement Events sends additional information from App Links Intents in flattened string key value pairs. Here are some of the useful fields for the three events. * `al_nav_in` * `inputURL`: the URL that opens the app. * `inputURLScheme`: the scheme of `inputURL`. * `refererURL`: the URL that the referrer app added into `al_applink_data`: `referer_app_link`. * `refererAppName`: the app name that the referrer app added to `al_applink_data`: `referer_app_link`. * `sourceApplication`: the bundle of referrer application. * `targetURL`: the `target_url` field in `al_applink_data`. * `version`: App Links API version. * `al_nav_out` / `al_ref_back_out` * `outputURL`: the URL used to open the other app (or browser). If there is an eligible app to open, this will be the custom scheme url/intent in `al_applink_data`. * `outputURLScheme`: the scheme of `outputURL`. * `sourceURL`: the URL of the page hosting App Links meta tags. * `sourceURLHost`: the hostname of `sourceURL`. * `success`: `“1”` to indicate success in opening the App Link in another app or browser; `“0”` to indicate failure to open the App Link. * `type`: `“app”` for open in app, `“web”` for open in browser; `“fail”` when the success field is `“0”`. * `version`: App Links API version. # Installation You can download the latest framework files from our [Releases page](https://github.com/BoltsFramework/Bolts-ObjC/releases). Bolts is also available through [CocoaPods](https://cocoapods.org/). To install it simply add the following line to your Podfile: pod 'Bolts' ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import /*! @abstract Notification indicating that the `currentAccessToken` has changed. @discussion the userInfo dictionary of the notification will contain keys `FBSDKAccessTokenChangeOldKey` and `FBSDKAccessTokenChangeNewKey`. */ FBSDK_EXTERN NSString *const FBSDKAccessTokenDidChangeNotification; /*! @abstract A key in the notification's userInfo that will be set if and only if the user ID changed between the old and new tokens. @discussion Token refreshes can occur automatically with the SDK which do not change the user. If you're only interested in user changes (such as logging out), you should check for the existence of this key. The value is a NSNumber with a boolValue. On a fresh start of the app where the SDK reads in the cached value of an access token, this key will also exist since the access token is moving from a null state (no user) to a non-null state (user). */ FBSDK_EXTERN NSString *const FBSDKAccessTokenDidChangeUserID; /* @abstract key in notification's userInfo object for getting the old token. @discussion If there was no old token, the key will not be present. */ FBSDK_EXTERN NSString *const FBSDKAccessTokenChangeOldKey; /* @abstract key in notification's userInfo object for getting the new token. @discussion If there is no new token, the key will not be present. */ FBSDK_EXTERN NSString *const FBSDKAccessTokenChangeNewKey; /*! @class FBSDKAccessToken @abstract Represents an immutable access token for using Facebook services. */ @interface FBSDKAccessToken : NSObject /*! @abstract Returns the app ID. */ @property (readonly, copy, nonatomic) NSString *appID; /*! @abstract Returns the known declined permissions. */ @property (readonly, copy, nonatomic) NSSet *declinedPermissions; /*! @abstract Returns the expiration date. */ @property (readonly, copy, nonatomic) NSDate *expirationDate; /*! @abstract Returns the known granted permissions. */ @property (readonly, copy, nonatomic) NSSet *permissions; /*! @abstract Returns the date the token was last refreshed. */ @property (readonly, copy, nonatomic) NSDate *refreshDate; /*! @abstract Returns the opaque token string. */ @property (readonly, copy, nonatomic) NSString *tokenString; /*! @abstract Returns the user ID. */ @property (readonly, copy, nonatomic) NSString *userID; - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE; /*! @abstract Initializes a new instance. @param tokenString the opaque token string. @param permissions the granted permissions. Note this is converted to NSSet and is only an NSArray for the convenience of literal syntax. @param declinedPermissions the declined permissions. Note this is converted to NSSet and is only an NSArray for the convenience of literal syntax. @param appID the app ID. @param userID the user ID. @param expirationDate the optional expiration date (defaults to distantFuture). @param refreshDate the optional date the token was last refreshed (defaults to today). @discussion This initializer should only be used for advanced apps that manage tokens explicitly. Typical login flows only need to use `FBSDKLoginManager` along with `+currentAccessToken`. */ - (instancetype)initWithTokenString:(NSString *)tokenString permissions:(NSArray *)permissions declinedPermissions:(NSArray *)declinedPermissions appID:(NSString *)appID userID:(NSString *)userID expirationDate:(NSDate *)expirationDate refreshDate:(NSDate *)refreshDate NS_DESIGNATED_INITIALIZER; /*! @abstract Convenience getter to determine if a permission has been granted @param permission The permission to check. */ - (BOOL)hasGranted:(NSString *)permission; /*! @abstract Compares the receiver to another FBSDKAccessToken @param token The other token @return YES if the receiver's values are equal to the other token's values; otherwise NO */ - (BOOL)isEqualToAccessToken:(FBSDKAccessToken *)token; /*! @abstract Returns the "global" access token that represents the currently logged in user. @discussion The `currentAccessToken` is a convenient representation of the token of the current user and is used by other SDK components (like `FBSDKLoginManager`). */ + (FBSDKAccessToken *)currentAccessToken; /*! @abstract Sets the "global" access token that represents the currently logged in user. @param token The access token to set. @discussion This will broadcast a notification and save the token to the app keychain. */ + (void)setCurrentAccessToken:(FBSDKAccessToken *)token; /*! @abstract Refresh the current access token's permission state and extend the token's expiration date, if possible. @param completionHandler an optional callback handler that can surface any errors related to permission refreshing. @discussion On a successful refresh, the currentAccessToken will be updated so you typically only need to observe the `FBSDKAccessTokenDidChangeNotification` notification. If a token is already expired, it cannot be refreshed. */ + (void)refreshCurrentAccessToken:(FBSDKGraphRequestHandler)completionHandler; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAccessToken.h" #import "FBSDKGraphRequestPiggybackManager.h" #import "FBSDKInternalUtility.h" #import "FBSDKMath.h" #import "FBSDKSettings+Internal.h" NSString *const FBSDKAccessTokenDidChangeNotification = @"com.facebook.sdk.FBSDKAccessTokenData.FBSDKAccessTokenDidChangeNotification"; NSString *const FBSDKAccessTokenDidChangeUserID = @"FBSDKAccessTokenDidChangeUserID"; NSString *const FBSDKAccessTokenChangeNewKey = @"FBSDKAccessToken"; NSString *const FBSDKAccessTokenChangeOldKey = @"FBSDKAccessTokenOld"; static FBSDKAccessToken *g_currentAccessToken; #define FBSDK_ACCESSTOKEN_TOKENSTRING_KEY @"tokenString" #define FBSDK_ACCESSTOKEN_PERMISSIONS_KEY @"permissions" #define FBSDK_ACCESSTOKEN_DECLINEDPERMISSIONS_KEY @"declinedPermissions" #define FBSDK_ACCESSTOKEN_APPID_KEY @"appID" #define FBSDK_ACCESSTOKEN_USERID_KEY @"userID" #define FBSDK_ACCESSTOKEN_REFRESHDATE_KEY @"refreshDate" #define FBSDK_ACCESSTOKEN_EXPIRATIONDATE_KEY @"expirationDate" @implementation FBSDKAccessToken - (instancetype)init NS_UNAVAILABLE { assert(0); } - (instancetype)initWithTokenString:(NSString *)tokenString permissions:(NSArray *)permissions declinedPermissions:(NSArray *)declinedPermissions appID:(NSString *)appID userID:(NSString *)userID expirationDate:(NSDate *)expirationDate refreshDate:(NSDate *)refreshDate { if ((self = [super init])) { _tokenString = [tokenString copy]; _permissions = [NSSet setWithArray:permissions]; _declinedPermissions = [NSSet setWithArray:declinedPermissions]; _appID = [appID copy]; _userID = [userID copy]; _expirationDate = [expirationDate copy] ?: [NSDate distantFuture]; _refreshDate = [refreshDate copy] ?: [NSDate date]; } return self; } - (BOOL)hasGranted:(NSString *)permission { return [self.permissions containsObject:permission]; } + (FBSDKAccessToken *)currentAccessToken { return g_currentAccessToken; } + (void)setCurrentAccessToken:(FBSDKAccessToken *)token { if (token != g_currentAccessToken) { NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; [FBSDKInternalUtility dictionary:userInfo setObject:token forKey:FBSDKAccessTokenChangeNewKey]; [FBSDKInternalUtility dictionary:userInfo setObject:g_currentAccessToken forKey:FBSDKAccessTokenChangeOldKey]; if (![g_currentAccessToken.userID isEqualToString:token.userID]) { userInfo[FBSDKAccessTokenDidChangeUserID] = @YES; } g_currentAccessToken = token; // Only need to keep current session in web view for the case when token is current // When token is abandoned cookies must to be cleaned up immediately if (token == nil) { [FBSDKInternalUtility deleteFacebookCookies]; } [[FBSDKSettings accessTokenCache] cacheAccessToken:token]; [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKAccessTokenDidChangeNotification object:[self class] userInfo:userInfo]; } } + (void)refreshCurrentAccessToken:(FBSDKGraphRequestHandler)completionHandler { if ([FBSDKAccessToken currentAccessToken]) { FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; [FBSDKGraphRequestPiggybackManager addRefreshPiggyback:connection permissionHandler:completionHandler]; [connection start]; } else { if (completionHandler) { completionHandler(nil, nil, [FBSDKError errorWithCode:FBSDKAccessTokenRequiredErrorCode message:@"No current access token to refresh"]); } } } #pragma mark - Equality - (NSUInteger)hash { NSUInteger subhashes[] = { [self.tokenString hash], [self.permissions hash], [self.declinedPermissions hash], [self.appID hash], [self.userID hash], [self.refreshDate hash], [self.expirationDate hash] }; return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKAccessToken class]]) { return NO; } return [self isEqualToAccessToken:(FBSDKAccessToken *)object]; } - (BOOL)isEqualToAccessToken:(FBSDKAccessToken *)token { return (token && [FBSDKInternalUtility object:self.tokenString isEqualToObject:token.tokenString] && [FBSDKInternalUtility object:self.permissions isEqualToObject:token.permissions] && [FBSDKInternalUtility object:self.declinedPermissions isEqualToObject:token.declinedPermissions] && [FBSDKInternalUtility object:self.appID isEqualToObject:token.appID] && [FBSDKInternalUtility object:self.userID isEqualToObject:token.userID] && [FBSDKInternalUtility object:self.refreshDate isEqualToObject:token.refreshDate] && [FBSDKInternalUtility object:self.expirationDate isEqualToObject:token.expirationDate] ); } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { // we're immutable. return self; } #pragma mark NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { NSString *appID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_ACCESSTOKEN_APPID_KEY]; NSSet *declinedPermissions = [decoder decodeObjectOfClass:[NSSet class] forKey:FBSDK_ACCESSTOKEN_DECLINEDPERMISSIONS_KEY]; NSSet *permissions = [decoder decodeObjectOfClass:[NSSet class] forKey:FBSDK_ACCESSTOKEN_PERMISSIONS_KEY]; NSString *tokenString = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_ACCESSTOKEN_TOKENSTRING_KEY]; NSString *userID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_ACCESSTOKEN_USERID_KEY]; NSDate *refreshDate = [decoder decodeObjectOfClass:[NSDate class] forKey:FBSDK_ACCESSTOKEN_REFRESHDATE_KEY]; NSDate *expirationDate = [decoder decodeObjectOfClass:[NSDate class] forKey:FBSDK_ACCESSTOKEN_EXPIRATIONDATE_KEY]; return [self initWithTokenString:tokenString permissions:[permissions allObjects] declinedPermissions:[declinedPermissions allObjects] appID:appID userID:userID expirationDate:expirationDate refreshDate:refreshDate]; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:self.appID forKey:FBSDK_ACCESSTOKEN_APPID_KEY]; [encoder encodeObject:self.declinedPermissions forKey:FBSDK_ACCESSTOKEN_DECLINEDPERMISSIONS_KEY]; [encoder encodeObject:self.permissions forKey:FBSDK_ACCESSTOKEN_PERMISSIONS_KEY]; [encoder encodeObject:self.tokenString forKey:FBSDK_ACCESSTOKEN_TOKENSTRING_KEY]; [encoder encodeObject:self.userID forKey:FBSDK_ACCESSTOKEN_USERID_KEY]; [encoder encodeObject:self.expirationDate forKey:FBSDK_ACCESSTOKEN_EXPIRATIONDATE_KEY]; [encoder encodeObject:self.refreshDate forKey:FBSDK_ACCESSTOKEN_REFRESHDATE_KEY]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKAppEvents.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKMacros.h" @class FBSDKAccessToken; @class FBSDKGraphRequest; /*! @abstract NSNotificationCenter name indicating a result of a failed log flush attempt. The posted object will be an NSError instance. */ FBSDK_EXTERN NSString *const FBSDKAppEventsLoggingResultNotification; /*! @abstract optional plist key ("FacebookLoggingOverrideAppID") for setting `loggingOverrideAppID` */ FBSDK_EXTERN NSString *const FBSDKAppEventsOverrideAppIDBundleKey; /*! @typedef NS_ENUM (NSUInteger, FBSDKAppEventsFlushBehavior) @abstract Specifies when `FBSDKAppEvents` sends log events to the server. */ typedef NS_ENUM(NSUInteger, FBSDKAppEventsFlushBehavior) { /*! Flush automatically: periodically (once a minute or every 100 logged events) and always at app reactivation. */ FBSDKAppEventsFlushBehaviorAuto = 0, /*! Only flush when the `flush` method is called. When an app is moved to background/terminated, the events are persisted and re-established at activation, but they will only be written with an explicit call to `flush`. */ FBSDKAppEventsFlushBehaviorExplicitOnly, }; /*! @methodgroup Predefined event names for logging events common to many apps. Logging occurs through the `logEvent` family of methods on `FBSDKAppEvents`. Common event parameters are provided in the `FBSDKAppEventsParameterNames*` constants. */ /*! Log this event when the user has achieved a level in the app. */ FBSDK_EXTERN NSString *const FBSDKAppEventNameAchievedLevel; /*! Log this event when the user has entered their payment info. */ FBSDK_EXTERN NSString *const FBSDKAppEventNameAddedPaymentInfo; /*! Log this event when the user has added an item to their cart. The valueToSum passed to logEvent should be the item's price. */ FBSDK_EXTERN NSString *const FBSDKAppEventNameAddedToCart; /*! Log this event when the user has added an item to their wishlist. The valueToSum passed to logEvent should be the item's price. */ FBSDK_EXTERN NSString *const FBSDKAppEventNameAddedToWishlist; /*! Log this event when a user has completed registration with the app. */ FBSDK_EXTERN NSString *const FBSDKAppEventNameCompletedRegistration; /*! Log this event when the user has completed a tutorial in the app. */ FBSDK_EXTERN NSString *const FBSDKAppEventNameCompletedTutorial; /*! Log this event when the user has entered the checkout process. The valueToSum passed to logEvent should be the total price in the cart. */ FBSDK_EXTERN NSString *const FBSDKAppEventNameInitiatedCheckout; /*! Log this event when the user has rated an item in the app. The valueToSum passed to logEvent should be the numeric rating. */ FBSDK_EXTERN NSString *const FBSDKAppEventNameRated; /*! Log this event when a user has performed a search within the app. */ FBSDK_EXTERN NSString *const FBSDKAppEventNameSearched; /*! Log this event when the user has spent app credits. The valueToSum passed to logEvent should be the number of credits spent. */ FBSDK_EXTERN NSString *const FBSDKAppEventNameSpentCredits; /*! Log this event when the user has unlocked an achievement in the app. */ FBSDK_EXTERN NSString *const FBSDKAppEventNameUnlockedAchievement; /*! Log this event when a user has viewed a form of content in the app. */ FBSDK_EXTERN NSString *const FBSDKAppEventNameViewedContent; /*! @methodgroup Predefined event name parameters for common additional information to accompany events logged through the `logEvent` family of methods on `FBSDKAppEvents`. Common event names are provided in the `FBAppEventName*` constants. */ /*! Parameter key used to specify an ID for the specific piece of content being logged about. Could be an EAN, article identifier, etc., depending on the nature of the app. */ FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameContentID; /*! Parameter key used to specify a generic content type/family for the logged event, e.g. "music", "photo", "video". Options to use will vary based upon what the app is all about. */ FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameContentType; /*! Parameter key used to specify currency used with logged event. E.g. "USD", "EUR", "GBP". See ISO-4217 for specific values. One reference for these is . */ FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameCurrency; /*! Parameter key used to specify a description appropriate to the event being logged. E.g., the name of the achievement unlocked in the `FBAppEventNameAchievementUnlocked` event. */ FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameDescription; /*! Parameter key used to specify the level achieved in a `FBAppEventNameAchieved` event. */ FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameLevel; /*! Parameter key used to specify the maximum rating available for the `FBAppEventNameRate` event. E.g., "5" or "10". */ FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameMaxRatingValue; /*! Parameter key used to specify how many items are being processed for an `FBAppEventNameInitiatedCheckout` or `FBAppEventNamePurchased` event. */ FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameNumItems; /*! Parameter key used to specify whether payment info is available for the `FBAppEventNameInitiatedCheckout` event. `FBSDKAppEventParameterValueYes` and `FBSDKAppEventParameterValueNo` are good canonical values to use for this parameter. */ FBSDK_EXTERN NSString *const FBSDKAppEventParameterNamePaymentInfoAvailable; /*! Parameter key used to specify method user has used to register for the app, e.g., "Facebook", "email", "Twitter", etc */ FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameRegistrationMethod; /*! Parameter key used to specify the string provided by the user for a search operation. */ FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameSearchString; /*! Parameter key used to specify whether the activity being logged about was successful or not. `FBSDKAppEventParameterValueYes` and `FBSDKAppEventParameterValueNo` are good canonical values to use for this parameter. */ FBSDK_EXTERN NSString *const FBSDKAppEventParameterNameSuccess; /* @methodgroup Predefined values to assign to event parameters that accompany events logged through the `logEvent` family of methods on `FBSDKAppEvents`. Common event parameters are provided in the `FBSDKAppEventParameterName*` constants. */ /*! Yes-valued parameter value to be used with parameter keys that need a Yes/No value */ FBSDK_EXTERN NSString *const FBSDKAppEventParameterValueYes; /*! No-valued parameter value to be used with parameter keys that need a Yes/No value */ FBSDK_EXTERN NSString *const FBSDKAppEventParameterValueNo; /*! @class FBSDKAppEvents @abstract Client-side event logging for specialized application analytics available through Facebook App Insights and for use with Facebook Ads conversion tracking and optimization. @discussion The `FBSDKAppEvents` static class has a few related roles: + Logging predefined and application-defined events to Facebook App Insights with a numeric value to sum across a large number of events, and an optional set of key/value parameters that define "segments" for this event (e.g., 'purchaserStatus' : 'frequent', or 'gamerLevel' : 'intermediate') + Logging events to later be used for ads optimization around lifetime value. + Methods that control the way in which events are flushed out to the Facebook servers. Here are some important characteristics of the logging mechanism provided by `FBSDKAppEvents`: + Events are not sent immediately when logged. They're cached and flushed out to the Facebook servers in a number of situations: - when an event count threshold is passed (currently 100 logged events). - when a time threshold is passed (currently 15 seconds). - when an app has gone to background and is then brought back to the foreground. + Events will be accumulated when the app is in a disconnected state, and sent when the connection is restored and one of the above 'flush' conditions are met. + The `FBSDKAppEvents` class is thread-safe in that events may be logged from any of the app's threads. + The developer can set the `flushBehavior` on `FBSDKAppEvents` to force the flushing of events to only occur on an explicit call to the `flush` method. + The developer can turn on console debug output for event logging and flushing to the server by using the `FBSDKLoggingBehaviorAppEvents` value in `[FBSettings setLoggingBehavior:]`. Some things to note when logging events: + There is a limit on the number of unique event names an app can use, on the order of 1000. + There is a limit to the number of unique parameter names in the provided parameters that can be used per event, on the order of 25. This is not just for an individual call, but for all invocations for that eventName. + Event names and parameter names (the keys in the NSDictionary) must be between 2 and 40 characters, and must consist of alphanumeric characters, _, -, or spaces. + The length of each parameter value can be no more than on the order of 100 characters. */ @interface FBSDKAppEvents : NSObject /* * Basic event logging */ /*! @abstract Log an event with just an eventName. @param eventName The name of the event to record. Limitations on number of events and name length are given in the `FBSDKAppEvents` documentation. */ + (void)logEvent:(NSString *)eventName; /*! @abstract Log an event with an eventName and a numeric value to be aggregated with other events of this name. @param eventName The name of the event to record. Limitations on number of events and name length are given in the `FBSDKAppEvents` documentation. Common event names are provided in `FBAppEventName*` constants. @param valueToSum Amount to be aggregated into all events of this eventName, and App Insights will report the cumulative and average value of this amount. */ + (void)logEvent:(NSString *)eventName valueToSum:(double)valueToSum; /*! @abstract Log an event with an eventName and a set of key/value pairs in the parameters dictionary. Parameter limitations are described above. @param eventName The name of the event to record. Limitations on number of events and name construction are given in the `FBSDKAppEvents` documentation. Common event names are provided in `FBAppEventName*` constants. @param parameters Arbitrary parameter dictionary of characteristics. The keys to this dictionary must be NSString's, and the values are expected to be NSString or NSNumber. Limitations on the number of parameters and name construction are given in the `FBSDKAppEvents` documentation. Commonly used parameter names are provided in `FBSDKAppEventParameterName*` constants. */ + (void)logEvent:(NSString *)eventName parameters:(NSDictionary *)parameters; /*! @abstract Log an event with an eventName, a numeric value to be aggregated with other events of this name, and a set of key/value pairs in the parameters dictionary. @param eventName The name of the event to record. Limitations on number of events and name construction are given in the `FBSDKAppEvents` documentation. Common event names are provided in `FBAppEventName*` constants. @param valueToSum Amount to be aggregated into all events of this eventName, and App Insights will report the cumulative and average value of this amount. @param parameters Arbitrary parameter dictionary of characteristics. The keys to this dictionary must be NSString's, and the values are expected to be NSString or NSNumber. Limitations on the number of parameters and name construction are given in the `FBSDKAppEvents` documentation. Commonly used parameter names are provided in `FBSDKAppEventParameterName*` constants. */ + (void)logEvent:(NSString *)eventName valueToSum:(double)valueToSum parameters:(NSDictionary *)parameters; /*! @abstract Log an event with an eventName, a numeric value to be aggregated with other events of this name, and a set of key/value pairs in the parameters dictionary. Providing session lets the developer target a particular . If nil is provided, then `[FBSession activeSession]` will be used. @param eventName The name of the event to record. Limitations on number of events and name construction are given in the `FBSDKAppEvents` documentation. Common event names are provided in `FBAppEventName*` constants. @param valueToSum Amount to be aggregated into all events of this eventName, and App Insights will report the cumulative and average value of this amount. Note that this is an NSNumber, and a value of `nil` denotes that this event doesn't have a value associated with it for summation. @param parameters Arbitrary parameter dictionary of characteristics. The keys to this dictionary must be NSString's, and the values are expected to be NSString or NSNumber. Limitations on the number of parameters and name construction are given in the `FBSDKAppEvents` documentation. Commonly used parameter names are provided in `FBSDKAppEventParameterName*` constants. @param accessToken The optional access token to log the event as. */ + (void)logEvent:(NSString *)eventName valueToSum:(NSNumber *)valueToSum parameters:(NSDictionary *)parameters accessToken:(FBSDKAccessToken *)accessToken; /* * Purchase logging */ /*! @abstract Log a purchase of the specified amount, in the specified currency. @param purchaseAmount Purchase amount to be logged, as expressed in the specified currency. This value will be rounded to the thousandths place (e.g., 12.34567 becomes 12.346). @param currency Currency, is denoted as, e.g. "USD", "EUR", "GBP". See ISO-4217 for specific values. One reference for these is . @discussion This event immediately triggers a flush of the `FBSDKAppEvents` event queue, unless the `flushBehavior` is set to `FBSDKAppEventsFlushBehaviorExplicitOnly`. */ + (void)logPurchase:(double)purchaseAmount currency:(NSString *)currency; /*! @abstract Log a purchase of the specified amount, in the specified currency, also providing a set of additional characteristics describing the purchase. @param purchaseAmount Purchase amount to be logged, as expressed in the specified currency.This value will be rounded to the thousandths place (e.g., 12.34567 becomes 12.346). @param currency Currency, is denoted as, e.g. "USD", "EUR", "GBP". See ISO-4217 for specific values. One reference for these is . @param parameters Arbitrary parameter dictionary of characteristics. The keys to this dictionary must be NSString's, and the values are expected to be NSString or NSNumber. Limitations on the number of parameters and name construction are given in the `FBSDKAppEvents` documentation. Commonly used parameter names are provided in `FBSDKAppEventParameterName*` constants. @discussion This event immediately triggers a flush of the `FBSDKAppEvents` event queue, unless the `flushBehavior` is set to `FBSDKAppEventsFlushBehaviorExplicitOnly`. */ + (void)logPurchase:(double)purchaseAmount currency:(NSString *)currency parameters:(NSDictionary *)parameters; /*! @abstract Log a purchase of the specified amount, in the specified currency, also providing a set of additional characteristics describing the purchase, as well as an to log to. @param purchaseAmount Purchase amount to be logged, as expressed in the specified currency.This value will be rounded to the thousandths place (e.g., 12.34567 becomes 12.346). @param currency Currency, is denoted as, e.g. "USD", "EUR", "GBP". See ISO-4217 for specific values. One reference for these is . @param parameters Arbitrary parameter dictionary of characteristics. The keys to this dictionary must be NSString's, and the values are expected to be NSString or NSNumber. Limitations on the number of parameters and name construction are given in the `FBSDKAppEvents` documentation. Commonly used parameter names are provided in `FBSDKAppEventParameterName*` constants. @param accessToken The optional access token to log the event as. @discussion This event immediately triggers a flush of the `FBSDKAppEvents` event queue, unless the `flushBehavior` is set to `FBSDKAppEventsFlushBehaviorExplicitOnly`. */ + (void)logPurchase:(double)purchaseAmount currency:(NSString *)currency parameters:(NSDictionary *)parameters accessToken:(FBSDKAccessToken *)accessToken; /* * Push Notifications Logging */ /*! @abstract Log an app event that tracks that the application was open via Push Notification. @param payload Notification payload received via `UIApplicationDelegate`. */ + (void)logPushNotificationOpen:(NSDictionary *)payload; /*! @abstract Log an app event that tracks that a custom action was taken from a push notification. @param payload Notification payload received via `UIApplicationDelegate`. @param action Name of the action that was taken. */ + (void)logPushNotificationOpen:(NSDictionary *)payload action:(NSString *)action; /*! @abstract Notifies the events system that the app has launched and, when appropriate, logs an "activated app" event. Should typically be placed in the app delegates' `applicationDidBecomeActive:` method. This method also takes care of logging the event indicating the first time this app has been launched, which, among other things, is used to track user acquisition and app install ads conversions. @discussion `activateApp` will not log an event on every app launch, since launches happen every time the app is backgrounded and then foregrounded. "activated app" events will be logged when the app has not been active for more than 60 seconds. This method also causes a "deactivated app" event to be logged when sessions are "completed", and these events are logged with the session length, with an indication of how much time has elapsed between sessions, and with the number of background/foreground interruptions that session had. This data is all visible in your app's App Events Insights. */ + (void)activateApp; /* * Push Notifications Registration */ /*! @abstract Sets a device token to register the current application installation for push notifications. @discussion Sets a device token from `NSData` representation that you get from `UIApplicationDelegate.-application:didRegisterForRemoteNotificationsWithDeviceToken:`. @param deviceToken Device token data. */ + (void)setPushNotificationsDeviceToken:(NSData *)deviceToken; /* * Control over event batching/flushing */ /*! @abstract Get the current event flushing behavior specifying when events are sent back to Facebook servers. */ + (FBSDKAppEventsFlushBehavior)flushBehavior; /*! @abstract Set the current event flushing behavior specifying when events are sent back to Facebook servers. @param flushBehavior The desired `FBSDKAppEventsFlushBehavior` to be used. */ + (void)setFlushBehavior:(FBSDKAppEventsFlushBehavior)flushBehavior; /*! @abstract Set the 'override' App ID for App Event logging. @discussion In some cases, apps want to use one Facebook App ID for login and social presence and another for App Event logging. (An example is if multiple apps from the same company share an app ID for login, but want distinct logging.) By default, this value is `nil`, and defers to the `FBSDKAppEventsOverrideAppIDBundleKey` plist value. If that's not set, it defaults to `[FBSDKSettings appID]`. This should be set before any other calls are made to `FBSDKAppEvents`. Thus, you should set it in your application delegate's `application:didFinishLaunchingWithOptions:` delegate. @param appID The Facebook App ID to be used for App Event logging. */ + (void)setLoggingOverrideAppID:(NSString *)appID; /*! @abstract Get the 'override' App ID for App Event logging. @see setLoggingOverrideAppID: */ + (NSString *)loggingOverrideAppID; /*! @abstract Explicitly kick off flushing of events to Facebook. This is an asynchronous method, but it does initiate an immediate kick off. Server failures will be reported through the NotificationCenter with notification ID `FBSDKAppEventsLoggingResultNotification`. */ + (void)flush; /*! @abstract Creates a request representing the Graph API call to retrieve a Custom Audience "third party ID" for the app's Facebook user. Callers will send this ID back to their own servers, collect up a set to create a Facebook Custom Audience with, and then use the resultant Custom Audience to target ads. @param accessToken The access token to use to establish the user's identity for users logged into Facebook through this app. If `nil`, then the `[FBSDKAccessToken currentAccessToken]` is used. @discussion The JSON in the request's response will include an "custom_audience_third_party_id" key/value pair, with the value being the ID retrieved. This ID is an encrypted encoding of the Facebook user's ID and the invoking Facebook app ID. Multiple calls with the same user will return different IDs, thus these IDs cannot be used to correlate behavior across devices or applications, and are only meaningful when sent back to Facebook for creating Custom Audiences. The ID retrieved represents the Facebook user identified in the following way: if the specified access token is valid, the ID will represent the user associated with that token; otherwise the ID will represent the user logged into the native Facebook app on the device. If there is no native Facebook app, no one is logged into it, or the user has opted out at the iOS level from ad tracking, then a `nil` ID will be returned. This method returns `nil` if either the user has opted-out (via iOS) from Ad Tracking, the app itself has limited event usage via the `[FBSDKSettings limitEventAndDataUsage]` flag, or a specific Facebook user cannot be identified. */ + (FBSDKGraphRequest *)requestForCustomAudienceThirdPartyIDWithAccessToken:(FBSDKAccessToken *)accessToken; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKAppEvents.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAppEvents.h" #import "FBSDKAppEvents+Internal.h" #import #import "FBSDKAccessToken.h" #import "FBSDKAppEventsState.h" #import "FBSDKAppEventsStateManager.h" #import "FBSDKAppEventsUtility.h" #import "FBSDKConstants.h" #import "FBSDKError.h" #import "FBSDKGraphRequest+Internal.h" #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKPaymentObserver.h" #import "FBSDKServerConfiguration.h" #import "FBSDKServerConfigurationManager.h" #import "FBSDKSettings.h" #import "FBSDKTimeSpentData.h" #import "FBSDKUtility.h" // // Public event names // // General purpose NSString *const FBSDKAppEventNameCompletedRegistration = @"fb_mobile_complete_registration"; NSString *const FBSDKAppEventNameViewedContent = @"fb_mobile_content_view"; NSString *const FBSDKAppEventNameSearched = @"fb_mobile_search"; NSString *const FBSDKAppEventNameRated = @"fb_mobile_rate"; NSString *const FBSDKAppEventNameCompletedTutorial = @"fb_mobile_tutorial_completion"; NSString *const FBSDKAppEventParameterLaunchSource = @"fb_mobile_launch_source"; // Ecommerce related NSString *const FBSDKAppEventNameAddedToCart = @"fb_mobile_add_to_cart"; NSString *const FBSDKAppEventNameAddedToWishlist = @"fb_mobile_add_to_wishlist"; NSString *const FBSDKAppEventNameInitiatedCheckout = @"fb_mobile_initiated_checkout"; NSString *const FBSDKAppEventNameAddedPaymentInfo = @"fb_mobile_add_payment_info"; // Gaming related NSString *const FBSDKAppEventNameAchievedLevel = @"fb_mobile_level_achieved"; NSString *const FBSDKAppEventNameUnlockedAchievement = @"fb_mobile_achievement_unlocked"; NSString *const FBSDKAppEventNameSpentCredits = @"fb_mobile_spent_credits"; // // Public event parameter names // NSString *const FBSDKAppEventParameterNameCurrency = @"fb_currency"; NSString *const FBSDKAppEventParameterNameRegistrationMethod = @"fb_registration_method"; NSString *const FBSDKAppEventParameterNameContentType = @"fb_content_type"; NSString *const FBSDKAppEventParameterNameContentID = @"fb_content_id"; NSString *const FBSDKAppEventParameterNameSearchString = @"fb_search_string"; NSString *const FBSDKAppEventParameterNameSuccess = @"fb_success"; NSString *const FBSDKAppEventParameterNameMaxRatingValue = @"fb_max_rating_value"; NSString *const FBSDKAppEventParameterNamePaymentInfoAvailable = @"fb_payment_info_available"; NSString *const FBSDKAppEventParameterNameNumItems = @"fb_num_items"; NSString *const FBSDKAppEventParameterNameLevel = @"fb_level"; NSString *const FBSDKAppEventParameterNameDescription = @"fb_description"; // // Public event parameter values // NSString *const FBSDKAppEventParameterValueNo = @"0"; NSString *const FBSDKAppEventParameterValueYes = @"1"; // // Event names internal to this file // NSString *const FBSDKAppEventNamePurchased = @"fb_mobile_purchase"; NSString *const FBSDKAppEventNameLoginViewUsage = @"fb_login_view_usage"; NSString *const FBSDKAppEventNameShareSheetLaunch = @"fb_share_sheet_launch"; NSString *const FBSDKAppEventNameShareSheetDismiss = @"fb_share_sheet_dismiss"; NSString *const FBSDKAppEventNamePermissionsUILaunch = @"fb_permissions_ui_launch"; NSString *const FBSDKAppEventNamePermissionsUIDismiss = @"fb_permissions_ui_dismiss"; NSString *const FBSDKAppEventNameFBDialogsPresentShareDialog = @"fb_dialogs_present_share"; NSString *const FBSDKAppEventNameFBDialogsPresentShareDialogPhoto = @"fb_dialogs_present_share_photo"; NSString *const FBSDKAppEventNameFBDialogsPresentShareDialogOG = @"fb_dialogs_present_share_og"; NSString *const FBSDKAppEventNameFBDialogsPresentLikeDialogOG = @"fb_dialogs_present_like_og"; NSString *const FBSDKAppEventNameFBDialogsPresentMessageDialog = @"fb_dialogs_present_message"; NSString *const FBSDKAppEventNameFBDialogsPresentMessageDialogPhoto = @"fb_dialogs_present_message_photo"; NSString *const FBSDKAppEventNameFBDialogsPresentMessageDialogOG = @"fb_dialogs_present_message_og"; NSString *const FBSDKAppEventNameFBDialogsNativeLoginDialogStart = @"fb_dialogs_native_login_dialog_start"; NSString *const FBSDKAppEventsNativeLoginDialogStartTime = @"fb_native_login_dialog_start_time"; NSString *const FBSDKAppEventNameFBDialogsNativeLoginDialogEnd = @"fb_dialogs_native_login_dialog_end"; NSString *const FBSDKAppEventsNativeLoginDialogEndTime = @"fb_native_login_dialog_end_time"; NSString *const FBSDKAppEventNameFBDialogsWebLoginCompleted = @"fb_dialogs_web_login_dialog_complete"; NSString *const FBSDKAppEventsWebLoginE2E = @"fb_web_login_e2e"; NSString *const FBSDKAppEventNameFBSessionAuthStart = @"fb_mobile_login_start"; NSString *const FBSDKAppEventNameFBSessionAuthEnd = @"fb_mobile_login_complete"; NSString *const FBSDKAppEventNameFBSessionAuthMethodStart = @"fb_mobile_login_method_start"; NSString *const FBSDKAppEventNameFBSessionAuthMethodEnd = @"fb_mobile_login_method_complete"; NSString *const FBSDKAppEventNameFBSDKLikeButtonImpression = @"fb_like_button_impression"; NSString *const FBSDKAppEventNameFBSDKLoginButtonImpression = @"fb_login_button_impression"; NSString *const FBSDKAppEventNameFBSDKSendButtonImpression = @"fb_send_button_impression"; NSString *const FBSDKAppEventNameFBSDKShareButtonImpression = @"fb_share_button_impression"; NSString *const FBSDKAppEventNameFBSDKLikeButtonDidTap = @"fb_like_button_did_tap"; NSString *const FBSDKAppEventNameFBSDKLoginButtonDidTap = @"fb_login_button_did_tap"; NSString *const FBSDKAppEventNameFBSDKSendButtonDidTap = @"fb_send_button_did_tap"; NSString *const FBSDKAppEventNameFBSDKShareButtonDidTap = @"fb_share_button_did_tap"; NSString *const FBSDKAppEventNameFBSDKLikeControlDidDisable = @"fb_like_control_did_disable"; NSString *const FBSDKAppEventNameFBSDKLikeControlDidLike = @"fb_like_control_did_like"; NSString *const FBSDKAppEventNameFBSDKLikeControlDidPresentDialog = @"fb_like_control_did_present_dialog"; NSString *const FBSDKAppEventNameFBSDKLikeControlDidTap = @"fb_like_control_did_tap"; NSString *const FBSDKAppEventNameFBSDKLikeControlDidUnlike = @"fb_like_control_did_unlike"; NSString *const FBSDKAppEventNameFBSDKLikeControlError = @"fb_like_control_error"; NSString *const FBSDKAppEventNameFBSDKLikeControlImpression = @"fb_like_control_impression"; NSString *const FBSDKAppEventNameFBSDKLikeControlNetworkUnavailable = @"fb_like_control_network_unavailable"; NSString *const FBSDLAppEventNameFBSDKEventShareDialogResult = @"fb_dialog_share_result"; NSString *const FBSDKAppEventNameFBSDKEventMessengerShareDialogResult = @"fb_messenger_dialog_share_result"; NSString *const FBSDKAppEventNameFBSDKEventAppInviteShareDialogResult = @"fb_app_invite_dialog_share_result"; NSString *const FBSDKAppEventNameFBSDKEventShareDialogShow = @"fb_dialog_share_show"; NSString *const FBSDKAppEventNameFBSDKEventMessengerShareDialogShow = @"fb_messenger_dialog_share_show"; NSString *const FBSDKAppEventNameFBSDKEventAppInviteShareDialogShow = @"fb_app_invite_share_show"; // Event Parameters internal to this file NSString *const FBSDKAppEventParameterDialogOutcome = @"fb_dialog_outcome"; NSString *const FBSDKAppEventParameterDialogErrorMessage = @"fb_dialog_outcome_error_message"; NSString *const FBSDKAppEventParameterDialogMode = @"fb_dialog_mode"; NSString *const FBSDKAppEventParameterDialogShareContentType = @"fb_dialog_share_content_type"; NSString *const FBSDKAppEventParameterLogTime = @"_logTime"; NSString *const FBSDKAppEventParameterEventName = @"_eventName"; NSString *const FBSDKAppEventParameterImplicitlyLogged = @"_implicitlyLogged"; // Event parameter values internal to this file NSString *const FBSDKAppEventsDialogOutcomeValue_Completed = @"Completed"; NSString *const FBSDKAppEventsDialogOutcomeValue_Cancelled = @"Cancelled"; NSString *const FBSDKAppEventsDialogOutcomeValue_Failed = @"Failed"; NSString *const FBSDKAppEventsDialogShareModeAutomatic = @"Automatic"; NSString *const FBSDKAppEventsDialogShareModeBrowser = @"Browser"; NSString *const FBSDKAppEventsDialogShareModeNative = @"Native"; NSString *const FBSDKAppEventsDialogShareModeShareSheet = @"ShareSheet"; NSString *const FBSDKAppEventsDialogShareModeWeb = @"Web"; NSString *const FBSDKAppEventsDialogShareModeFeedBrowser = @"FeedBrowser"; NSString *const FBSDKAppEventsDialogShareModeFeedWeb = @"FeedWeb"; NSString *const FBSDKAppEventsDialogShareModeUnknown = @"Unknown"; NSString *const FBSDKAppEventsDialogShareContentTypeOpenGraph = @"OpenGraph"; NSString *const FBSDKAppEventsDialogShareContentTypeStatus = @"Status"; NSString *const FBSDKAppEventsDialogShareContentTypePhoto = @"Photo"; NSString *const FBSDKAppEventsDialogShareContentTypeVideo = @"Video"; NSString *const FBSDKAppEventsDialogShareContentTypeUnknown = @"Unknown"; NSString *const FBSDKAppEventsLoggingResultNotification = @"com.facebook.sdk:FBSDKAppEventsLoggingResultNotification"; NSString *const FBSDKAppEventsOverrideAppIDBundleKey = @"FacebookLoggingOverrideAppID"; // // Push Notifications // Activities Endpoint Parameter static NSString *const FBSDKActivitesParameterPushDeviceToken = @"device_token"; // Event Name static NSString *const FBSDKAppEventNamePushOpened = @"fb_mobile_push_opened"; // Event Parameter static NSString *const FBSDKAppEventParameterPushCampaign = @"fb_push_campaign"; static NSString *const FBSDKAppEventParameterPushAction = @"fb_push_action"; // Payload Keys static NSString *const FBSDKAppEventsPushPayloadKey = @"fb_push_payload"; static NSString *const FBSDKAppEventsPushPayloadCampaignKey = @"campaign"; #define NUM_LOG_EVENTS_TO_TRY_TO_FLUSH_AFTER 100 #define FLUSH_PERIOD_IN_SECONDS 15 #define APP_SUPPORTS_ATTRIBUTION_ID_RECHECK_PERIOD 60 * 60 * 24 static NSString *g_overrideAppID = nil; @interface FBSDKAppEvents () @property (nonatomic, readwrite) FBSDKAppEventsFlushBehavior flushBehavior; //for testing only. @property (nonatomic, assign) BOOL disableTimer; @property (nonatomic, copy) NSString *pushNotificationsDeviceTokenString; @end @implementation FBSDKAppEvents { BOOL _explicitEventsLoggedYet; NSTimer *_flushTimer; NSTimer *_attributionIDRecheckTimer; FBSDKServerConfiguration *_serverConfiguration; FBSDKAppEventsState *_appEventsState; } #pragma mark - Object Lifecycle + (void)initialize { if (self == [FBSDKAppEvents class]) { g_overrideAppID = [[[NSBundle mainBundle] objectForInfoDictionaryKey:FBSDKAppEventsOverrideAppIDBundleKey] copy]; } } - (FBSDKAppEvents *)init { self = [super init]; if (self) { _flushBehavior = FBSDKAppEventsFlushBehaviorAuto; _flushTimer = [NSTimer timerWithTimeInterval:FLUSH_PERIOD_IN_SECONDS target:self selector:@selector(flushTimerFired:) userInfo:nil repeats:YES]; _attributionIDRecheckTimer = [NSTimer timerWithTimeInterval:APP_SUPPORTS_ATTRIBUTION_ID_RECHECK_PERIOD target:self selector:@selector(appSettingsFetchStateResetTimerFired:) userInfo:nil repeats:YES]; [[NSRunLoop mainRunLoop] addTimer:_flushTimer forMode:NSDefaultRunLoopMode]; [[NSRunLoop mainRunLoop] addTimer:_attributionIDRecheckTimer forMode:NSDefaultRunLoopMode]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationMovingFromActiveStateOrTerminating) name:UIApplicationWillResignActiveNotification object:NULL]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationMovingFromActiveStateOrTerminating) name:UIApplicationWillTerminateNotification object:NULL]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:NULL]; } return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; // technically these timers retain self so there's a cycle but // we're a singleton anyway. [_flushTimer invalidate]; [_attributionIDRecheckTimer invalidate]; } #pragma mark - Public Methods + (void)logEvent:(NSString *)eventName { [FBSDKAppEvents logEvent:eventName parameters:nil]; } + (void)logEvent:(NSString *)eventName valueToSum:(double)valueToSum { [FBSDKAppEvents logEvent:eventName valueToSum:valueToSum parameters:nil]; } + (void)logEvent:(NSString *)eventName parameters:(NSDictionary *)parameters { [FBSDKAppEvents logEvent:eventName valueToSum:nil parameters:parameters accessToken:nil]; } + (void)logEvent:(NSString *)eventName valueToSum:(double)valueToSum parameters:(NSDictionary *)parameters { [FBSDKAppEvents logEvent:eventName valueToSum:[NSNumber numberWithDouble:valueToSum] parameters:parameters accessToken:nil]; } + (void)logEvent:(NSString *)eventName valueToSum:(NSNumber *)valueToSum parameters:(NSDictionary *)parameters accessToken:(FBSDKAccessToken *)accessToken { [[FBSDKAppEvents singleton] instanceLogEvent:eventName valueToSum:valueToSum parameters:parameters isImplicitlyLogged:NO accessToken:accessToken]; } + (void)logPurchase:(double)purchaseAmount currency:(NSString *)currency { [FBSDKAppEvents logPurchase:purchaseAmount currency:currency parameters:nil]; } + (void)logPurchase:(double)purchaseAmount currency:(NSString *)currency parameters:(NSDictionary *)parameters { [FBSDKAppEvents logPurchase:purchaseAmount currency:currency parameters:parameters accessToken:nil]; } + (void)logPurchase:(double)purchaseAmount currency:(NSString *)currency parameters:(NSDictionary *)parameters accessToken:(FBSDKAccessToken *)accessToken { // A purchase event is just a regular logged event with a given event name // and treating the currency value as going into the parameters dictionary. NSDictionary *newParameters; if (!parameters) { newParameters = @{ FBSDKAppEventParameterNameCurrency : currency }; } else { newParameters = [NSMutableDictionary dictionaryWithDictionary:parameters]; [newParameters setValue:currency forKey:FBSDKAppEventParameterNameCurrency]; } [FBSDKAppEvents logEvent:FBSDKAppEventNamePurchased valueToSum:[NSNumber numberWithDouble:purchaseAmount] parameters:newParameters accessToken:accessToken]; // Unless the behavior is set to only allow explicit flushing, we go ahead and flush, since purchase events // are relatively rare and relatively high value and worth getting across on wire right away. if ([FBSDKAppEvents flushBehavior] != FBSDKAppEventsFlushBehaviorExplicitOnly) { [[FBSDKAppEvents singleton] flushForReason:FBSDKAppEventsFlushReasonEagerlyFlushingEvent]; } } /* * Push Notifications Logging */ + (void)logPushNotificationOpen:(NSDictionary *)payload { [self logPushNotificationOpen:payload action:nil]; } + (void)logPushNotificationOpen:(NSDictionary *)payload action:(NSString *)action { NSDictionary *facebookPayload = payload[FBSDKAppEventsPushPayloadKey]; if (!facebookPayload) { return; } NSString *campaign = facebookPayload[FBSDKAppEventsPushPayloadCampaignKey]; if (campaign.length == 0) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"Malformed payload specified for logging a push notification open."]; return; } NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithObject:campaign forKey:FBSDKAppEventParameterPushCampaign]; if (action) { parameters[FBSDKAppEventParameterPushAction] = action; } [self logEvent:FBSDKAppEventNamePushOpened parameters:parameters]; } + (void)activateApp { [FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass(self)]; // Fetch app settings and register for transaction notifications only if app supports implicit purchase // events FBSDKAppEvents *instance = [FBSDKAppEvents singleton]; [instance publishInstall]; [instance fetchServerConfiguration:NULL]; // Restore time spent data, indicating that we're being called from "activateApp", which will, // when appropriate, result in logging an "activated app" and "deactivated app" (for the // previous session) App Event. [FBSDKTimeSpentData restore:YES]; } + (void)setPushNotificationsDeviceToken:(NSData *)deviceToken { [FBSDKAppEvents singleton].pushNotificationsDeviceTokenString = [FBSDKInternalUtility hexadecimalStringFromData:deviceToken]; } + (FBSDKAppEventsFlushBehavior)flushBehavior { return [FBSDKAppEvents singleton].flushBehavior; } + (void)setFlushBehavior:(FBSDKAppEventsFlushBehavior)flushBehavior { [FBSDKAppEvents singleton].flushBehavior = flushBehavior; } + (NSString *)loggingOverrideAppID { return g_overrideAppID; } + (void)setLoggingOverrideAppID:(NSString *)appID { if (![g_overrideAppID isEqualToString:appID]) { FBSDKConditionalLog(![FBSDKAppEvents singleton]->_explicitEventsLoggedYet, FBSDKLoggingBehaviorDeveloperErrors, @"[FBSDKAppEvents setLoggingOverrideAppID:] should only be called prior to any events being logged."); g_overrideAppID = appID; } } + (void)flush { [[FBSDKAppEvents singleton] flushForReason:FBSDKAppEventsFlushReasonExplicit]; } #pragma mark - Internal Methods + (void)logImplicitEvent:(NSString *)eventName valueToSum:(NSNumber *)valueToSum parameters:(NSDictionary *)parameters accessToken:(FBSDKAccessToken *)accessToken { [[FBSDKAppEvents singleton] instanceLogEvent:eventName valueToSum:valueToSum parameters:parameters isImplicitlyLogged:YES accessToken:accessToken]; } + (FBSDKAppEvents *)singleton { static dispatch_once_t pred; static FBSDKAppEvents *shared = nil; dispatch_once(&pred, ^{ shared = [[FBSDKAppEvents alloc] init]; }); return shared; } - (void)flushForReason:(FBSDKAppEventsFlushReason)flushReason { // Always flush asynchronously, even on main thread, for two reasons: // - most consistent code path for all threads. // - allow locks being held by caller to be released prior to actual flushing work being done. @synchronized (self) { if (!_appEventsState) { return; } FBSDKAppEventsState *copy = [_appEventsState copy]; _appEventsState = [[FBSDKAppEventsState alloc] initWithToken:copy.tokenString appID:copy.appID]; dispatch_async(dispatch_get_main_queue(), ^{ [self flushOnMainQueue:copy forReason:flushReason]; }); } } #pragma mark - Private Methods - (NSString *)appID { return [FBSDKAppEvents loggingOverrideAppID] ?: [FBSDKSettings appID]; } - (void)publishInstall { NSString *appID = [self appID]; NSString *lastAttributionPingString = [NSString stringWithFormat:@"com.facebook.sdk:lastAttributionPing%@", appID]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; if ([defaults objectForKey:lastAttributionPingString]) { return; } [self fetchServerConfiguration:^{ NSDictionary *params = [FBSDKAppEventsUtility activityParametersDictionaryForEvent:@"MOBILE_APP_INSTALL" implicitEventsOnly:NO shouldAccessAdvertisingID:_serverConfiguration.isAdvertisingIDEnabled]; NSString *path = [NSString stringWithFormat:@"%@/activities", appID]; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:path parameters:params tokenString:nil HTTPMethod:@"POST" flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (!error) { [defaults setObject:[NSDate date] forKey:lastAttributionPingString]; NSString *lastInstallResponseKey = [NSString stringWithFormat:@"com.facebook.sdk:lastInstallResponse%@", appID]; [defaults setObject:result forKey:lastInstallResponseKey]; [defaults synchronize]; } }]; }]; } // app events can use a server configuration up to 24 hours old to minimize network traffic. - (void)fetchServerConfiguration:(void (^)(void))callback { if (_serverConfiguration == nil) { [FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:^(FBSDKServerConfiguration *serverConfiguration, NSError *error) { _serverConfiguration = serverConfiguration; if (_serverConfiguration.implicitPurchaseLoggingEnabled) { [FBSDKPaymentObserver startObservingTransactions]; } else { [FBSDKPaymentObserver stopObservingTransactions]; } if (callback) { callback(); } }]; return; } if (callback) { callback(); } } - (void)instanceLogEvent:(NSString *)eventName valueToSum:(NSNumber *)valueToSum parameters:(NSDictionary *)parameters isImplicitlyLogged:(BOOL)isImplicitlyLogged accessToken:(FBSDKAccessToken *)accessToken { if (isImplicitlyLogged && _serverConfiguration && !_serverConfiguration.isImplicitLoggingSupported) { return; } if (!isImplicitlyLogged && !_explicitEventsLoggedYet) { _explicitEventsLoggedYet = YES; } __block BOOL failed = NO; if (![FBSDKAppEventsUtility validateIdentifier:eventName]) { failed = YES; } // Make sure parameter dictionary is well formed. Log and exit if not. [parameters enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { if (![key isKindOfClass:[NSString class]]) { [FBSDKAppEventsUtility logAndNotify:[NSString stringWithFormat:@"The keys in the parameters must be NSStrings, '%@' is not.", key]]; failed = YES; } if (![FBSDKAppEventsUtility validateIdentifier:key]) { failed = YES; } if (![obj isKindOfClass:[NSString class]] && ![obj isKindOfClass:[NSNumber class]]) { [FBSDKAppEventsUtility logAndNotify:[NSString stringWithFormat:@"The values in the parameters dictionary must be NSStrings or NSNumbers, '%@' is not.", obj]]; failed = YES; } } ]; if (failed) { return; } NSMutableDictionary *eventDictionary = [NSMutableDictionary dictionaryWithDictionary:parameters]; eventDictionary[FBSDKAppEventParameterEventName] = eventName; if (!eventDictionary[FBSDKAppEventParameterLogTime]) { eventDictionary[FBSDKAppEventParameterLogTime] = @([FBSDKAppEventsUtility unixTimeNow]); } [FBSDKInternalUtility dictionary:eventDictionary setObject:valueToSum forKey:@"_valueToSum"]; if (isImplicitlyLogged) { eventDictionary[FBSDKAppEventParameterImplicitlyLogged] = @"1"; } NSString *currentViewControllerName; if ([NSThread isMainThread]) { // We only collect the view controller when on the main thread, as the behavior off // the main thread is unpredictable. Besides, UI state for off-main-thread computations // isn't really relevant anyhow. UIViewController *vc = [UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController; if (vc) { currentViewControllerName = [[vc class] description]; } else { currentViewControllerName = @"no_ui"; } } else { currentViewControllerName = @"off_thread"; } eventDictionary[@"_ui"] = currentViewControllerName; NSString *tokenString = [FBSDKAppEventsUtility tokenStringToUseFor:accessToken]; NSString *appID = [self appID]; @synchronized (self) { if (!_appEventsState) { _appEventsState = [[FBSDKAppEventsState alloc] initWithToken:tokenString appID:appID]; } else if (![_appEventsState isCompatibleWithTokenString:tokenString appID:appID]) { if (self.flushBehavior == FBSDKAppEventsFlushBehaviorExplicitOnly) { [FBSDKAppEventsStateManager persistAppEventsData:_appEventsState]; } else { [self flushForReason:FBSDKAppEventsFlushReasonSessionChange]; } _appEventsState = [[FBSDKAppEventsState alloc] initWithToken:tokenString appID:appID]; } [_appEventsState addEvent:eventDictionary isImplicit:isImplicitlyLogged]; if (!isImplicitlyLogged) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAppEvents formatString:@"FBSDKAppEvents: Recording event @ %ld: %@", [FBSDKAppEventsUtility unixTimeNow], eventDictionary]; } [self checkPersistedEvents]; if (_appEventsState.events.count > NUM_LOG_EVENTS_TO_TRY_TO_FLUSH_AFTER && self.flushBehavior != FBSDKAppEventsFlushBehaviorExplicitOnly) { [self flushForReason:FBSDKAppEventsFlushReasonEventThreshold]; } } } // this fetches persisted event states. // for those matching the currently tracked events, add it. // otherwise, either flush (if not explicitonly behavior) or persist them back. - (void)checkPersistedEvents { NSArray *existingEventsStates = [FBSDKAppEventsStateManager retrievePersistedAppEventsStates]; if (existingEventsStates.count == 0) { return; } FBSDKAppEventsState *matchingEventsPreviouslySaved = nil; // reduce lock time by creating a new FBSDKAppEventsState to collect matching persisted events. @synchronized(self) { if (_appEventsState) { matchingEventsPreviouslySaved = [[FBSDKAppEventsState alloc] initWithToken:_appEventsState.tokenString appID:_appEventsState.appID]; } } for (FBSDKAppEventsState *saved in existingEventsStates) { if ([saved isCompatibleWithAppEventsState:matchingEventsPreviouslySaved]) { [matchingEventsPreviouslySaved addEventsFromAppEventState:saved]; } else { if (self.flushBehavior == FBSDKAppEventsFlushBehaviorExplicitOnly) { [FBSDKAppEventsStateManager persistAppEventsData:saved]; } else { dispatch_async(dispatch_get_main_queue(), ^{ [self flushOnMainQueue:saved forReason:FBSDKAppEventsFlushReasonPersistedEvents]; }); } } } if (matchingEventsPreviouslySaved.events.count > 0) { @synchronized(self) { if ([_appEventsState isCompatibleWithAppEventsState:matchingEventsPreviouslySaved]) { [_appEventsState addEventsFromAppEventState:matchingEventsPreviouslySaved]; } } } } - (void)flushOnMainQueue:(FBSDKAppEventsState *)appEventsState forReason:(FBSDKAppEventsFlushReason)reason { if (appEventsState.events.count == 0) { return; } [FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; [self fetchServerConfiguration:^(void) { NSString *JSONString = [appEventsState JSONStringForEvents:_serverConfiguration.implicitLoggingEnabled]; NSData *encodedEvents = [JSONString dataUsingEncoding:NSUTF8StringEncoding]; if (!encodedEvents) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAppEvents logEntry:@"FBSDKAppEvents: Flushing skipped - no events after removing implicitly logged ones.\n"]; return; } NSMutableDictionary *postParameters = [FBSDKAppEventsUtility activityParametersDictionaryForEvent:@"CUSTOM_APP_EVENTS" implicitEventsOnly:appEventsState.areAllEventsImplicit shouldAccessAdvertisingID:_serverConfiguration.advertisingIDEnabled]; postParameters[@"custom_events_file"] = encodedEvents; if (appEventsState.numSkipped > 0) { postParameters[@"num_skipped_events"] = [NSString stringWithFormat:@"%lu", (unsigned long)appEventsState.numSkipped]; } if (self.pushNotificationsDeviceTokenString) { postParameters[FBSDKActivitesParameterPushDeviceToken] = self.pushNotificationsDeviceTokenString; } NSString *loggingEntry = nil; if ([[FBSDKSettings loggingBehavior] containsObject:FBSDKLoggingBehaviorAppEvents]) { NSData *prettyJSONData = [NSJSONSerialization dataWithJSONObject:appEventsState.events options:NSJSONWritingPrettyPrinted error:NULL]; NSString *prettyPrintedJsonEvents = [[NSString alloc] initWithData:prettyJSONData encoding:NSUTF8StringEncoding]; // Remove this param -- just an encoding of the events which we pretty print later. NSMutableDictionary *paramsForPrinting = [postParameters mutableCopy]; [paramsForPrinting removeObjectForKey:@"custom_events_file"]; loggingEntry = [NSString stringWithFormat:@"FBSDKAppEvents: Flushed @ %ld, %lu events due to '%@' - %@\nEvents: %@", [FBSDKAppEventsUtility unixTimeNow], (unsigned long)appEventsState.events.count, [FBSDKAppEventsUtility flushReasonToString:reason], paramsForPrinting, prettyPrintedJsonEvents]; } FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/activities", appEventsState.appID] parameters:postParameters tokenString:appEventsState.tokenString HTTPMethod:@"POST" flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { [self handleActivitiesPostCompletion:error loggingEntry:loggingEntry appEventsState:(FBSDKAppEventsState *)appEventsState]; }]; }]; } - (void)handleActivitiesPostCompletion:(NSError *)error loggingEntry:(NSString *)loggingEntry appEventsState:(FBSDKAppEventsState *)appEventsState { typedef NS_ENUM(NSUInteger, FBSDKAppEventsFlushResult) { FlushResultSuccess, FlushResultServerError, FlushResultNoConnectivity }; [FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; FBSDKAppEventsFlushResult flushResult = FlushResultSuccess; if (error) { NSInteger errorCode = [error.userInfo[FBSDKGraphRequestErrorHTTPStatusCodeKey] integerValue]; // We interpret a 400 coming back from FBRequestConnection as a server error due to improper data being // sent down. Otherwise we assume no connectivity, or another condition where we could treat it as no connectivity. flushResult = errorCode == 400 ? FlushResultServerError : FlushResultNoConnectivity; } if (flushResult == FlushResultServerError) { // Only log events that developer can do something with (i.e., if parameters are incorrect). // as opposed to cases where the token is bad. if ([error.userInfo[FBSDKGraphRequestErrorCategoryKey] unsignedIntegerValue] == FBSDKGraphRequestErrorCategoryOther) { NSString *message = [NSString stringWithFormat:@"Failed to send AppEvents: %@", error]; [FBSDKAppEventsUtility logAndNotify:message allowLogAsDeveloperError:!appEventsState.areAllEventsImplicit]; } } else if (flushResult == FlushResultNoConnectivity) { @synchronized(self) { if ([appEventsState isCompatibleWithAppEventsState:_appEventsState]) { [_appEventsState addEventsFromAppEventState:appEventsState]; } else { // flush failed due to connectivity. Persist to be tried again later. [FBSDKAppEventsStateManager persistAppEventsData:appEventsState]; } } } NSString *resultString = @""; switch (flushResult) { case FlushResultSuccess: resultString = @"Success"; break; case FlushResultNoConnectivity: resultString = @"No Connectivity"; break; case FlushResultServerError: resultString = [NSString stringWithFormat:@"Server Error - %@", [error description]]; break; } [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAppEvents formatString:@"%@\nFlush Result : %@", loggingEntry, resultString]; } - (void)flushTimerFired:(id)arg { [FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; if (self.flushBehavior != FBSDKAppEventsFlushBehaviorExplicitOnly && !self.disableTimer) { [self flushForReason:FBSDKAppEventsFlushReasonTimer]; } } - (void)appSettingsFetchStateResetTimerFired:(id)arg { _serverConfiguration = nil; } - (void)applicationDidBecomeActive { [FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; [self checkPersistedEvents]; // Restore time spent data, indicating that we're not being called from "activateApp". [FBSDKTimeSpentData restore:NO]; } - (void)applicationMovingFromActiveStateOrTerminating { // When moving from active state, we don't have time to wait for the result of a flush, so // just persist events to storage, and we'll process them at the next activation. FBSDKAppEventsState *copy = nil; @synchronized (self) { copy = [_appEventsState copy]; _appEventsState = nil; } if (copy) { [FBSDKAppEventsStateManager persistAppEventsData:copy]; } [FBSDKTimeSpentData suspend]; } #pragma mark - Custom Audience + (FBSDKGraphRequest *)requestForCustomAudienceThirdPartyIDWithAccessToken:(FBSDKAccessToken *)accessToken { accessToken = accessToken ?: [FBSDKAccessToken currentAccessToken]; // Rules for how we use the attribution ID / advertiser ID for an 'custom_audience_third_party_id' Graph API request // 1) if the OS tells us that the user has Limited Ad Tracking, then just don't send, and return a nil in the token. // 2) if the app has set 'limitEventAndDataUsage', this effectively implies that app-initiated ad targeting shouldn't happen, // so use that data here to return nil as well. // 3) if we have a user session token, then no need to send attribution ID / advertiser ID back as the udid parameter // 4) otherwise, send back the udid parameter. if ([FBSDKAppEventsUtility advertisingTrackingStatus] == FBSDKAdvertisingTrackingDisallowed || [FBSDKSettings limitEventAndDataUsage]) { return nil; } NSString *tokenString = [FBSDKAppEventsUtility tokenStringToUseFor:accessToken]; NSString *udid = nil; if (!accessToken) { // We don't have a logged in user, so we need some form of udid representation. Prefer advertiser ID if // available, and back off to attribution ID if not. Note that this function only makes sense to be // called in the context of advertising. udid = [FBSDKAppEventsUtility advertiserID]; if (!udid) { udid = [FBSDKAppEventsUtility attributionID]; } if (!udid) { // No udid, and no user token. No point in making the request. return nil; } } NSDictionary *parameters = nil; if (udid) { parameters = @{ @"udid" : udid }; } NSString *graphPath = [NSString stringWithFormat:@"%@/custom_audience_third_party_id", [[self singleton] appID]]; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath parameters:parameters tokenString:tokenString HTTPMethod:nil flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; return request; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKAppLinkResolver.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @class BFTask; // Check if Bolts.framework is available for import #if __has_include() // Import it if it's available # import #else // Otherwise - redeclare BFAppLinkResolving protocol to resolve the problem of missing symbols // Please note: Bolts.framework is still required for AppLink resolving to work, // but this allows FBSDKCoreKit to weakly link Bolts.framework as well as this enables clang modulemaps to work. /*! Implement this protocol to provide an alternate strategy for resolving App Links that may include pre-fetching, caching, or querying for App Link data from an index provided by a service provider. */ @protocol BFAppLinkResolving /*! Asynchronously resolves App Link data for a given URL. @param url The URL to resolve into an App Link. @returns A BFTask that will return a BFAppLink for the given URL. */ - (BFTask *)appLinkFromURLInBackground:(NSURL *)url; @end #endif /*! @class FBSDKAppLinkResolver @abstract Provides an implementation of the BFAppLinkResolving protocol that uses the Facebook App Link Index API to resolve App Links given a URL. It also provides an additional helper method that can resolve multiple App Links in a single call. @discussion Usage of this type requires a client token. See `[FBSDKSettings setClientToken:]` and linking Bolts.framework */ @interface FBSDKAppLinkResolver : NSObject /*! @abstract Asynchronously resolves App Link data for multiple URLs. @param urls An array of NSURLs to resolve into App Links. @returns A BFTask that will return dictionary mapping input NSURLs to their corresponding BFAppLink. @discussion You should set the client token before making this call. See `[FBSDKSettings setClientToken:]` */ - (BFTask *)appLinksFromURLsInBackground:(NSArray *)urls; /*! @abstract Allocates and initializes a new instance of FBSDKAppLinkResolver. */ + (instancetype)resolver; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKAppLinkResolver.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAppLinkResolver.h" #import #import #import #import #import #import "FBSDKGraphRequest+Internal.h" #import "FBSDKGraphRequestConnection.h" #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKSettings+Internal.h" #import "FBSDKUtility.h" static NSString *const kURLKey = @"url"; static NSString *const kIOSAppStoreIdKey = @"app_store_id"; static NSString *const kIOSAppNameKey = @"app_name"; static NSString *const kWebKey = @"web"; static NSString *const kIOSKey = @"ios"; static NSString *const kIPhoneKey = @"iphone"; static NSString *const kIPadKey = @"ipad"; static NSString *const kShouldFallbackKey = @"should_fallback"; static NSString *const kAppLinksKey = @"app_links"; @interface FBSDKAppLinkResolver () @property (nonatomic, strong) NSMutableDictionary *cachedLinks; @property (nonatomic, assign) UIUserInterfaceIdiom userInterfaceIdiom; @end @implementation FBSDKAppLinkResolver static Class g_BFTaskCompletionSourceClass; static Class g_BFAppLinkTargetClass; static Class g_BFAppLinkClass; static Class g_BFTaskClass; + (void)initialize { if (self == [FBSDKAppLinkResolver class]) { g_BFTaskCompletionSourceClass = [FBSDKInternalUtility resolveBoltsClassWithName:@"BFTaskCompletionSource"]; g_BFAppLinkTargetClass = [FBSDKInternalUtility resolveBoltsClassWithName:@"BFAppLinkTarget"]; g_BFTaskClass = [FBSDKInternalUtility resolveBoltsClassWithName:@"BFTask"]; g_BFAppLinkClass = [FBSDKInternalUtility resolveBoltsClassWithName:@"BFAppLink"]; } } - (id)initWithUserInterfaceIdiom:(UIUserInterfaceIdiom)userInterfaceIdiom { if (self = [super init]) { self.cachedLinks = [NSMutableDictionary dictionary]; self.userInterfaceIdiom = userInterfaceIdiom; } return self; } - (BFTask *)appLinksFromURLsInBackground:(NSArray *)urls { if (![FBSDKSettings clientToken] && ![FBSDKAccessToken currentAccessToken]) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"A user access token or clientToken is required to use FBAppLinkResolver"]; } NSMutableDictionary *appLinks = [NSMutableDictionary dictionary]; NSMutableArray *toFind = [NSMutableArray array]; NSMutableArray *toFindStrings = [NSMutableArray array]; @synchronized (self.cachedLinks) { for (NSURL *url in urls) { if (self.cachedLinks[url]) { appLinks[url] = self.cachedLinks[url]; } else { [toFind addObject:url]; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" [toFindStrings addObject:[url.absoluteString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; #pragma clang diagnostic pop } } } if (toFind.count == 0) { // All of the URLs have already been found. return [g_BFTaskClass taskWithResult:appLinks]; } NSMutableArray *fields = [NSMutableArray arrayWithObject:kIOSKey]; NSString *idiomSpecificField = nil; switch (self.userInterfaceIdiom) { case UIUserInterfaceIdiomPad: idiomSpecificField = kIPadKey; break; case UIUserInterfaceIdiomPhone: idiomSpecificField = kIPhoneKey; break; default: break; } if (idiomSpecificField) { [fields addObject:idiomSpecificField]; } NSString *path = [NSString stringWithFormat:@"?fields=%@.fields(%@)&ids=%@", kAppLinksKey, [fields componentsJoinedByString:@","], [toFindStrings componentsJoinedByString:@","]]; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:path parameters:nil flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; BFTaskCompletionSource *tcs = [g_BFTaskCompletionSourceClass taskCompletionSource]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (error) { [tcs setError:error]; return; } for (NSURL *url in toFind) { id nestedObject = [[result objectForKey:url.absoluteString] objectForKey:kAppLinksKey]; NSMutableArray *rawTargets = [NSMutableArray array]; if (idiomSpecificField) { [rawTargets addObjectsFromArray:[nestedObject objectForKey:idiomSpecificField]]; } [rawTargets addObjectsFromArray:[nestedObject objectForKey:kIOSKey]]; NSMutableArray *targets = [NSMutableArray arrayWithCapacity:rawTargets.count]; for (id rawTarget in rawTargets) { [targets addObject:[g_BFAppLinkTargetClass appLinkTargetWithURL:[NSURL URLWithString:[rawTarget objectForKey:kURLKey]] appStoreId:[rawTarget objectForKey:kIOSAppStoreIdKey] appName:[rawTarget objectForKey:kIOSAppNameKey]]]; } id webTarget = [nestedObject objectForKey:kWebKey]; NSString *webFallbackString = [webTarget objectForKey:kURLKey]; NSURL *fallbackUrl = webFallbackString ? [NSURL URLWithString:webFallbackString] : url; NSNumber *shouldFallback = [webTarget objectForKey:kShouldFallbackKey]; if (shouldFallback && !shouldFallback.boolValue) { fallbackUrl = nil; } BFAppLink *link = [g_BFAppLinkClass appLinkWithSourceURL:url targets:targets webURL:fallbackUrl]; @synchronized (self.cachedLinks) { self.cachedLinks[url] = link; } appLinks[url] = link; } [tcs setResult:appLinks]; }]; return tcs.task; } - (BFTask *)appLinkFromURLInBackground:(NSURL *)url { // Implement in terms of appLinksFromURLsInBackground BFTask *resolveTask = [self appLinksFromURLsInBackground:@[url]]; return [resolveTask continueWithSuccessBlock:^id(BFTask *task) { return task.result[url]; }]; } + (id)resolver { return [[self alloc] initWithUserInterfaceIdiom:UI_USER_INTERFACE_IDIOM()]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKAppLinkUtility.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import /*! @abstract Describes the callback for fetchDeferredAppLink. @param url the url representing the deferred App Link @param error the error during the request, if any @discussion The url may also have a fb_click_time_utc query parameter that represents when the click occurred that caused the deferred App Link to be created. */ typedef void (^FBSDKDeferredAppLinkHandler)(NSURL *url, NSError *error); /*! @abstract Describes the callback for fetchOrganicDeferredAppLink. @param url the url representing the deferred App Link */ typedef void (^FBSDKDeferredAppInviteHandler)(NSURL *url); /*! @abstract Class containing App Links related utility methods. */ @interface FBSDKAppLinkUtility : NSObject /*! @abstract Call this method from the main thread to fetch deferred applink data if you use Mobile App Engagement Ads (https://developers.facebook.com/docs/ads-for-apps/mobile-app-ads-engagement). This may require a network round trip. If successful, the handler is invoked with the link data (this will only return a valid URL once, and future calls will result in a nil URL value in the callback). @param handler the handler to be invoked if there is deferred App Link data @discussion The handler may contain an NSError instance to capture any errors. In the common case where there simply was no app link data, the NSError instance will be nil. This method should only be called from a location that occurs after any launching URL has been processed (e.g., you should call this method from your application delegate's applicationDidBecomeActive:). */ + (void)fetchDeferredAppLink:(FBSDKDeferredAppLinkHandler)handler; /*! @deprecated This method is no longer available and will always return NO. */ + (BOOL)fetchDeferredAppInvite:(FBSDKDeferredAppInviteHandler)handler __attribute__((deprecated("This method is no longer available.")));; /* @abstract Call this method to fetch promotion code from the url, if it's present. This function requires Bolts framework. Note: This throws an exception if Bolts.framework is not linked. Add '[BFURL class]' in intialize method of your AppDelegate. @param url App Link url that was passed to the app. @return Promotion code string. @discussion Call this method to fetch App Invite Promotion Code from applink if present. This can be used to fetch the promotion code that was associated with the invite when it was created. This method should be called with the url from the openURL method. */ + (NSString*)appInvitePromotionCodeFromURL:(NSURL*)url; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKAppLinkUtility.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAppLinkUtility.h" #import #import "FBSDKAppEventsUtility.h" #import "FBSDKGraphRequest.h" #import "FBSDKInternalUtility.h" #import "FBSDKSettings.h" #import "FBSDKUtility.h" static NSString *const FBSDKLastDeferredAppLink = @"com.facebook.sdk:lastDeferredAppLink%@"; static NSString *const FBSDKDeferredAppLinkEvent = @"DEFERRED_APP_LINK"; @implementation FBSDKAppLinkUtility {} + (void)fetchDeferredAppLink:(FBSDKDeferredAppLinkHandler)handler { NSAssert([NSThread isMainThread], @"FBSDKAppLink fetchDeferredAppLink: must be invoked from main thread."); NSString *appID = [FBSDKSettings appID]; // Deferred app links are only currently used for engagement ads, thus we consider the app to be an advertising one. // If this is considered for organic, non-ads scenarios, we'll need to retrieve the FBAppEventsUtility.shouldAccessAdvertisingID // before we make this call. NSMutableDictionary *deferredAppLinkParameters = [FBSDKAppEventsUtility activityParametersDictionaryForEvent:FBSDKDeferredAppLinkEvent implicitEventsOnly:NO shouldAccessAdvertisingID:YES]; FBSDKGraphRequest *deferredAppLinkRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/activities", appID, nil] parameters:deferredAppLinkParameters tokenString:nil version:nil HTTPMethod:@"POST"]; [deferredAppLinkRequest startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { NSURL *applinkURL = nil; if (!error) { NSString *appLinkString = result[@"applink_url"]; if (appLinkString) { applinkURL = [NSURL URLWithString:appLinkString]; NSString *createTimeUtc = result[@"click_time"]; if (createTimeUtc) { // append/translate the create_time_utc so it can be used by clients NSString *modifiedURLString = [[applinkURL absoluteString] stringByAppendingFormat:@"%@fb_click_time_utc=%@", ([applinkURL query]) ? @"&" : @"?" , createTimeUtc ]; applinkURL = [NSURL URLWithString:modifiedURLString]; } } } if (handler) { dispatch_async(dispatch_get_main_queue(), ^{ handler(applinkURL, error); }); } }]; } + (BOOL)fetchDeferredAppInvite:(FBSDKDeferredAppInviteHandler)handler { return NO; } + (NSString*)appInvitePromotionCodeFromURL:(NSURL*)url; { BFURL *parsedUrl = [[FBSDKInternalUtility resolveBoltsClassWithName:@"BFURL"] URLWithURL:url]; NSDictionary *extras = [parsedUrl appLinkExtras]; if (extras) { NSString *deeplinkContextString = extras[@"deeplink_context"]; // Parse deeplinkContext and extract promo code if ([deeplinkContextString length] > 0) { NSError *error = nil; NSDictionary *deeplinkContextData = [FBSDKInternalUtility objectForJSONString:deeplinkContextString error:&error]; if (!error && [deeplinkContextData isKindOfClass:[NSDictionary class]]) { return deeplinkContextData[@"promo_code"]; } } } return nil; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import /*! @class FBSDKApplicationDelegate @abstract The FBSDKApplicationDelegate is designed to post process the results from Facebook Login or Facebook Dialogs (or any action that requires switching over to the native Facebook app or Safari). @discussion The methods in this class are designed to mirror those in UIApplicationDelegate, and you should call them in the respective methods in your AppDelegate implementation. */ @interface FBSDKApplicationDelegate : NSObject /*! @abstract Gets the singleton instance. */ + (instancetype)sharedInstance; /*! @abstract Call this method from the [UIApplicationDelegate application:openURL:sourceApplication:annotation:] method of the AppDelegate for your app. It should be invoked for the proper processing of responses during interaction with the native Facebook app or Safari as part of SSO authorization flow or Facebook dialogs. @param application The application as passed to [UIApplicationDelegate application:openURL:sourceApplication:annotation:]. @param url The URL as passed to [UIApplicationDelegate application:openURL:sourceApplication:annotation:]. @param sourceApplication The sourceApplication as passed to [UIApplicationDelegate application:openURL:sourceApplication:annotation:]. @param annotation The annotation as passed to [UIApplicationDelegate application:openURL:sourceApplication:annotation:]. @return YES if the url was intended for the Facebook SDK, NO if not. */ - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; /*! @abstract Call this method from the [UIApplicationDelegate application:didFinishLaunchingWithOptions:] method of the AppDelegate for your app. It should be invoked for the proper use of the Facebook SDK. @param application The application as passed to [UIApplicationDelegate application:didFinishLaunchingWithOptions:]. @param launchOptions The launchOptions as passed to [UIApplicationDelegate application:didFinishLaunchingWithOptions:]. @return YES if the url was intended for the Facebook SDK, NO if not. */ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKApplicationDelegate.h" #import "FBSDKApplicationDelegate+Internal.h" #import #import "FBSDKAppEvents+Internal.h" #import "FBSDKConstants.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKError.h" #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKServerConfiguration.h" #import "FBSDKServerConfigurationManager.h" #import "FBSDKSettings+Internal.h" #import "FBSDKTimeSpentData.h" #import "FBSDKUtility.h" #if !TARGET_OS_TV #import "FBSDKBoltsMeasurementEventListener.h" #import "FBSDKBridgeAPIRequest.h" #import "FBSDKBridgeAPIResponse.h" #import "FBSDKContainerViewController.h" #import "FBSDKProfile+Internal.h" #endif NSString *const FBSDKApplicationDidBecomeActiveNotification = @"com.facebook.sdk.FBSDKApplicationDidBecomeActiveNotification"; static NSString *const FBSDKAppLinkInboundEvent = @"fb_al_inbound"; @implementation FBSDKApplicationDelegate { #if !TARGET_OS_TV FBSDKBridgeAPIRequest *_pendingRequest; FBSDKBridgeAPICallbackBlock _pendingRequestCompletionBlock; id _pendingURLOpen; #endif BOOL _expectingBackground; UIViewController *_safariViewController; } #pragma mark - Class Methods + (void)load { // when the app becomes active by any means, kick off the initialization. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(initializeWithLaunchData:) name:UIApplicationDidFinishLaunchingNotification object:nil]; } // Initialize SDK listeners // Don't call this function in any place else. It should only be called when the class is loaded. + (void)initializeWithLaunchData:(NSNotification *)note { NSDictionary *launchData = note.userInfo; #if !TARGET_OS_TV // Register Listener for Bolts measurement events [FBSDKBoltsMeasurementEventListener defaultListener]; #endif // Set the SourceApplication for time spent data. This is not going to update the value if the app has already launched. [FBSDKTimeSpentData setSourceApplication:launchData[UIApplicationLaunchOptionsSourceApplicationKey] openURL:launchData[UIApplicationLaunchOptionsURLKey]]; // Register on UIApplicationDidEnterBackgroundNotification events to reset source application data when app backgrounds. [FBSDKTimeSpentData registerAutoResetSourceApplication]; [FBSDKInternalUtility validateFacebookReservedURLSchemes]; // Remove the observer [[NSNotificationCenter defaultCenter] removeObserver:self]; } + (instancetype)sharedInstance { static FBSDKApplicationDelegate *_sharedInstance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _sharedInstance = [[self alloc] _init]; }); return _sharedInstance; } #pragma mark - Object Lifecycle - (instancetype)_init { if ((self = [super init]) != nil) { NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; [defaultCenter addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil]; [defaultCenter addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil]; } return self; } - (instancetype)init { return nil; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } #pragma mark - UIApplicationDelegate - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { if (sourceApplication != nil && ![sourceApplication isKindOfClass:[NSString class]]) { @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"Expected 'sourceApplication' to be NSString. Please verify you are passing in 'sourceApplication' from your app delegate (not the UIApplication* parameter). If your app delegate implements iOS 9's application:openURL:options:, you should pass in options[UIApplicationOpenURLOptionsSourceApplicationKey]. " userInfo:nil]; } [FBSDKTimeSpentData setSourceApplication:sourceApplication openURL:url]; #if !TARGET_OS_TV // if they completed a SFVC flow, dismiss it. [_safariViewController.presentingViewController dismissViewControllerAnimated:YES completion: nil]; _safariViewController = nil; if (_pendingURLOpen) { id pendingURLOpen = _pendingURLOpen; _pendingURLOpen = nil; if ([pendingURLOpen application:application openURL:url sourceApplication:sourceApplication annotation:annotation]) { return YES; } } if ([self _handleBridgeAPIResponseURL:url sourceApplication:sourceApplication]) { return YES; } #endif [self _logIfAppLinkEvent:url]; return NO; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { FBSDKAccessToken *cachedToken = [[FBSDKSettings accessTokenCache] fetchAccessToken]; [FBSDKAccessToken setCurrentAccessToken:cachedToken]; #if !TARGET_OS_TV FBSDKProfile *cachedProfile = [FBSDKProfile fetchCachedProfile]; [FBSDKProfile setCurrentProfile:cachedProfile]; NSURL *launchedURL = launchOptions[UIApplicationLaunchOptionsURLKey]; NSString *sourceApplication = launchOptions[UIApplicationLaunchOptionsSourceApplicationKey]; if (launchedURL && sourceApplication) { Class loginManagerClass = NSClassFromString(@"FBSDKLoginManager"); if (loginManagerClass) { id annotation = launchOptions[UIApplicationLaunchOptionsAnnotationKey]; id loginManager = [[loginManagerClass alloc] init]; return [loginManager application:application openURL:launchedURL sourceApplication:sourceApplication annotation:annotation]; } } #endif return NO; } - (void)applicationDidEnterBackground:(NSNotification *)notification { _active = NO; _expectingBackground = NO; } - (void)applicationDidBecomeActive:(NSNotification *)notification { // _expectingBackground can be YES if the caller started doing work (like login) // within the app delegate's lifecycle like openURL, in which case there // might have been a "didBecomeActive" event pending that we want to ignore. if (!_expectingBackground && !_safariViewController) { _active = YES; #if !TARGET_OS_TV [_pendingURLOpen applicationDidBecomeActive:[notification object]]; [self _cancelBridgeRequest]; #endif [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKApplicationDidBecomeActiveNotification object:self]; } } #pragma mark - Internal Methods #pragma mark -- (non-tvos) #if !TARGET_OS_TV - (void)openURL:(NSURL *)url sender:(id)sender handler:(void(^)(BOOL))handler { _expectingBackground = YES; _pendingURLOpen = sender; dispatch_async(dispatch_get_main_queue(), ^{ // Dispatch openURL calls to prevent hangs if we're inside the current app delegate's openURL flow already BOOL opened = [[UIApplication sharedApplication] openURL:url]; if ([url.scheme hasPrefix:@"http"] && !opened) { NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; if (![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) { // Safari openURL calls can wrongly return NO on iOS 7 so manually overwrite that case to YES. // Otherwise we would rather trust in the actual result of openURL opened = YES; } } if (handler) { handler(opened); } }); } - (void)openBridgeAPIRequest:(FBSDKBridgeAPIRequest *)request useSafariViewController:(BOOL)useSafariViewController fromViewController:(UIViewController *)fromViewController completionBlock:(FBSDKBridgeAPICallbackBlock)completionBlock { if (!request) { return; } NSError *error; NSURL *requestURL = [request requestURL:&error]; if (!requestURL) { FBSDKBridgeAPIResponse *response = [FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request error:error]; completionBlock(response); return; } _pendingRequest = request; _pendingRequestCompletionBlock = [completionBlock copy]; void (^handler)(BOOL) = ^(BOOL openedURL) { if (!openedURL) { _pendingRequest = nil; _pendingRequestCompletionBlock = nil; NSError *openedURLError; if ([request.scheme hasPrefix:@"http"]) { openedURLError = [FBSDKError errorWithCode:FBSDKBrowserUnavailableErrorCode message:@"the app switch failed because the browser is unavailable"]; } else { openedURLError = [FBSDKError errorWithCode:FBSDKAppVersionUnsupportedErrorCode message:@"the app switch failed because the destination app is out of date"]; } FBSDKBridgeAPIResponse *response = [FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request error:openedURLError]; completionBlock(response); return; } }; if (useSafariViewController) { [self openURLWithSafariViewController:requestURL sender:nil fromViewController:fromViewController handler:handler]; } else { [self openURL:requestURL sender:nil handler:handler]; } } - (void)openURLWithSafariViewController:(NSURL *)url sender:(id)sender fromViewController:(UIViewController *)fromViewController handler:(void(^)(BOOL))handler { if (![url.scheme hasPrefix:@"http"]) { [self openURL:url sender:sender handler:handler]; return; } _expectingBackground = NO; _pendingURLOpen = sender; // trying to dynamically load SFSafariViewController class // so for the cases when it is available we can send users through Safari View Controller flow // in cases it is not available regular flow will be selected Class SFSafariViewControllerClass = fbsdkdfl_SFSafariViewControllerClass(); if (SFSafariViewControllerClass) { UIViewController *parent = fromViewController ?: [FBSDKInternalUtility topMostViewController]; NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO]; NSURLQueryItem *sfvcQueryItem = [[NSURLQueryItem alloc] initWithName:@"sfvc" value:@"1"]; [components setQueryItems:[components.queryItems arrayByAddingObject:sfvcQueryItem]]; url = components.URL; FBSDKContainerViewController *container = [[FBSDKContainerViewController alloc] init]; container.delegate = self; if (parent.transitionCoordinator != nil) { // Wait until the transition is finished before presenting SafariVC to avoid a blank screen. [parent.transitionCoordinator animateAlongsideTransition:NULL completion:^(id context) { // Note SFVC init must occur inside block to avoid blank screen. _safariViewController = [[SFSafariViewControllerClass alloc] initWithURL:url]; // Disable dismissing with edge pan gesture _safariViewController.modalPresentationStyle = UIModalPresentationOverFullScreen; [_safariViewController performSelector:@selector(setDelegate:) withObject:self]; [container displayChildController:_safariViewController]; [parent presentViewController:container animated:YES completion:nil]; }]; } else { _safariViewController = [[SFSafariViewControllerClass alloc] initWithURL:url]; // Disable dismissing with edge pan gesture _safariViewController.modalPresentationStyle = UIModalPresentationOverFullScreen; [_safariViewController performSelector:@selector(setDelegate:) withObject:self]; [container displayChildController:_safariViewController]; [parent presentViewController:container animated:YES completion:nil]; } // Assuming Safari View Controller always opens if (handler) { handler(YES); } } else { [self openURL:url sender:sender handler:handler]; } } #pragma mark -- SFSafariViewControllerDelegate // This means the user tapped "Done" which we should treat as a cancellation. - (void)safariViewControllerDidFinish:(UIViewController *)safariViewController { if (_pendingURLOpen) { id pendingURLOpen = _pendingURLOpen; _pendingURLOpen = nil; [pendingURLOpen application:nil openURL:nil sourceApplication:nil annotation:nil]; } [self _cancelBridgeRequest]; _safariViewController = nil; } #pragma mark -- FBSDKContainerViewControllerDelegate - (void)viewControllerDidDisappear:(FBSDKContainerViewController *)viewController animated:(BOOL)animated { if (_safariViewController) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"**ERROR**:\n The SFSafariViewController's parent view controller was dismissed.\n" "This can happen if you are triggering login from a UIAlertController. Instead, make sure your top most view " "controller will not be prematurely dismissed."]; [self safariViewControllerDidFinish:_safariViewController]; } } #endif #pragma mark - Helper Methods - (void)_logIfAppLinkEvent:(NSURL *)url { if (!url) { return; } NSDictionary *params = [FBSDKUtility dictionaryWithQueryString:url.query]; NSString *applinkDataString = params[@"al_applink_data"]; if (!applinkDataString) { return; } NSDictionary * applinkData = [FBSDKInternalUtility objectForJSONString:applinkDataString error:NULL]; if (!applinkData) { return; } NSURL *targetURL = [NSURL URLWithString:applinkData[@"target_url"]]; NSMutableDictionary *logData = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:logData setObject:[targetURL absoluteString] forKey:@"targetURL"]; [FBSDKInternalUtility dictionary:logData setObject:[targetURL host] forKey:@"targetURLHost"]; NSDictionary *refererData = applinkData[@"referer_data"]; if (refererData) { [FBSDKInternalUtility dictionary:logData setObject:refererData[@"target_url"] forKey:@"referralTargetURL"]; [FBSDKInternalUtility dictionary:logData setObject:refererData[@"url"] forKey:@"referralURL"]; [FBSDKInternalUtility dictionary:logData setObject:refererData[@"app_name"] forKey:@"referralAppName"]; } [FBSDKInternalUtility dictionary:logData setObject:[url absoluteString] forKey:@"inputURL"]; [FBSDKInternalUtility dictionary:logData setObject:[url scheme] forKey:@"inputURLScheme"]; [FBSDKAppEvents logImplicitEvent:FBSDKAppLinkInboundEvent valueToSum:nil parameters:logData accessToken:nil]; } #pragma mark -- (non-tvos) #if !TARGET_OS_TV - (BOOL)_handleBridgeAPIResponseURL:(NSURL *)responseURL sourceApplication:(NSString *)sourceApplication { FBSDKBridgeAPIRequest *request = _pendingRequest; FBSDKBridgeAPICallbackBlock completionBlock = _pendingRequestCompletionBlock; _pendingRequest = nil; _pendingRequestCompletionBlock = NULL; if (![responseURL.scheme isEqualToString:[FBSDKInternalUtility appURLScheme]]) { return NO; } if (![responseURL.host isEqualToString:@"bridge"]) { return NO; } if (!request) { return NO; } if (!completionBlock) { return YES; } NSError *error; FBSDKBridgeAPIResponse *response = [FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request responseURL:responseURL sourceApplication:sourceApplication error:&error]; if (response) { completionBlock(response); return YES; } else if (error) { completionBlock([FBSDKBridgeAPIResponse bridgeAPIResponseWithRequest:request error:error]); return YES; } else { return NO; } } - (void)_cancelBridgeRequest { if (_pendingRequest && _pendingRequestCompletionBlock) { _pendingRequestCompletionBlock([FBSDKBridgeAPIResponse bridgeAPIResponseCancelledWithRequest:_pendingRequest]); } _pendingRequest = nil; _pendingRequestCompletionBlock = NULL; } #endif @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKButton.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import /*! @abstract A base class for common SDK buttons. */ @interface FBSDKButton : UIButton @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKButton.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKButton.h" #import "FBSDKButton+Subclass.h" #import "FBSDKAccessToken.h" #import "FBSDKAppEvents+Internal.h" #import "FBSDKAppEvents.h" #import "FBSDKApplicationDelegate+Internal.h" #import "FBSDKLogo.h" #import "FBSDKMath.h" #import "FBSDKUIUtility.h" #import "FBSDKViewImpressionTracker.h" #define HEIGHT_TO_FONT_SIZE 0.47 #define HEIGHT_TO_MARGIN 0.27 #define HEIGHT_TO_PADDING 0.23 #define HEIGHT_TO_TEXT_PADDING_CORRECTION 0.08 @implementation FBSDKButton { BOOL _skipIntrinsicContentSizing; BOOL _isExplicitlyDisabled; } #pragma mark - Object Lifecycle - (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { _skipIntrinsicContentSizing = YES; [self configureButton]; _skipIntrinsicContentSizing = NO; } return self; } - (void)awakeFromNib { [super awakeFromNib]; _skipIntrinsicContentSizing = YES; [self configureButton]; _skipIntrinsicContentSizing = NO; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } #pragma mark - Properties - (void)setEnabled:(BOOL)enabled { _isExplicitlyDisabled = !enabled; [self checkImplicitlyDisabled]; } #pragma mark - Layout - (CGRect)imageRectForContentRect:(CGRect)contentRect { if ([self isHidden] || CGRectIsEmpty(self.bounds)) { return CGRectZero; } CGRect imageRect = UIEdgeInsetsInsetRect(contentRect, self.imageEdgeInsets); CGFloat margin = [self _marginForHeight:[self _heightForContentRect:contentRect]]; imageRect = CGRectInset(imageRect, margin, margin); imageRect.size.width = CGRectGetHeight(imageRect); return imageRect; } - (CGSize)intrinsicContentSize { if (_skipIntrinsicContentSizing) { return CGSizeZero; } _skipIntrinsicContentSizing = YES; CGSize size = [self sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; _skipIntrinsicContentSizing = NO; return size; } - (void)layoutSubviews { // automatic impression tracking if the button conforms to FBSDKButtonImpressionTracking if ([self conformsToProtocol:@protocol(FBSDKButtonImpressionTracking)]) { NSString *eventName = [(id)self impressionTrackingEventName]; NSString *identifier = [(id)self impressionTrackingIdentifier]; NSDictionary *parameters = [(id)self analyticsParameters]; if (eventName && identifier) { FBSDKViewImpressionTracker *impressionTracker = [FBSDKViewImpressionTracker impressionTrackerWithEventName:eventName]; [impressionTracker logImpressionWithIdentifier:identifier parameters:parameters]; } } [super layoutSubviews]; } - (CGSize)sizeThatFits:(CGSize)size { if ([self isHidden]) { return CGSizeZero; } CGSize normalSize = [self sizeThatFits:size title:[self titleForState:UIControlStateNormal]]; CGSize selectedSize = [self sizeThatFits:size title:[self titleForState:UIControlStateSelected]]; return CGSizeMake(MAX(normalSize.width, selectedSize.width), MAX(normalSize.height, selectedSize.height)); } - (void)sizeToFit { CGRect bounds = self.bounds; bounds.size = [self sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; self.bounds = bounds; } - (CGRect)titleRectForContentRect:(CGRect)contentRect { if ([self isHidden] || CGRectIsEmpty(self.bounds)) { return CGRectZero; } CGRect imageRect = [self imageRectForContentRect:contentRect]; CGFloat height = [self _heightForContentRect:contentRect]; CGFloat padding = [self _paddingForHeight:height]; CGFloat titleX = CGRectGetMaxX(imageRect) + padding; CGRect titleRect = CGRectMake(titleX, 0.0, CGRectGetWidth(contentRect) - titleX, CGRectGetHeight(contentRect)); UIEdgeInsets titleEdgeInsets = UIEdgeInsetsZero; if (!self.layer.needsLayout) { UILabel *titleLabel = self.titleLabel; if (titleLabel.textAlignment == NSTextAlignmentCenter) { // if the text is centered, we need to adjust the frame for the titleLabel based on the size of the text in order // to keep the text centered in the button without adding extra blank space to the right when unnecessary // 1. the text fits centered within the button without colliding with the image (imagePaddingWidth) // 2. the text would run into the image, so adjust the insets to effectively left align it (textPaddingWidth) CGSize titleSize = FBSDKTextSize(titleLabel.text, titleLabel.font, titleRect.size, titleLabel.lineBreakMode); CGFloat titlePaddingWidth = (CGRectGetWidth(titleRect) - titleSize.width) / 2; CGFloat imagePaddingWidth = titleX / 2; CGFloat inset = MIN(titlePaddingWidth, imagePaddingWidth); titleEdgeInsets.left -= inset; titleEdgeInsets.right += inset; } } return UIEdgeInsetsInsetRect(titleRect, titleEdgeInsets); } #pragma mark - Subclass Methods - (void)logTapEventWithEventName:(NSString *)eventName parameters:(NSDictionary *)parameters { [FBSDKAppEvents logImplicitEvent:eventName valueToSum:nil parameters:parameters accessToken:[FBSDKAccessToken currentAccessToken]]; } - (void)checkImplicitlyDisabled { BOOL enabled = !_isExplicitlyDisabled && ![self isImplicitlyDisabled]; BOOL currentEnabled = [self isEnabled]; [super setEnabled:enabled]; if (currentEnabled != enabled) { [self invalidateIntrinsicContentSize]; [self setNeedsLayout]; } } - (void)configureButton { [self configureWithIcon:[[self class] defaultIcon] title:nil backgroundColor:[[self class] defaultBackgroundColor] highlightedColor:[[self class] defaultHighlightedColor]]; } - (void)configureWithIcon:(FBSDKIcon *)icon title:(NSString *)title backgroundColor:(UIColor *)backgroundColor highlightedColor:(UIColor *)highlightedColor { [self _configureWithIcon:icon title:title backgroundColor:backgroundColor highlightedColor:highlightedColor selectedTitle:nil selectedIcon:nil selectedColor:nil selectedHighlightedColor:nil]; } - (void)configureWithIcon:(FBSDKIcon *)icon title:(NSString *)title backgroundColor:(UIColor *)backgroundColor highlightedColor:(UIColor *)highlightedColor selectedTitle:(NSString *)selectedTitle selectedIcon:(FBSDKIcon *)selectedIcon selectedColor:(UIColor *)selectedColor selectedHighlightedColor:(UIColor *)selectedHighlightedColor { if (!selectedColor) { selectedColor = [self defaultSelectedColor]; } if (!selectedHighlightedColor) { selectedHighlightedColor = highlightedColor; } [self _configureWithIcon:icon title:title backgroundColor:backgroundColor highlightedColor:highlightedColor selectedTitle:selectedTitle selectedIcon:selectedIcon selectedColor:selectedColor selectedHighlightedColor:selectedHighlightedColor]; } - (UIColor *)defaultBackgroundColor { return [UIColor colorWithRed:65.0/255.0 green:93.0/255.0 blue:174.0/255.0 alpha:1.0]; } - (UIColor *)defaultDisabledColor { return [UIColor colorWithRed:189.0/255.0 green:193.0/255.0 blue:201.0/255.0 alpha:1.0]; } - (UIFont *)defaultFont { return [UIFont systemFontOfSize:14]; } - (UIColor *)defaultHighlightedColor { return [UIColor colorWithRed:47.0/255.0 green:71.0/255.0 blue:122.0/255.0 alpha:1.0]; } - (FBSDKIcon *)defaultIcon { return [[FBSDKLogo alloc] init]; } - (UIColor *)defaultSelectedColor { return [UIColor colorWithRed:124.0/255.0 green:143.0/255.0 blue:200.0/255.0 alpha:1.0]; } - (BOOL)isImplicitlyDisabled { return NO; } - (CGSize)sizeThatFits:(CGSize)size title:(NSString *)title { UIFont *font = self.titleLabel.font; CGFloat height = [self _heightForFont:font]; UIEdgeInsets contentEdgeInsets = self.contentEdgeInsets; CGSize constrainedContentSize = FBSDKEdgeInsetsInsetSize(size, contentEdgeInsets); CGSize titleSize = FBSDKTextSize(title, font, constrainedContentSize, self.titleLabel.lineBreakMode); CGFloat padding = [self _paddingForHeight:height]; CGFloat textPaddingCorrection = [self _textPaddingCorrectionForHeight:height]; CGSize contentSize = CGSizeMake(height + padding + titleSize.width - textPaddingCorrection, height); return FBSDKEdgeInsetsOutsetSize(contentSize, contentEdgeInsets); } #pragma mark - Helper Methods - (void)_applicationDidBecomeActiveNotification:(NSNotification *)notification { [self checkImplicitlyDisabled]; } - (UIImage *)_backgroundImageWithColor:(UIColor *)color cornerRadius:(CGFloat)cornerRadius scale:(CGFloat)scale { CGFloat size = 1.0 + 2 * cornerRadius; UIGraphicsBeginImageContextWithOptions(CGSizeMake(size, size), NO, scale); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, color.CGColor); CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, NULL, cornerRadius + 1.0, 0.0); CGPathAddArcToPoint(path, NULL, size, 0.0, size, cornerRadius, cornerRadius); CGPathAddLineToPoint(path, NULL, size, cornerRadius + 1.0); CGPathAddArcToPoint(path, NULL, size, size, cornerRadius + 1.0, size, cornerRadius); CGPathAddLineToPoint(path, NULL, cornerRadius, size); CGPathAddArcToPoint(path, NULL, 0.0, size, 0.0, cornerRadius + 1.0, cornerRadius); CGPathAddLineToPoint(path, NULL, 0.0, cornerRadius); CGPathAddArcToPoint(path, NULL, 0.0, 0.0, cornerRadius, 0.0, cornerRadius); CGPathCloseSubpath(path); CGContextAddPath(context, path); CGPathRelease(path); CGContextFillPath(context); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); #if TARGET_OS_TV return [image resizableImageWithCapInsets:UIEdgeInsetsMake(cornerRadius, cornerRadius, cornerRadius, cornerRadius) resizingMode:UIImageResizingModeStretch]; #else return [image stretchableImageWithLeftCapWidth:cornerRadius topCapHeight:cornerRadius]; #endif } - (void)_configureWithIcon:(FBSDKIcon *)icon title:(NSString *)title backgroundColor:(UIColor *)backgroundColor highlightedColor:(UIColor *)highlightedColor selectedTitle:(NSString *)selectedTitle selectedIcon:(FBSDKIcon *)selectedIcon selectedColor:(UIColor *)selectedColor selectedHighlightedColor:(UIColor *)selectedHighlightedColor { [self checkImplicitlyDisabled]; if (!icon) { icon = [self defaultIcon]; } if (!backgroundColor) { backgroundColor = [self defaultBackgroundColor]; } if (!highlightedColor) { highlightedColor = [self defaultHighlightedColor]; } self.adjustsImageWhenDisabled = NO; self.adjustsImageWhenHighlighted = NO; self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentFill; self.contentVerticalAlignment = UIControlContentVerticalAlignmentFill; self.tintColor = [UIColor whiteColor]; BOOL forceSizeToFit = CGRectIsEmpty(self.bounds); CGFloat scale = [UIScreen mainScreen].scale; UIImage *backgroundImage; backgroundImage = [self _backgroundImageWithColor:backgroundColor cornerRadius:3.0 scale:scale]; [self setBackgroundImage:backgroundImage forState:UIControlStateNormal]; #if TARGET_OS_TV [self setBackgroundImage:backgroundImage forState:UIControlStateFocused]; #endif backgroundImage = [self _backgroundImageWithColor:highlightedColor cornerRadius:3.0 scale:scale]; [self setBackgroundImage:backgroundImage forState:UIControlStateHighlighted]; backgroundImage = [self _backgroundImageWithColor:[self defaultDisabledColor] cornerRadius:3.0 scale:scale]; [self setBackgroundImage:backgroundImage forState:UIControlStateDisabled]; if (selectedColor) { backgroundImage = [self _backgroundImageWithColor:selectedColor cornerRadius:3.0 scale:scale]; [self setBackgroundImage:backgroundImage forState:UIControlStateSelected]; } if (selectedHighlightedColor) { backgroundImage = [self _backgroundImageWithColor:selectedHighlightedColor cornerRadius:3.0 scale:scale]; [self setBackgroundImage:backgroundImage forState:UIControlStateSelected | UIControlStateHighlighted]; #if TARGET_OS_TV [self setBackgroundImage:backgroundImage forState:UIControlStateSelected | UIControlStateFocused]; #endif } [self setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; [self setTitle:title forState:UIControlStateNormal]; #if TARGET_OS_TV [self setTitle:title forState:UIControlStateFocused]; #endif if (selectedTitle) { [self setTitle:selectedTitle forState:UIControlStateSelected]; [self setTitle:selectedTitle forState:UIControlStateSelected | UIControlStateHighlighted]; #if TARGET_OS_TV [self setTitle:selectedTitle forState:UIControlStateSelected | UIControlStateFocused]; #endif } UILabel *titleLabel = self.titleLabel; titleLabel.lineBreakMode = NSLineBreakByClipping; UIFont *font = [self defaultFont]; titleLabel.font = font; CGSize imageSize = CGSizeMake(font.pointSize, font.pointSize); UIImage *image = [icon imageWithSize:imageSize]; image = [image resizableImageWithCapInsets:UIEdgeInsetsZero resizingMode:UIImageResizingModeStretch]; [self setImage:image forState:UIControlStateNormal]; #if TARGET_OS_TV [self setImage:image forState:UIControlStateFocused]; #endif if (selectedIcon) { UIImage *selectedImage = [selectedIcon imageWithSize:imageSize]; selectedImage = [selectedImage resizableImageWithCapInsets:UIEdgeInsetsZero resizingMode:UIImageResizingModeStretch]; [self setImage:selectedImage forState:UIControlStateSelected]; [self setImage:selectedImage forState:UIControlStateSelected | UIControlStateHighlighted]; #if TARGET_OS_TV [self setImage:selectedImage forState:UIControlStateSelected | UIControlStateFocused]; #endif } if (forceSizeToFit) { [self sizeToFit]; } [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationDidBecomeActiveNotification:) name:FBSDKApplicationDidBecomeActiveNotification object:[FBSDKApplicationDelegate sharedInstance]]; } - (CGFloat)_fontSizeForHeight:(CGFloat)height { return floorf(height * HEIGHT_TO_FONT_SIZE); } - (CGFloat)_heightForContentRect:(CGRect)contentRect { UIEdgeInsets contentEdgeInsets = self.contentEdgeInsets; return contentEdgeInsets.top + CGRectGetHeight(contentRect) + contentEdgeInsets.bottom; } - (CGFloat)_heightForFont:(UIFont *)font { return floorf(font.pointSize / (1 - 2 * HEIGHT_TO_MARGIN)); } - (CGFloat)_marginForHeight:(CGFloat)height { return floorf(height * HEIGHT_TO_MARGIN); } - (CGFloat)_paddingForHeight:(CGFloat)height { return roundf(height * HEIGHT_TO_PADDING) - [self _textPaddingCorrectionForHeight:height]; } - (CGFloat)_textPaddingCorrectionForHeight:(CGFloat)height { return floorf(height * HEIGHT_TO_TEXT_PADDING_CORRECTION); } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKConstants.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /*! @abstract The error domain for all errors from FBSDKCoreKit. @discussion Error codes from the SDK in the range 0-99 are reserved for this domain. */ FBSDK_EXTERN NSString *const FBSDKErrorDomain; /*! @typedef NS_ENUM(NSInteger, FBSDKErrorCode) @abstract Error codes for FBSDKErrorDomain. */ typedef NS_ENUM(NSInteger, FBSDKErrorCode) { /*! @abstract Reserved. */ FBSDKReservedErrorCode = 0, /*! @abstract The error code for errors from invalid encryption on incoming encryption URLs. */ FBSDKEncryptionErrorCode, /*! @abstract The error code for errors from invalid arguments to SDK methods. */ FBSDKInvalidArgumentErrorCode, /*! @abstract The error code for unknown errors. */ FBSDKUnknownErrorCode, /*! @abstract A request failed due to a network error. Use NSUnderlyingErrorKey to retrieve the error object from the NSURLConnection for more information. */ FBSDKNetworkErrorCode, /*! @abstract The error code for errors encountered during an App Events flush. */ FBSDKAppEventsFlushErrorCode, /*! @abstract An endpoint that returns a binary response was used with FBSDKGraphRequestConnection. @discussion Endpoints that return image/jpg, etc. should be accessed using NSURLRequest */ FBSDKGraphRequestNonTextMimeTypeReturnedErrorCode, /*! @abstract The operation failed because the server returned an unexpected response. @discussion You can get this error if you are not using the most recent SDK, or you are accessing a version of the Graph API incompatible with the current SDK. */ FBSDKGraphRequestProtocolMismatchErrorCode, /*! @abstract The Graph API returned an error. @discussion See below for useful userInfo keys (beginning with FBSDKGraphRequestError*) */ FBSDKGraphRequestGraphAPIErrorCode, /*! @abstract The specified dialog configuration is not available. @discussion This error may signify that the configuration for the dialogs has not yet been downloaded from the server or that the dialog is unavailable. Subsequent attempts to use the dialog may succeed as the configuration is loaded. */ FBSDKDialogUnavailableErrorCode, /*! @abstract Indicates an operation failed because a required access token was not found. */ FBSDKAccessTokenRequiredErrorCode, /*! @abstract Indicates an app switch (typically for a dialog) failed because the destination app is out of date. */ FBSDKAppVersionUnsupportedErrorCode, /*! @abstract Indicates an app switch to the browser (typically for a dialog) failed. */ FBSDKBrowserUnavailableErrorCode, /*! @deprecated use FBSDKBrowserUnavailableErrorCode instead */ FBSDKBrowswerUnavailableErrorCode __attribute__ ((deprecated("use FBSDKBrowserUnavailableErrorCode instead"))) = FBSDKBrowserUnavailableErrorCode, }; /*! @typedef NS_ENUM(NSUInteger, FBSDKGraphRequestErrorCategory) @abstract Describes the category of Facebook error. See `FBSDKGraphRequestErrorCategoryKey`. */ typedef NS_ENUM(NSUInteger, FBSDKGraphRequestErrorCategory) { /*! The default error category that is not known to be recoverable. Check `FBSDKLocalizedErrorDescriptionKey` for a user facing message. */ FBSDKGraphRequestErrorCategoryOther = 0, /*! Indicates the error is temporary (such as server throttling). While a recoveryAttempter will be provided with the error instance, the attempt is guaranteed to succeed so you can simply retry the operation if you do not want to present an alert. */ FBSDKGraphRequestErrorCategoryTransient = 1, /*! Indicates the error can be recovered (such as requiring a login). A recoveryAttempter will be provided with the error instance that can take UI action. */ FBSDKGraphRequestErrorCategoryRecoverable = 2 }; /* @methodgroup error userInfo keys */ /*! @abstract The userInfo key for the invalid collection for errors with FBSDKInvalidArgumentErrorCode. @discussion If the invalid argument is a collection, the collection can be found with this key and the individual invalid item can be found with FBSDKErrorArgumentValueKey. */ FBSDK_EXTERN NSString *const FBSDKErrorArgumentCollectionKey; /*! @abstract The userInfo key for the invalid argument name for errors with FBSDKInvalidArgumentErrorCode. */ FBSDK_EXTERN NSString *const FBSDKErrorArgumentNameKey; /*! @abstract The userInfo key for the invalid argument value for errors with FBSDKInvalidArgumentErrorCode. */ FBSDK_EXTERN NSString *const FBSDKErrorArgumentValueKey; /*! @abstract The userInfo key for the message for developers in NSErrors that originate from the SDK. @discussion The developer message will not be localized and is not intended to be presented within the app. */ FBSDK_EXTERN NSString *const FBSDKErrorDeveloperMessageKey; /*! @abstract The userInfo key describing a localized description that can be presented to the user. */ FBSDK_EXTERN NSString *const FBSDKErrorLocalizedDescriptionKey; /*! @abstract The userInfo key describing a localized title that can be presented to the user, used with `FBSDKLocalizedErrorDescriptionKey`. */ FBSDK_EXTERN NSString *const FBSDKErrorLocalizedTitleKey; /* @methodgroup FBSDKGraphRequest error userInfo keys */ /*! @abstract The userInfo key describing the error category, for error recovery purposes. @discussion See `FBSDKGraphErrorRecoveryProcessor` and `[FBSDKGraphRequest disableErrorRecovery]`. */ FBSDK_EXTERN NSString *const FBSDKGraphRequestErrorCategoryKey; /* @abstract The userInfo key for the Graph API error code. */ FBSDK_EXTERN NSString *const FBSDKGraphRequestErrorGraphErrorCode; /* @abstract The userInfo key for the Graph API error subcode. */ FBSDK_EXTERN NSString *const FBSDKGraphRequestErrorGraphErrorSubcode; /* @abstract The userInfo key for the HTTP status code. */ FBSDK_EXTERN NSString *const FBSDKGraphRequestErrorHTTPStatusCodeKey; /* @abstract The userInfo key for the raw JSON response. */ FBSDK_EXTERN NSString *const FBSDKGraphRequestErrorParsedJSONResponseKey; /*! @abstract a formal protocol very similar to the informal protocol NSErrorRecoveryAttempting */ @protocol FBSDKErrorRecoveryAttempting /*! @abstract attempt the recovery @param error the error @param recoveryOptionIndex the selected option index @param delegate the delegate @param didRecoverSelector the callback selector, see discussion. @param contextInfo context info to pass back to callback selector, see discussion. @discussion Given that an error alert has been presented document-modally to the user, and the user has chosen one of the error's recovery options, attempt recovery from the error, and send the selected message to the specified delegate. The option index is an index into the error's array of localized recovery options. The method selected by didRecoverSelector must have the same signature as: - (void)didPresentErrorWithRecovery:(BOOL)didRecover contextInfo:(void *)contextInfo; The value passed for didRecover must be YES if error recovery was completely successful, NO otherwise. */ - (void)attemptRecoveryFromError:(NSError *)error optionIndex:(NSUInteger)recoveryOptionIndex delegate:(id)delegate didRecoverSelector:(SEL)didRecoverSelector contextInfo:(void *)contextInfo; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKConstants.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKConstants.h" NSString *const FBSDKErrorDomain = @"com.facebook.sdk.core"; NSString *const FBSDKErrorArgumentCollectionKey = @"com.facebook.sdk:FBSDKErrorArgumentCollectionKey"; NSString *const FBSDKErrorArgumentNameKey = @"com.facebook.sdk:FBSDKErrorArgumentNameKey"; NSString *const FBSDKErrorArgumentValueKey = @"com.facebook.sdk:FBSDKErrorArgumentValueKey"; NSString *const FBSDKErrorDeveloperMessageKey = @"com.facebook.sdk:FBSDKErrorDeveloperMessageKey"; NSString *const FBSDKErrorLocalizedDescriptionKey = @"com.facebook.sdk:FBSDKErrorLocalizedDescriptionKey"; NSString *const FBSDKErrorLocalizedTitleKey = @"com.facebook.sdk:FBSDKErrorLocalizedErrorTitleKey"; NSString *const FBSDKGraphRequestErrorCategoryKey = @"com.facebook.sdk:FBSDKGraphRequestErrorCategoryKey"; NSString *const FBSDKGraphRequestErrorGraphErrorCode = @"com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorCode"; NSString *const FBSDKGraphRequestErrorGraphErrorSubcode = @"com.facebook.sdk:FBSDKGraphRequestErrorGraphErrorSubcode"; NSString *const FBSDKGraphRequestErrorHTTPStatusCodeKey = @"com.facebook.sdk:FBSDKGraphRequestErrorHTTPStatusCodeKey"; NSString *const FBSDKGraphRequestErrorParsedJSONResponseKey = @"com.facebook.sdk:FBSDKGraphRequestErrorParsedJSONResponseKey"; ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKCopying.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import /*! @abstract Extension protocol for NSCopying that adds the copy method, which is implemented on NSObject. @discussion NSObject implicitly conforms to this protocol. */ @protocol FBSDKCopying /*! @abstract Implemented by NSObject as a convenience to copyWithZone:. @return A copy of the receiver. */ - (id)copy; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import #import #import #import #import #import #import #import #import #import #import #if !TARGET_OS_TV #import #import #import #import #import #import #else #import #import #endif #define FBSDK_VERSION_STRING @"4.16.0" #define FBSDK_TARGET_PLATFORM_VERSION @"v2.7" ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphErrorRecoveryProcessor.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKConstants.h" @class FBSDKGraphErrorRecoveryProcessor; @class FBSDKGraphRequest; /*! @abstract Defines a delegate for `FBSDKGraphErrorRecoveryProcessor`. */ @protocol FBSDKGraphErrorRecoveryProcessorDelegate /*! @abstract Indicates the error recovery has been attempted. @param processor the processor instance. @param didRecover YES if the recovery was successful. @param error the error that that was attempted to be recovered from. */ - (void)processorDidAttemptRecovery:(FBSDKGraphErrorRecoveryProcessor *)processor didRecover:(BOOL)didRecover error:(NSError *)error; @optional /*! @abstract Indicates the processor is about to process the error. @param processor the processor instance. @param error the error is about to be processed. @discussion return NO if the processor should not process the error. For example, if you want to prevent alerts of localized messages but otherwise perform retries and recoveries, you could return NO for errors where userInfo[FBSDKGraphRequestErrorCategoryKey] equal to FBSDKGraphRequestErrorCategoryOther */ - (BOOL)processorWillProcessError:(FBSDKGraphErrorRecoveryProcessor *)processor error:(NSError *)error; @end /*! @abstract Defines a type that can process Facebook NSErrors with best practices. @discussion Facebook NSErrors can contain FBSDKErrorRecoveryAttempting instances to recover from errors, or localized messages to present to the user. This class will process the instances as follows: 1. If the error is temporary as indicated by FBSDKGraphRequestErrorCategoryKey, assume the recovery succeeded and notify the delegate. 2. If a FBSDKErrorRecoveryAttempting instance is available, display an alert (dispatched to main thread) with the recovery options and call the instance's [ attemptRecoveryFromError:optionIndex:...]. 3. If a FBSDKErrorRecoveryAttempting is not available, check the userInfo for FBSDKLocalizedErrorDescriptionKey and present that in an alert (dispatched to main thread). By default, FBSDKGraphRequests use this type to process errors and retry the request upon a successful recovery. Note that Facebook recovery attempters can present UI or even cause app switches (such as to login). Any such work is dispatched to the main thread (therefore your request handlers may then run on the main thread). Login recovery requires FBSDKLoginKit. Login will use FBSDKLoginBehaviorNative and will prompt the user for all permissions last granted. If any are declined on the new request, the recovery is not successful but the `[FBSDKAccessToken currentAccessToken]` might still have been updated. . */ @interface FBSDKGraphErrorRecoveryProcessor : NSObject /*! @abstract Gets the delegate. Note this is a strong reference, and is nil'ed out after recovery is complete. */ @property (nonatomic, strong, readonly) iddelegate; /*! @abstract Attempts to process the error, return YES if the error can be processed. @param error the error to process. @param request the related request that may be reissued. @param delegate the delegate that will be retained until recovery is complete. */ - (BOOL)processError:(NSError *)error request:(FBSDKGraphRequest *)request delegate:(id) delegate; /*! @abstract The callback for FBSDKErrorRecoveryAttempting @param didRecover if the recovery succeeded @param contextInfo unused */ - (void)didPresentErrorWithRecovery:(BOOL)didRecover contextInfo:(void *)contextInfo; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphErrorRecoveryProcessor.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKGraphErrorRecoveryProcessor.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKErrorRecoveryAttempter.h" @interface FBSDKGraphErrorRecoveryProcessor() { FBSDKErrorRecoveryAttempter *_recoveryAttempter; NSError *_error; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" UIAlertView *_alertView; #pragma clang diagnostic pop } @property (nonatomic, strong, readwrite) iddelegate; @end @implementation FBSDKGraphErrorRecoveryProcessor - (void)dealloc { if (_alertView) { _alertView.delegate = nil; } } - (BOOL)processError:(NSError *)error request:(FBSDKGraphRequest *)request delegate:(id) delegate { self.delegate = delegate; if ([self.delegate respondsToSelector:@selector(processorWillProcessError:error:)]) { if (![self.delegate processorWillProcessError:self error:error]) { return NO; } } FBSDKGraphRequestErrorCategory errorCategory = [error.userInfo[FBSDKGraphRequestErrorCategoryKey] unsignedIntegerValue]; switch (errorCategory) { case FBSDKGraphRequestErrorCategoryTransient : [self.delegate processorDidAttemptRecovery:self didRecover:YES error:nil]; self.delegate = nil; return YES; case FBSDKGraphRequestErrorCategoryRecoverable : if ([request.tokenString isEqualToString:[FBSDKAccessToken currentAccessToken].tokenString]) { _recoveryAttempter = error.recoveryAttempter; BOOL isLoginRecoveryAttempter = [_recoveryAttempter isKindOfClass:NSClassFromString(@"_FBSDKLoginRecoveryAttempter")]; // Set up a block to do the typical recovery work so that we can chain it for ios auth special cases. // the block returns YES if recovery UI is started (meaning we wait for the alertviewdelegate to resume control flow). BOOL (^standardRecoveryWork)(void) = ^BOOL{ NSArray *recoveryOptionsTitles = error.userInfo[NSLocalizedRecoveryOptionsErrorKey]; if (recoveryOptionsTitles.count > 0 && _recoveryAttempter) { NSString *recoverySuggestion = error.userInfo[NSLocalizedRecoverySuggestionErrorKey]; _error = error; dispatch_async(dispatch_get_main_queue(), ^{ [self displayAlertWithRecoverySuggestion:recoverySuggestion recoveryOptionsTitles:recoveryOptionsTitles]; }); return YES; } return NO; }; if ([request.tokenString isEqualToString:[[FBSDKSystemAccountStoreAdapter sharedInstance] accessTokenString]] && isLoginRecoveryAttempter) { // special system auth case: if user has granted permissions we can simply renew. On a successful // renew, treat this as immediately recovered without the standard alert prompty. // (for example, this can repair expired tokens seamlessly) [[FBSDKSystemAccountStoreAdapter sharedInstance] renewSystemAuthorization:^(ACAccountCredentialRenewResult result, NSError *renewError) { dispatch_async(dispatch_get_main_queue(), ^{ if (result == ACAccountCredentialRenewResultRenewed) { [self.delegate processorDidAttemptRecovery:self didRecover:YES error:nil]; self.delegate = nil; } else if (!standardRecoveryWork()) { [self.delegate processorDidAttemptRecovery:self didRecover:NO error:_error]; }; }); }]; // short-circuit YES so that the renew callback resumes the control flow. return YES; } return standardRecoveryWork(); } return NO; case FBSDKGraphRequestErrorCategoryOther : if ([request.tokenString isEqualToString:[FBSDKAccessToken currentAccessToken].tokenString]) { NSString *message = error.userInfo[FBSDKErrorLocalizedDescriptionKey]; NSString *title = error.userInfo[FBSDKErrorLocalizedTitleKey]; if (message) { dispatch_async(dispatch_get_main_queue(), ^{ NSString *localizedOK = NSLocalizedStringWithDefaultValue(@"ErrorRecovery.Alert.OK", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"OK", @"The title of the label to dismiss the alert when presenting user facing error messages"); [self displayAlertWithTitle:title message:message cancelButtonTitle:localizedOK]; }); } } return NO; } return NO; } #pragma mark - UIAlertView and UIAlertController support - (void)displayAlertWithRecoverySuggestion:(NSString *)recoverySuggestion recoveryOptionsTitles:(NSArray *)recoveryOptionsTitles { if ([UIAlertController class]) { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:recoverySuggestion preferredStyle:UIAlertControllerStyleAlert]; for (NSUInteger i = 0; i < recoveryOptionsTitles.count; i++) { NSString *title = recoveryOptionsTitles[i]; UIAlertAction *option = [UIAlertAction actionWithTitle:title style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { [_recoveryAttempter attemptRecoveryFromError:_error optionIndex:i delegate:self didRecoverSelector:@selector(didPresentErrorWithRecovery:contextInfo:) contextInfo:nil]; }]; [alertController addAction:option]; } UIViewController *topMostViewController = [FBSDKInternalUtility topMostViewController]; [topMostViewController presentViewController:alertController animated:YES completion:nil]; } else { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" _alertView = [[UIAlertView alloc] initWithTitle:nil message:recoverySuggestion delegate:self cancelButtonTitle:nil otherButtonTitles:nil]; #pragma clang diagnostic pop for (NSString *option in recoveryOptionsTitles) { [_alertView addButtonWithTitle:option]; } [_alertView show]; } } - (void)displayAlertWithTitle:(NSString *)title message:(NSString *)message cancelButtonTitle:(NSString *)localizedOK { if ([UIAlertController class]) { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:message preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *OKAction = [UIAlertAction actionWithTitle:localizedOK style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { [_recoveryAttempter attemptRecoveryFromError:_error optionIndex:0 delegate:self didRecoverSelector:@selector(didPresentErrorWithRecovery:contextInfo:) contextInfo:nil]; }]; [alertController addAction:OKAction]; UIViewController *topMostViewController = [FBSDKInternalUtility topMostViewController]; [topMostViewController presentViewController:alertController animated:YES completion:nil]; } else { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" [[[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:localizedOK otherButtonTitles:nil] show]; #pragma clang diagnostic pop } } #pragma mark - UIAlertViewDelegate #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { [_recoveryAttempter attemptRecoveryFromError:_error optionIndex:buttonIndex delegate:self didRecoverSelector:@selector(didPresentErrorWithRecovery:contextInfo:) contextInfo:nil]; if (_alertView) { _alertView.delegate = nil; _alertView = nil; } } #pragma clang diagnostic pop #pragma mark - FBSDKErrorRecoveryAttempting "delegate" - (void)didPresentErrorWithRecovery:(BOOL)didRecover contextInfo:(void *)contextInfo { [self.delegate processorDidAttemptRecovery:self didRecover:didRecover error:_error]; self.delegate = nil; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphRequest.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @class FBSDKAccessToken; /*! @abstract Represents a request to the Facebook Graph API. @discussion `FBSDKGraphRequest` encapsulates the components of a request (the Graph API path, the parameters, error recovery behavior) and should be used in conjunction with `FBSDKGraphRequestConnection` to issue the request. Nearly all Graph APIs require an access token. Unless specified, the `[FBSDKAccessToken currentAccessToken]` is used. Therefore, most requests will require login first (see `FBSDKLoginManager` in FBSDKLoginKit.framework). A `- start` method is provided for convenience for single requests. By default, FBSDKGraphRequest will attempt to recover any errors returned from Facebook. You can disable this via `disableErrorRecovery:`. @see FBSDKGraphErrorRecoveryProcessor */ @interface FBSDKGraphRequest : NSObject /*! @abstract Initializes a new instance that use use `[FBSDKAccessToken currentAccessToken]`. @param graphPath the graph path (e.g., @"me"). @param parameters the optional parameters dictionary. */ - (instancetype)initWithGraphPath:(NSString *)graphPath parameters:(NSDictionary *)parameters; /*! @abstract Initializes a new instance that use use `[FBSDKAccessToken currentAccessToken]`. @param graphPath the graph path (e.g., @"me"). @param parameters the optional parameters dictionary. @param HTTPMethod the optional HTTP method. nil defaults to @"GET". */ - (instancetype)initWithGraphPath:(NSString *)graphPath parameters:(NSDictionary *)parameters HTTPMethod:(NSString *)HTTPMethod; /*! @abstract Initializes a new instance. @param graphPath the graph path (e.g., @"me"). @param parameters the optional parameters dictionary. @param tokenString the token string to use. Specifying nil will cause no token to be used. @param version the optional Graph API version (e.g., @"v2.0"). nil defaults to `[FBSDKSettings graphAPIVersion]`. @param HTTPMethod the optional HTTP method (e.g., @"POST"). nil defaults to @"GET". */ - (instancetype)initWithGraphPath:(NSString *)graphPath parameters:(NSDictionary *)parameters tokenString:(NSString *)tokenString version:(NSString *)version HTTPMethod:(NSString *)HTTPMethod NS_DESIGNATED_INITIALIZER; /*! @abstract The request parameters. */ @property (nonatomic, strong, readonly) NSMutableDictionary *parameters; /*! @abstract The access token string used by the request. */ @property (nonatomic, copy, readonly) NSString *tokenString; /*! @abstract The Graph API endpoint to use for the request, for example "me". */ @property (nonatomic, copy, readonly) NSString *graphPath; /*! @abstract The HTTPMethod to use for the request, for example "GET" or "POST". */ @property (nonatomic, copy, readonly) NSString *HTTPMethod; /*! @abstract The Graph API version to use (e.g., "v2.0") */ @property (nonatomic, copy, readonly) NSString *version; /*! @abstract If set, disables the automatic error recovery mechanism. @param disable whether to disable the automatic error recovery mechanism @discussion By default, non-batched FBSDKGraphRequest instances will automatically try to recover from errors by constructing a `FBSDKGraphErrorRecoveryProcessor` instance that re-issues the request on successful recoveries. The re-issued request will call the same handler as the receiver but may occur with a different `FBSDKGraphRequestConnection` instance. This will override [FBSDKSettings setGraphErrorRecoveryDisabled:]. */ - (void)setGraphErrorRecoveryDisabled:(BOOL)disable; /*! @abstract Starts a connection to the Graph API. @param handler The handler block to call when the request completes. */ - (FBSDKGraphRequestConnection *)startWithCompletionHandler:(FBSDKGraphRequestHandler)handler; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphRequest.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKGraphRequest+Internal.h" #import #import "FBSDKAccessToken.h" #import "FBSDKCoreKit.h" #import "FBSDKGraphRequestConnection.h" #import "FBSDKGraphRequestDataAttachment.h" #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKSettings+Internal.h" // constants static NSString *const kGetHTTPMethod = @"GET"; @interface FBSDKGraphRequest() @property (nonatomic, assign) FBSDKGraphRequestFlags flags; @end @implementation FBSDKGraphRequest - (instancetype)init NS_UNAVAILABLE { assert(0); } - (instancetype)initWithGraphPath:(NSString *)graphPath parameters:(NSDictionary *)parameters { return [self initWithGraphPath:graphPath parameters:parameters flags:FBSDKGraphRequestFlagNone]; } - (instancetype)initWithGraphPath:(NSString *)graphPath parameters:(NSDictionary *)parameters HTTPMethod:(NSString *)HTTPMethod { return [self initWithGraphPath:graphPath parameters:parameters tokenString:[FBSDKAccessToken currentAccessToken].tokenString version:nil HTTPMethod:HTTPMethod]; } - (instancetype)initWithGraphPath:(NSString *)graphPath parameters:(NSDictionary *)parameters flags:(FBSDKGraphRequestFlags)flags { return [self initWithGraphPath:graphPath parameters:parameters tokenString:[FBSDKAccessToken currentAccessToken].tokenString HTTPMethod:nil flags:flags]; } - (instancetype)initWithGraphPath:(NSString *)graphPath parameters:(NSDictionary *)parameters tokenString:(NSString *)tokenString HTTPMethod:(NSString *)HTTPMethod flags:(FBSDKGraphRequestFlags)flags { if ((self = [self initWithGraphPath:graphPath parameters:parameters tokenString:tokenString version:[FBSDKSettings graphAPIVersion] HTTPMethod:HTTPMethod])) { self.flags |= flags; } return self; } - (instancetype)initWithGraphPath:(NSString *)graphPath parameters:(NSDictionary *)parameters tokenString:(NSString *)tokenString version:(NSString *)version HTTPMethod:(NSString *)HTTPMethod { if ((self = [super init])) { _tokenString = [tokenString copy]; _version = version ? [version copy] : [FBSDKSettings graphAPIVersion]; _graphPath = [graphPath copy]; _HTTPMethod = HTTPMethod ? [HTTPMethod copy] : kGetHTTPMethod; _parameters = [[NSMutableDictionary alloc] initWithDictionary:parameters]; if ([FBSDKSettings isGraphErrorRecoveryDisabled]) { _flags = FBSDKGraphRequestFlagDisableErrorRecovery; } } return self; } - (BOOL)isGraphErrorRecoveryDisabled { return (self.flags & FBSDKGraphRequestFlagDisableErrorRecovery); } - (void)setGraphErrorRecoveryDisabled:(BOOL)disable { if (disable) { self.flags |= FBSDKGraphRequestFlagDisableErrorRecovery; } else { self.flags &= ~FBSDKGraphRequestFlagDisableErrorRecovery; } } - (BOOL)hasAttachments { __block BOOL hasAttachments = NO; [self.parameters enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { if ([FBSDKGraphRequest isAttachment:obj]) { hasAttachments = YES; *stop = YES; } }]; return hasAttachments; } + (BOOL)isAttachment:(id)item { return ([item isKindOfClass:[UIImage class]] || [item isKindOfClass:[NSData class]] || [item isKindOfClass:[FBSDKGraphRequestDataAttachment class]]); } + (NSString *)serializeURL:(NSString *)baseUrl params:(NSDictionary *)params { return [self serializeURL:baseUrl params:params httpMethod:kGetHTTPMethod]; } + (NSString *)serializeURL:(NSString *)baseUrl params:(NSDictionary *)params httpMethod:(NSString *)httpMethod { params = [self preprocessParams: params]; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" NSURL *parsedURL = [NSURL URLWithString:[baseUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]; #pragma clang pop NSString *queryPrefix = parsedURL.query ? @"&" : @"?"; NSString *query = [FBSDKInternalUtility queryStringWithDictionary:params error:NULL invalidObjectHandler:^id(id object, BOOL *stop) { if ([self isAttachment:object]) { if ([httpMethod isEqualToString:kGetHTTPMethod]) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"can not use GET to upload a file"]; } return nil; } return object; }]; return [NSString stringWithFormat:@"%@%@%@", baseUrl, queryPrefix, query]; } + (NSDictionary *)preprocessParams:(NSDictionary *)params { NSString *debugValue = [FBSDKSettings graphAPIDebugParamValue]; if (debugValue) { NSMutableDictionary *mutableParams = [NSMutableDictionary dictionaryWithDictionary:params]; [mutableParams setObject:debugValue forKey:@"debug"]; return mutableParams; } return params; } - (FBSDKGraphRequestConnection *)startWithCompletionHandler:(FBSDKGraphRequestHandler)handler { FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; [connection addRequest:self completionHandler:handler]; [connection start]; return connection; } #pragma mark - Debugging helpers - (NSString *)description { NSMutableString *result = [NSMutableString stringWithFormat:@"<%@: %p", NSStringFromClass([self class]), self]; if (self.graphPath) { [result appendFormat:@", graphPath: %@", self.graphPath]; } if (self.HTTPMethod) { [result appendFormat:@", HTTPMethod: %@", self.HTTPMethod]; } [result appendFormat:@", parameters: %@>", [self.parameters description]]; return result; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphRequestConnection.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @class FBSDKGraphRequest; @class FBSDKGraphRequestConnection; /*! @typedef FBSDKGraphRequestHandler @abstract A block that is passed to addRequest to register for a callback with the results of that request once the connection completes. @discussion Pass a block of this type when calling addRequest. This will be called once the request completes. The call occurs on the UI thread. @param connection The `FBSDKGraphRequestConnection` that sent the request. @param result The result of the request. This is a translation of JSON data to `NSDictionary` and `NSArray` objects. This is nil if there was an error. @param error The `NSError` representing any error that occurred. */ typedef void (^FBSDKGraphRequestHandler)(FBSDKGraphRequestConnection *connection, id result, NSError *error); /*! @protocol @abstract The `FBSDKGraphRequestConnectionDelegate` protocol defines the methods used to receive network activity progress information from a . */ @protocol FBSDKGraphRequestConnectionDelegate @optional /*! @method @abstract Tells the delegate the request connection will begin loading @discussion If the is created using one of the convenience factory methods prefixed with start, the object returned from the convenience method has already begun loading and this method will not be called when the delegate is set. @param connection The request connection that is starting a network request */ - (void)requestConnectionWillBeginLoading:(FBSDKGraphRequestConnection *)connection; /*! @method @abstract Tells the delegate the request connection finished loading @discussion If the request connection completes without a network error occurring then this method is called. Invocation of this method does not indicate success of every made, only that the request connection has no further activity. Use the error argument passed to the FBSDKGraphRequestHandler block to determine success or failure of each . This method is invoked after the completion handler for each . @param connection The request connection that successfully completed a network request */ - (void)requestConnectionDidFinishLoading:(FBSDKGraphRequestConnection *)connection; /*! @method @abstract Tells the delegate the request connection failed with an error @discussion If the request connection fails with a network error then this method is called. The `error` argument specifies why the network connection failed. The `NSError` object passed to the FBSDKGraphRequestHandler block may contain additional information. @param connection The request connection that successfully completed a network request @param error The `NSError` representing the network error that occurred, if any. May be nil in some circumstances. Consult the `NSError` for the for reliable failure information. */ - (void)requestConnection:(FBSDKGraphRequestConnection *)connection didFailWithError:(NSError *)error; /*! @method @abstract Tells the delegate how much data has been sent and is planned to send to the remote host @discussion The byte count arguments refer to the aggregated objects, not a particular . Like `NSURLConnection`, the values may change in unexpected ways if data needs to be resent. @param connection The request connection transmitting data to a remote host @param bytesWritten The number of bytes sent in the last transmission @param totalBytesWritten The total number of bytes sent to the remote host @param totalBytesExpectedToWrite The total number of bytes expected to send to the remote host */ - (void)requestConnection:(FBSDKGraphRequestConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite; @end /*! @class FBSDKGraphRequestConnection @abstract The `FBSDKGraphRequestConnection` represents a single connection to Facebook to service a request. @discussion The request settings are encapsulated in a reusable object. The `FBSDKGraphRequestConnection` object encapsulates the concerns of a single communication e.g. starting a connection, canceling a connection, or batching requests. */ @interface FBSDKGraphRequestConnection : NSObject /*! @abstract The delegate object that receives updates. */ @property (nonatomic, weak) id delegate; /*! @abstract Gets or sets the timeout interval to wait for a response before giving up. */ @property (nonatomic) NSTimeInterval timeout; /*! @abstract The raw response that was returned from the server. (readonly) @discussion This property can be used to inspect HTTP headers that were returned from the server. The property is nil until the request completes. If there was a response then this property will be non-nil during the FBSDKGraphRequestHandler callback. */ @property (nonatomic, retain, readonly) NSHTTPURLResponse *URLResponse; /*! @methodgroup Class methods */ /*! @method @abstract This method sets the default timeout on all FBSDKGraphRequestConnection instances. Defaults to 60 seconds. @param defaultConnectionTimeout The timeout interval. */ + (void)setDefaultConnectionTimeout:(NSTimeInterval)defaultConnectionTimeout; /*! @methodgroup Adding requests */ /*! @method @abstract This method adds an object to this connection. @param request A request to be included in the round-trip when start is called. @param handler A handler to call back when the round-trip completes or times out. @discussion The completion handler is retained until the block is called upon the completion or cancellation of the connection. */ - (void)addRequest:(FBSDKGraphRequest *)request completionHandler:(FBSDKGraphRequestHandler)handler; /*! @method @abstract This method adds an object to this connection. @param request A request to be included in the round-trip when start is called. @param handler A handler to call back when the round-trip completes or times out. The handler will be invoked on the main thread. @param name An optional name for this request. This can be used to feed the results of one request to the input of another in the same `FBSDKGraphRequestConnection` as described in [Graph API Batch Requests]( https://developers.facebook.com/docs/reference/api/batch/ ). @discussion The completion handler is retained until the block is called upon the completion or cancellation of the connection. This request can be named to allow for using the request's response in a subsequent request. */ - (void)addRequest:(FBSDKGraphRequest *)request completionHandler:(FBSDKGraphRequestHandler)handler batchEntryName:(NSString *)name; /*! @method @abstract This method adds an object to this connection. @param request A request to be included in the round-trip when start is called. @param handler A handler to call back when the round-trip completes or times out. @param batchParameters The optional dictionary of parameters to include for this request as described in [Graph API Batch Requests]( https://developers.facebook.com/docs/reference/api/batch/ ). Examples include "depends_on", "name", or "omit_response_on_success". @discussion The completion handler is retained until the block is called upon the completion or cancellation of the connection. This request can be named to allow for using the request's response in a subsequent request. */ - (void)addRequest:(FBSDKGraphRequest *)request completionHandler:(FBSDKGraphRequestHandler)handler batchParameters:(NSDictionary *)batchParameters; /*! @methodgroup Instance methods */ /*! @method @abstract Signals that a connection should be logically terminated as the application is no longer interested in a response. @discussion Synchronously calls any handlers indicating the request was cancelled. Cancel does not guarantee that the request-related processing will cease. It does promise that all handlers will complete before the cancel returns. A call to cancel prior to a start implies a cancellation of all requests associated with the connection. */ - (void)cancel; /*! @method @abstract This method starts a connection with the server and is capable of handling all of the requests that were added to the connection. @discussion By default, a connection is scheduled on the current thread in the default mode when it is created. See `setDelegateQueue:` for other options. This method cannot be called twice for an `FBSDKGraphRequestConnection` instance. */ - (void)start; /*! @abstract Determines the operation queue that is used to call methods on the connection's delegate. @param queue The operation queue to use when calling delegate methods. @discussion By default, a connection is scheduled on the current thread in the default mode when it is created. You cannot reschedule a connection after it has started. This is very similar to `[NSURLConnection setDelegateQueue:]`. */ - (void)setDelegateQueue:(NSOperationQueue *)queue; /*! @method @abstract Overrides the default version for a batch request @discussion The SDK automatically prepends a version part, such as "v2.0" to API paths in order to simplify API versioning for applications. If you want to override the version part while using batch requests on the connection, call this method to set the version for the batch request. @param version This is a string in the form @"v2.0" which will be used for the version part of an API path */ - (void)overrideVersionPartWith:(NSString *)version; @end /*! @abstract The key in the result dictionary for requests to old versions of the Graph API whose response is not a JSON object. @discussion When a request returns a non-JSON response (such as a "true" literal), that response will be wrapped into a dictionary using this const as the key. This only applies for very few Graph API prior to v2.1. */ FBSDK_EXTERN NSString *const FBSDKNonJSONResponseProperty; ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphRequestConnection.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKGraphRequestConnection+Internal.h" #import "FBSDKAppEvents+Internal.h" #import "FBSDKConstants.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKError.h" #import "FBSDKErrorConfiguration.h" #import "FBSDKGraphRequest+Internal.h" #import "FBSDKGraphRequestBody.h" #import "FBSDKGraphRequestDataAttachment.h" #import "FBSDKGraphRequestMetadata.h" #import "FBSDKGraphRequestPiggybackManager.h" #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKSettings+Internal.h" #import "FBSDKURLSessionTask.h" NSString *const FBSDKNonJSONResponseProperty = @"FACEBOOK_NON_JSON_RESULT"; // URL construction constants static NSString *const kGraphURLPrefix = @"graph."; static NSString *const kGraphVideoURLPrefix = @"graph-video."; static NSString *const kBatchKey = @"batch"; static NSString *const kBatchMethodKey = @"method"; static NSString *const kBatchRelativeURLKey = @"relative_url"; static NSString *const kBatchAttachmentKey = @"attached_files"; static NSString *const kBatchFileNamePrefix = @"file"; static NSString *const kBatchEntryName = @"name"; static NSString *const kAccessTokenKey = @"access_token"; #if TARGET_OS_TV static NSString *const kSDK = @"tvos"; static NSString *const kUserAgentBase = @"FBtvOSSDK"; #else static NSString *const kSDK = @"ios"; static NSString *const kUserAgentBase = @"FBiOSSDK"; #endif static NSString *const kBatchRestMethodBaseURL = @"method/"; static NSTimeInterval g_defaultTimeout = 60.0; static FBSDKErrorConfiguration *g_errorConfiguration; // ---------------------------------------------------------------------------- // FBSDKGraphRequestConnectionState typedef NS_ENUM(NSUInteger, FBSDKGraphRequestConnectionState) { kStateCreated, kStateSerialized, kStateStarted, kStateCompleted, kStateCancelled, }; // ---------------------------------------------------------------------------- // Private properties and methods @interface FBSDKGraphRequestConnection () < NSURLSessionDataDelegate #if !TARGET_OS_TV , FBSDKGraphErrorRecoveryProcessorDelegate #endif > @property (nonatomic, strong) NSURLSession *session; @property (nonatomic, strong) FBSDKURLSessionTask *task; @property (nonatomic, retain) NSMutableArray *requests; @property (nonatomic, assign) FBSDKGraphRequestConnectionState state; @property (nonatomic, strong) FBSDKLogger *logger; @property (nonatomic, assign) unsigned long requestStartTime; @end // ---------------------------------------------------------------------------- // FBSDKGraphRequestConnection @implementation FBSDKGraphRequestConnection { NSString *_overrideVersionPart; NSUInteger _expectingResults; NSOperationQueue *_delegateQueue; #if !TARGET_OS_TV FBSDKGraphRequestMetadata *_recoveringRequestMetadata; FBSDKGraphErrorRecoveryProcessor *_errorRecoveryProcessor; #endif } - (instancetype)init { if ((self = [super init])) { _requests = [[NSMutableArray alloc] init]; _timeout = g_defaultTimeout; _state = kStateCreated; _logger = [[FBSDKLogger alloc] initWithLoggingBehavior:FBSDKLoggingBehaviorNetworkRequests]; } return self; } - (void)dealloc { [_session invalidateAndCancel]; } #pragma mark - Public + (void)setDefaultConnectionTimeout:(NSTimeInterval)defaultTimeout { if (defaultTimeout >= 0) { g_defaultTimeout = defaultTimeout; } } - (void)addRequest:(FBSDKGraphRequest *)request completionHandler:(FBSDKGraphRequestHandler)handler { [self addRequest:request completionHandler:handler batchEntryName:nil]; } - (void)addRequest:(FBSDKGraphRequest *)request completionHandler:(FBSDKGraphRequestHandler)handler batchEntryName:(NSString *)name { NSDictionary *batchParams = (name)? @{kBatchEntryName : name } : nil; [self addRequest:request completionHandler:handler batchParameters:batchParams]; } - (void)addRequest:(FBSDKGraphRequest *)request completionHandler:(FBSDKGraphRequestHandler)handler batchParameters:(NSDictionary *)batchParameters { if (self.state != kStateCreated) { @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Cannot add requests once started or if a URLRequest is set" userInfo:nil]; } FBSDKGraphRequestMetadata *metadata = [[FBSDKGraphRequestMetadata alloc] initWithRequest:request completionHandler:handler batchParameters:batchParameters]; [self.requests addObject:metadata]; } - (void)cancel { self.state = kStateCancelled; [self.task cancel]; [self cleanUpSession]; } - (void)overrideVersionPartWith:(NSString *)version { if (![_overrideVersionPart isEqualToString:version]) { _overrideVersionPart = [version copy]; } } - (void)start { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ g_errorConfiguration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; }); //optimistically check for updated server configuration; g_errorConfiguration = [FBSDKServerConfigurationManager cachedServerConfiguration].errorConfiguration ?: g_errorConfiguration; if (self.state != kStateCreated && self.state != kStateSerialized) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors formatString:@"FBSDKGraphRequestConnection cannot be started again."]; return; } [FBSDKGraphRequestPiggybackManager addPiggybackRequests:self]; NSMutableURLRequest *request = [self requestWithBatch:self.requests timeout:_timeout]; self.state = kStateStarted; [self logRequest:request bodyLength:0 bodyLogger:nil attachmentLogger:nil]; _requestStartTime = [FBSDKInternalUtility currentTimeInMilliseconds]; FBSDKURLSessionTaskHandler handler = ^(NSError *error, NSURLResponse *response, NSData *responseData) { [self completeFBSDKURLSessionWithResponse:response data:responseData networkError:error]; }; if (!self.session) { self.session = [self defaultSession]; } self.task = [[FBSDKURLSessionTask alloc] initWithRequest:request fromSession:self.session completionHandler:handler]; [self.task start]; id delegate = self.delegate; if ([delegate respondsToSelector:@selector(requestConnectionWillBeginLoading:)]) { if (_delegateQueue) { [_delegateQueue addOperationWithBlock:^{ [delegate requestConnectionWillBeginLoading:self]; }]; } else { [delegate requestConnectionWillBeginLoading:self]; } } } - (void)setDelegateQueue:(NSOperationQueue *)queue { _delegateQueue = queue; } #pragma mark - Private methods (request generation) // // Adds request data to a batch in a format expected by the JsonWriter. // Binary attachments are referenced by name in JSON and added to the // attachments dictionary. // - (void)addRequest:(FBSDKGraphRequestMetadata *)metadata toBatch:(NSMutableArray *)batch attachments:(NSMutableDictionary *)attachments batchToken:(NSString *)batchToken { NSMutableDictionary *requestElement = [[NSMutableDictionary alloc] init]; if (metadata.batchParameters) { [requestElement addEntriesFromDictionary:metadata.batchParameters]; } if (batchToken) { metadata.request.parameters[kAccessTokenKey] = batchToken; [self registerTokenToOmitFromLog:batchToken]; } NSString *urlString = [self urlStringForSingleRequest:metadata.request forBatch:YES]; requestElement[kBatchRelativeURLKey] = urlString; requestElement[kBatchMethodKey] = metadata.request.HTTPMethod; NSMutableArray *attachmentNames = [NSMutableArray array]; [metadata.request.parameters enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { if ([FBSDKGraphRequest isAttachment:value]) { NSString *name = [NSString stringWithFormat:@"%@%lu", kBatchFileNamePrefix, (unsigned long)[attachments count]]; [attachmentNames addObject:name]; attachments[name] = value; } }]; if ([attachmentNames count]) { requestElement[kBatchAttachmentKey] = [attachmentNames componentsJoinedByString:@","]; } [batch addObject:requestElement]; } - (void)appendAttachments:(NSDictionary *)attachments toBody:(FBSDKGraphRequestBody *)body addFormData:(BOOL)addFormData logger:(FBSDKLogger *)logger { [attachments enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { value = [FBSDKInternalUtility convertRequestValue:value]; if ([value isKindOfClass:[NSString class]]) { if (addFormData) { [body appendWithKey:key formValue:(NSString *)value logger:logger]; } } else if ([value isKindOfClass:[UIImage class]]) { [body appendWithKey:key imageValue:(UIImage *)value logger:logger]; } else if ([value isKindOfClass:[NSData class]]) { [body appendWithKey:key dataValue:(NSData *)value logger:logger]; } else if ([value isKindOfClass:[FBSDKGraphRequestDataAttachment class]]) { [body appendWithKey:key dataAttachmentValue:(FBSDKGraphRequestDataAttachment *)value logger:logger]; } else { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors formatString:@"Unsupported FBSDKGraphRequest attachment:%@, skipping.", value]; } }]; } // // Serializes all requests in the batch to JSON and appends the result to // body. Also names all attachments that need to go as separate blocks in // the body of the request. // // All the requests are serialized into JSON, with any binary attachments // named and referenced by name in the JSON. // - (void)appendJSONRequests:(NSArray *)requests toBody:(FBSDKGraphRequestBody *)body andNameAttachments:(NSMutableDictionary *)attachments logger:(FBSDKLogger *)logger { NSMutableArray *batch = [[NSMutableArray alloc] init]; NSString *batchToken = nil; for (FBSDKGraphRequestMetadata *metadata in requests) { NSString *individualToken = [self accessTokenWithRequest:metadata.request]; BOOL isClientToken = [FBSDKSettings clientToken] && [individualToken hasSuffix:[FBSDKSettings clientToken]]; if (!batchToken && !isClientToken) { batchToken = individualToken; } [self addRequest:metadata toBatch:batch attachments:attachments batchToken:[batchToken isEqualToString:individualToken] ? nil : individualToken]; } NSString *jsonBatch = [FBSDKInternalUtility JSONStringForObject:batch error:NULL invalidObjectHandler:NULL]; [body appendWithKey:kBatchKey formValue:jsonBatch logger:logger]; if (batchToken) { [body appendWithKey:kAccessTokenKey formValue:batchToken logger:logger]; } } - (BOOL)_shouldWarnOnMissingFieldsParam:(FBSDKGraphRequest *)request { NSString *minVersion = @"2.4"; NSString *version = request.version; if (!version) { return YES; } if ([version hasPrefix:@"v"]) { version = [version substringFromIndex:1]; } NSComparisonResult result = [version compare:minVersion options:NSNumericSearch]; // if current version is the same as minVersion, or if the current version is > minVersion return (result == NSOrderedSame) || (result == NSOrderedDescending); } // Validate that all GET requests after v2.4 have a "fields" param - (void)_validateFieldsParamForGetRequests:(NSArray *)requests { for (FBSDKGraphRequestMetadata *metadata in requests) { FBSDKGraphRequest *request = metadata.request; if ([request.HTTPMethod.uppercaseString isEqualToString:@"GET"] && [self _shouldWarnOnMissingFieldsParam:request] && !request.parameters[@"fields"] && [request.graphPath rangeOfString:@"fields="].location == NSNotFound) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors formatString:@"starting with Graph API v2.4, GET requests for /%@ should contain an explicit \"fields\" parameter", request.graphPath]; } } } // // Generates a NSURLRequest based on the contents of self.requests, and sets // options on the request. Chooses between URL-based request for a single // request and JSON-based request for batches. // - (NSMutableURLRequest *)requestWithBatch:(NSArray *)requests timeout:(NSTimeInterval)timeout { FBSDKGraphRequestBody *body = [[FBSDKGraphRequestBody alloc] init]; FBSDKLogger *bodyLogger = [[FBSDKLogger alloc] initWithLoggingBehavior:_logger.loggingBehavior]; FBSDKLogger *attachmentLogger = [[FBSDKLogger alloc] initWithLoggingBehavior:_logger.loggingBehavior]; NSMutableURLRequest *request; if (requests.count == 0) { [[NSException exceptionWithName:NSInvalidArgumentException reason:@"FBSDKGraphRequestConnection: Must have at least one request or urlRequest not specified." userInfo:nil] raise]; } [self _validateFieldsParamForGetRequests:requests]; if ([requests count] == 1) { FBSDKGraphRequestMetadata *metadata = [requests objectAtIndex:0]; NSURL *url = [NSURL URLWithString:[self urlStringForSingleRequest:metadata.request forBatch:NO]]; request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:timeout]; // HTTP methods are case-sensitive; be helpful in case someone provided a mixed case one. NSString *httpMethod = [metadata.request.HTTPMethod uppercaseString]; [request setHTTPMethod:httpMethod]; [self appendAttachments:metadata.request.parameters toBody:body addFormData:[httpMethod isEqualToString:@"POST"] logger:attachmentLogger]; } else { // Find the session with an app ID and use that as the batch_app_id. If we can't // find one, try to load it from the plist. As a last resort, pass 0. NSString *batchAppID = [FBSDKSettings appID]; if (!batchAppID || batchAppID.length == 0) { // The Graph API batch method requires either an access token or batch_app_id. // If we can't determine an App ID to use for the batch, we can't issue it. [[NSException exceptionWithName:NSInternalInconsistencyException reason:@"FBSDKGraphRequestConnection: [FBSDKSettings appID] must be specified for batch requests" userInfo:nil] raise]; } [body appendWithKey:@"batch_app_id" formValue:batchAppID logger:bodyLogger]; NSMutableDictionary *attachments = [[NSMutableDictionary alloc] init]; [self appendJSONRequests:requests toBody:body andNameAttachments:attachments logger:bodyLogger]; [self appendAttachments:attachments toBody:body addFormData:NO logger:attachmentLogger]; NSURL *url = [FBSDKInternalUtility facebookURLWithHostPrefix:kGraphURLPrefix path:nil queryParameters:nil defaultVersion:_overrideVersionPart error:NULL]; request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:timeout]; [request setHTTPMethod:@"POST"]; } [request setHTTPBody:[body data]]; NSUInteger bodyLength = [[body data] length] / 1024; [request setValue:[FBSDKGraphRequestConnection userAgent] forHTTPHeaderField:@"User-Agent"]; [request setValue:[FBSDKGraphRequestBody mimeContentType] forHTTPHeaderField:@"Content-Type"]; [request setHTTPShouldHandleCookies:NO]; [self logRequest:request bodyLength:bodyLength bodyLogger:bodyLogger attachmentLogger:attachmentLogger]; return request; } // // Generates a URL for a batch containing only a single request, // and names all attachments that need to go in the body of the // request. // // The URL contains all parameters that are not body attachments, // including the session key if present. // // Attachments are named and referenced by name in the URL. // - (NSString *)urlStringForSingleRequest:(FBSDKGraphRequest *)request forBatch:(BOOL)forBatch { request.parameters[@"format"] = @"json"; request.parameters[@"sdk"] = kSDK; request.parameters[@"include_headers"] = @"false"; NSString *baseURL; if (forBatch) { baseURL = request.graphPath; } else { NSString *token = [self accessTokenWithRequest:request]; if (token) { [request.parameters setValue:token forKey:kAccessTokenKey]; [self registerTokenToOmitFromLog:token]; } NSString *prefix = kGraphURLPrefix; // We special case a graph post to /videos and send it to graph-video.facebook.com // We only do this for non batch post requests NSString *graphPath = [request.graphPath lowercaseString]; if ([[request.HTTPMethod uppercaseString] isEqualToString:@"POST"] && [graphPath hasSuffix:@"/videos"]) { graphPath = [graphPath stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"/"]]; NSArray *components = [graphPath componentsSeparatedByString:@"/"]; if ([components count] == 2) { prefix = kGraphVideoURLPrefix; } } baseURL = [[FBSDKInternalUtility facebookURLWithHostPrefix:prefix path:request.graphPath queryParameters:nil defaultVersion:request.version error:NULL] absoluteString]; } NSString *url = [FBSDKGraphRequest serializeURL:baseURL params:request.parameters httpMethod:request.HTTPMethod]; return url; } #pragma mark - Private methods (response parsing) - (void)completeFBSDKURLSessionWithResponse:(NSURLResponse *)response data:(NSData *)data networkError:(NSError *)error { if (self.state != kStateCancelled) { NSAssert(self.state == kStateStarted, @"Unexpected state %lu in completeWithResponse", (unsigned long)self.state); self.state = kStateCompleted; } NSArray *results = nil; _URLResponse = (NSHTTPURLResponse *)response; if (response) { NSAssert([response isKindOfClass:[NSHTTPURLResponse class]], @"Expected NSHTTPURLResponse, got %@", response); NSInteger statusCode = _URLResponse.statusCode; if (!error && [response.MIMEType hasPrefix:@"image"]) { error = [FBSDKError errorWithCode:FBSDKGraphRequestNonTextMimeTypeReturnedErrorCode message:@"Response is a non-text MIME type; endpoints that return images and other " @"binary data should be fetched using NSURLRequest and NSURLSession"]; } else { results = [self parseJSONResponse:data error:&error statusCode:statusCode]; } } else if (!error) { error = [FBSDKError errorWithCode:FBSDKUnknownErrorCode message:@"Missing NSURLResponse"]; } if (!error) { if ([self.requests count] != [results count]) { error = [FBSDKError errorWithCode:FBSDKGraphRequestProtocolMismatchErrorCode message:@"Unexpected number of results returned from server."]; } else { [_logger appendFormat:@"Response <#%lu>\nDuration: %lu msec\nSize: %lu kB\nResponse Body:\n%@\n\n", (unsigned long)[_logger loggerSerialNumber], [FBSDKInternalUtility currentTimeInMilliseconds] - _requestStartTime, (unsigned long)[data length], results]; } } if (error) { [_logger appendFormat:@"Response <#%lu> :\n%@\n%@\n", (unsigned long)[_logger loggerSerialNumber], [error localizedDescription], [error userInfo]]; } [_logger emitToNSLog]; [self completeWithResults:results networkError:error]; [self cleanUpSession]; } // // If there is one request, the JSON is the response. // If there are multiple requests, the JSON has an array of dictionaries whose // body property is the response. // [{ "code":200, // "body":"JSON-response-as-a-string" }, // { "code":200, // "body":"JSON-response-as-a-string" }] // // In both cases, this function returns an NSArray containing the results. // The NSArray looks just like the multiple request case except the body // value is converted from a string to parsed JSON. // - (NSArray *)parseJSONResponse:(NSData *)data error:(NSError **)error statusCode:(NSInteger)statusCode; { // Graph API can return "true" or "false", which is not valid JSON. // Translate that before asking JSON parser to look at it. NSString *responseUTF8 = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSMutableArray *results = [[NSMutableArray alloc] init];; id response = [self parseJSONOrOtherwise:responseUTF8 error:error]; if (responseUTF8 == nil) { NSString *base64Data = [data length] != 0 ? [data base64EncodedStringWithOptions:0] : @""; if (base64Data != nil) { [FBSDKAppEvents logImplicitEvent:@"fb_response_invalid_utf8" valueToSum:nil parameters:nil accessToken:nil]; } } NSDictionary *responseError = nil; if (!response) { if ((error != NULL) && (*error == nil)) { *error = [self errorWithCode:FBSDKUnknownErrorCode statusCode:statusCode parsedJSONResponse:nil innerError:nil message:@"The server returned an unexpected response."]; } } else if ([self.requests count] == 1) { // response is the entry, so put it in a dictionary under "body" and add // that to array of responses. [results addObject:@{ @"code":@(statusCode), @"body":response }]; } else if ([response isKindOfClass:[NSArray class]]) { // response is the array of responses, but the body element of each needs // to be decoded from JSON. for (id item in response) { // Don't let errors parsing one response stop us from parsing another. NSError *batchResultError = nil; if (![item isKindOfClass:[NSDictionary class]]) { [results addObject:item]; } else { NSMutableDictionary *result = [((NSDictionary *)item) mutableCopy]; if (result[@"body"]) { result[@"body"] = [self parseJSONOrOtherwise:result[@"body"] error:&batchResultError]; } [results addObject:result]; } if (batchResultError) { // We'll report back the last error we saw. *error = batchResultError; } } } else if ([response isKindOfClass:[NSDictionary class]] && (responseError = [FBSDKTypeUtility dictionaryValue:response[@"error"]]) != nil && [responseError[@"type"] isEqualToString:@"OAuthException"]) { // if there was one request then return the only result. if there were multiple requests // but only one error then the server rejected the batch access token NSDictionary *result = @{ @"code":@(statusCode), @"body":response }; for (NSUInteger resultIndex = 0, resultCount = self.requests.count; resultIndex < resultCount; ++resultIndex) { [results addObject:result]; } } else if (error != NULL) { *error = [self errorWithCode:FBSDKGraphRequestProtocolMismatchErrorCode statusCode:statusCode parsedJSONResponse:results innerError:nil message:nil]; } return results; } - (id)parseJSONOrOtherwise:(NSString *)utf8 error:(NSError **)error { id parsed = nil; if (!(*error)) { parsed = [FBSDKInternalUtility objectForJSONString:utf8 error:error]; // if we fail parse we attempt a re-parse of a modified input to support results in the form "foo=bar", "true", etc. // which is shouldn't be necessary since Graph API v2.1. if (*error) { // we round-trip our hand-wired response through the parser in order to remain // consistent with the rest of the output of this function (note, if perf turns out // to be a problem -- unlikely -- we can return the following dictionary outright) NSDictionary *original = @{ FBSDKNonJSONResponseProperty : utf8 }; NSString *jsonrep = [FBSDKInternalUtility JSONStringForObject:original error:NULL invalidObjectHandler:NULL]; NSError *reparseError = nil; parsed = [FBSDKInternalUtility objectForJSONString:jsonrep error:&reparseError]; if (!reparseError) { *error = nil; } } } return parsed; } - (void)completeWithResults:(NSArray *)results networkError:(NSError *)networkError { NSUInteger count = [self.requests count]; _expectingResults = count; NSUInteger disabledRecoveryCount = 0; for (FBSDKGraphRequestMetadata *metadata in self.requests) { if ([metadata.request isGraphErrorRecoveryDisabled]) { disabledRecoveryCount++; } } #if !TARGET_OS_TV BOOL isSingleRequestToRecover = (count - disabledRecoveryCount == 1); #endif [self.requests enumerateObjectsUsingBlock:^(FBSDKGraphRequestMetadata *metadata, NSUInteger i, BOOL *stop) { id result = networkError ? nil : [results objectAtIndex:i]; NSError *resultError = networkError ?: [self errorFromResult:result request:metadata.request]; id body = nil; if (!resultError && [result isKindOfClass:[NSDictionary class]]) { NSDictionary *resultDictionary = [FBSDKTypeUtility dictionaryValue:result]; body = [FBSDKTypeUtility dictionaryValue:resultDictionary[@"body"]]; } #if !TARGET_OS_TV if (resultError && ![metadata.request isGraphErrorRecoveryDisabled] && isSingleRequestToRecover) { _recoveringRequestMetadata = metadata; _errorRecoveryProcessor = [[FBSDKGraphErrorRecoveryProcessor alloc] init]; if ([_errorRecoveryProcessor processError:resultError request:metadata.request delegate:self]) { return; } } #endif [self processResultBody:body error:resultError metadata:metadata canNotifyDelegate:networkError == nil]; }]; if (networkError) { if ([_delegate respondsToSelector:@selector(requestConnection:didFailWithError:)]) { [_delegate requestConnection:self didFailWithError:networkError]; } } } - (void)processResultBody:(NSDictionary *)body error:(NSError *)error metadata:(FBSDKGraphRequestMetadata *)metadata canNotifyDelegate:(BOOL)canNotifyDelegate { void (^finishAndInvokeCompletionHandler)(void) = ^{ NSDictionary *graphDebugDict = [body objectForKey:@"__debug__"]; if ([graphDebugDict isKindOfClass:[NSDictionary class]]) { [self processResultDebugDictionary: graphDebugDict]; } [metadata invokeCompletionHandlerForConnection:self withResults:body error:error]; if (--_expectingResults == 0) { if (canNotifyDelegate && [_delegate respondsToSelector:@selector(requestConnectionDidFinishLoading:)]) { [_delegate requestConnectionDidFinishLoading:self]; } } }; #if !TARGET_OS_TV void (^clearToken)(void) = ^{ if (!(metadata.request.flags & FBSDKGraphRequestFlagDoNotInvalidateTokenOnError)) { [FBSDKAccessToken setCurrentAccessToken:nil]; } }; FBSDKSystemAccountStoreAdapter *adapter = [FBSDKSystemAccountStoreAdapter sharedInstance]; NSString *metadataTokenString = metadata.request.tokenString; NSString *currentTokenString = [FBSDKAccessToken currentAccessToken].tokenString; NSString *accountStoreTokenString = adapter.accessTokenString; BOOL isAccountStoreLogin = [metadataTokenString isEqualToString:accountStoreTokenString]; if ([metadataTokenString isEqualToString:currentTokenString] || isAccountStoreLogin) { NSInteger errorCode = [error.userInfo[FBSDKGraphRequestErrorGraphErrorCode] integerValue]; NSInteger errorSubcode = [error.userInfo[FBSDKGraphRequestErrorGraphErrorSubcode] integerValue]; if (errorCode == 190 || errorCode == 102) { if (isAccountStoreLogin) { if (errorSubcode == 460) { // For iOS6, when the password is changed on the server, the system account store // will continue to issue the old token until the user has changed the // password AND _THEN_ a renew call is made. To prevent opening // with an old token which would immediately be closed, we tell our adapter // that we want to force a blocking renew until success. adapter.forceBlockingRenew = YES; } else { [adapter renewSystemAuthorization:^(ACAccountCredentialRenewResult result, NSError *renewError) { NSOperationQueue *queue = _delegateQueue ?: [NSOperationQueue mainQueue]; [queue addOperationWithBlock:^{ clearToken(); finishAndInvokeCompletionHandler(); }]; }]; return; } } clearToken(); } else if (errorCode >= 200 && errorCode < 300) { // permission error [adapter renewSystemAuthorization:^(ACAccountCredentialRenewResult result, NSError *renewError) { NSOperationQueue *queue = _delegateQueue ?: [NSOperationQueue mainQueue]; [queue addOperationWithBlock:finishAndInvokeCompletionHandler]; }]; return; } } #endif // this is already on the queue since we are currently in the NSURLSession callback. finishAndInvokeCompletionHandler(); } - (void)processResultDebugDictionary:(NSDictionary *)dict { NSArray *messages = [FBSDKTypeUtility arrayValue:dict[@"messages"]]; if (![messages count]) { return; } [messages enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { NSDictionary *messageDict = [FBSDKTypeUtility dictionaryValue:obj]; NSString *message = [FBSDKTypeUtility stringValue:messageDict[@"message"]]; NSString *type = [FBSDKTypeUtility stringValue:messageDict[@"type"]]; NSString *link = [FBSDKTypeUtility stringValue:messageDict[@"link"]]; if (!message || !type) { return; } NSString *loggingBehavior = FBSDKLoggingBehaviorGraphAPIDebugInfo; if ([type isEqualToString:@"warning"]) { loggingBehavior = FBSDKLoggingBehaviorGraphAPIDebugWarning; } if (link) { message = [message stringByAppendingFormat:@" Link: %@", link]; } [FBSDKLogger singleShotLogEntry:loggingBehavior logEntry:message]; }]; } - (NSError *)errorFromResult:(id)result request:(FBSDKGraphRequest *)request { if ([result isKindOfClass:[NSDictionary class]]) { NSDictionary *errorDictionary = [FBSDKTypeUtility dictionaryValue:result[@"body"]][@"error"]; if (errorDictionary) { NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; [FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"code"] forKey:FBSDKGraphRequestErrorGraphErrorCode]; [FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"error_subcode"] forKey:FBSDKGraphRequestErrorGraphErrorSubcode]; //"message" is preferred over error_msg or error_reason. [FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"error_msg"] forKey:FBSDKErrorDeveloperMessageKey]; [FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"error_reason"] forKey:FBSDKErrorDeveloperMessageKey]; [FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"message"] forKey:FBSDKErrorDeveloperMessageKey]; [FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"error_user_title"] forKey:FBSDKErrorLocalizedTitleKey]; [FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"error_user_msg"] forKey:FBSDKErrorLocalizedDescriptionKey]; [FBSDKInternalUtility dictionary:userInfo setObject:errorDictionary[@"error_user_msg"] forKey:NSLocalizedDescriptionKey]; [FBSDKInternalUtility dictionary:userInfo setObject:result[@"code"] forKey:FBSDKGraphRequestErrorHTTPStatusCodeKey]; [FBSDKInternalUtility dictionary:userInfo setObject:result forKey:FBSDKGraphRequestErrorParsedJSONResponseKey]; FBSDKErrorRecoveryConfiguration *recoveryConfiguration = [g_errorConfiguration recoveryConfigurationForCode:[userInfo[FBSDKGraphRequestErrorGraphErrorCode] stringValue] subcode:[userInfo[FBSDKGraphRequestErrorGraphErrorSubcode] stringValue] request:request]; if ([errorDictionary[@"is_transient"] boolValue]) { userInfo[FBSDKGraphRequestErrorCategoryKey] = @(FBSDKGraphRequestErrorCategoryTransient); } else { [FBSDKInternalUtility dictionary:userInfo setObject:@(recoveryConfiguration.errorCategory) forKey:FBSDKGraphRequestErrorCategoryKey]; } [FBSDKInternalUtility dictionary:userInfo setObject:recoveryConfiguration.localizedRecoveryDescription forKey:NSLocalizedRecoverySuggestionErrorKey]; [FBSDKInternalUtility dictionary:userInfo setObject:recoveryConfiguration.localizedRecoveryOptionDescriptions forKey:NSLocalizedRecoveryOptionsErrorKey]; FBSDKErrorRecoveryAttempter *attempter = [FBSDKErrorRecoveryAttempter recoveryAttempterFromConfiguration:recoveryConfiguration]; [FBSDKInternalUtility dictionary:userInfo setObject:attempter forKey:NSRecoveryAttempterErrorKey]; return [FBSDKError errorWithCode:FBSDKGraphRequestGraphAPIErrorCode userInfo:userInfo message:nil underlyingError:nil]; } } return nil; } - (NSError *)errorWithCode:(FBSDKErrorCode)code statusCode:(NSInteger)statusCode parsedJSONResponse:(id)response innerError:(NSError *)innerError message:(NSString *)message { NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init]; userInfo[FBSDKGraphRequestErrorHTTPStatusCodeKey] = @(statusCode); if (response) { userInfo[FBSDKGraphRequestErrorParsedJSONResponseKey] = response; } if (innerError) { userInfo[FBSDKGraphRequestErrorParsedJSONResponseKey] = innerError; } if (message) { userInfo[FBSDKErrorDeveloperMessageKey] = message; } NSError *error = [[NSError alloc] initWithDomain:FBSDKErrorDomain code:code userInfo:userInfo]; return error; } #pragma mark - Private methods (miscellaneous) - (void)logRequest:(NSMutableURLRequest *)request bodyLength:(NSUInteger)bodyLength bodyLogger:(FBSDKLogger *)bodyLogger attachmentLogger:(FBSDKLogger *)attachmentLogger { if (_logger.isActive) { [_logger appendFormat:@"Request <#%lu>:\n", (unsigned long)_logger.loggerSerialNumber]; [_logger appendKey:@"URL" value:[[request URL] absoluteString]]; [_logger appendKey:@"Method" value:[request HTTPMethod]]; [_logger appendKey:@"UserAgent" value:[request valueForHTTPHeaderField:@"User-Agent"]]; [_logger appendKey:@"MIME" value:[request valueForHTTPHeaderField:@"Content-Type"]]; if (bodyLength != 0) { [_logger appendKey:@"Body Size" value:[NSString stringWithFormat:@"%lu kB", (unsigned long)bodyLength / 1024]]; } if (bodyLogger != nil) { [_logger appendKey:@"Body (w/o attachments)" value:bodyLogger.contents]; } if (attachmentLogger != nil) { [_logger appendKey:@"Attachments" value:attachmentLogger.contents]; } [_logger appendString:@"\n"]; [_logger emitToNSLog]; } } - (NSString *)accessTokenWithRequest:(FBSDKGraphRequest *)request { NSString *token = request.tokenString ?: request.parameters[kAccessTokenKey]; if (!token && !(request.flags & FBSDKGraphRequestFlagSkipClientToken) && [FBSDKSettings clientToken].length > 0) { return [NSString stringWithFormat:@"%@|%@", [FBSDKSettings appID], [FBSDKSettings clientToken]]; } return token; } - (void)registerTokenToOmitFromLog:(NSString *)token { if (![[FBSDKSettings loggingBehavior] containsObject:FBSDKLoggingBehaviorAccessTokens]) { [FBSDKLogger registerStringToReplace:token replaceWith:@"ACCESS_TOKEN_REMOVED"]; } } + (NSString *)userAgent { static NSString *agent = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ agent = [NSString stringWithFormat:@"%@.%@", kUserAgentBase, FBSDK_VERSION_STRING]; }); if ([FBSDKSettings userAgentSuffix]) { return [NSString stringWithFormat:@"%@/%@", agent, [FBSDKSettings userAgentSuffix]]; } return agent; } - (NSURLSession *)defaultSession { NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration]; return [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:_delegateQueue]; } - (void)cleanUpSession { [self.session invalidateAndCancel]; self.session = nil; } #pragma mark - NSURLSessionDataDelegate - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend { id delegate = self.delegate; if ([delegate respondsToSelector:@selector(requestConnection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:)]) { [delegate requestConnection:self didSendBodyData:(NSUInteger)bytesSent totalBytesWritten:(NSUInteger)totalBytesSent totalBytesExpectedToWrite:(NSUInteger)totalBytesExpectedToSend]; } } #pragma mark - FBSDKGraphErrorRecoveryProcessorDelegate #if !TARGET_OS_TV - (void)processorDidAttemptRecovery:(FBSDKGraphErrorRecoveryProcessor *)processor didRecover:(BOOL)didRecover error:(NSError *)error { if (didRecover) { FBSDKGraphRequest *originalRequest = _recoveringRequestMetadata.request; FBSDKGraphRequest *retryRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:originalRequest.graphPath parameters:originalRequest.parameters tokenString:[FBSDKAccessToken currentAccessToken].tokenString version:originalRequest.version HTTPMethod:originalRequest.HTTPMethod]; // prevent further attempts at recovery (i.e., additional retries). [retryRequest setGraphErrorRecoveryDisabled:YES]; FBSDKGraphRequestMetadata *retryMetadata = [[FBSDKGraphRequestMetadata alloc] initWithRequest:retryRequest completionHandler:_recoveringRequestMetadata.completionHandler batchParameters:_recoveringRequestMetadata.batchParameters]; [retryRequest startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *retriedError) { [self processResultBody:result error:retriedError metadata:retryMetadata canNotifyDelegate:YES]; _errorRecoveryProcessor = nil; _recoveringRequestMetadata = nil; }]; } else { [self processResultBody:nil error:error metadata:_recoveringRequestMetadata canNotifyDelegate:YES]; _errorRecoveryProcessor = nil; _recoveringRequestMetadata = nil; } } #endif #pragma mark - Debugging helpers - (NSString *)description { NSMutableString *result = [NSMutableString stringWithFormat:@"<%@: %p, %lu request(s): (\n", NSStringFromClass([self class]), self, (unsigned long)self.requests.count]; BOOL comma = NO; for (FBSDKGraphRequestMetadata *metadata in self.requests) { FBSDKGraphRequest *request = metadata.request; if (comma) { [result appendString:@",\n"]; } [result appendString:[request description]]; comma = YES; } [result appendString:@"\n)>"]; return result; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphRequestDataAttachment.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import /*! @abstract A container class for data attachments so that additional metadata can be provided about the attachment. */ @interface FBSDKGraphRequestDataAttachment : NSObject /*! @abstract Initializes the receiver with the attachment data and metadata. @param data The attachment data (retained, not copied) @param filename The filename for the attachment @param contentType The content type for the attachment */ - (instancetype)initWithData:(NSData *)data filename:(NSString *)filename contentType:(NSString *)contentType NS_DESIGNATED_INITIALIZER; /*! @abstract The content type for the attachment. */ @property (nonatomic, copy, readonly) NSString *contentType; /*! @abstract The attachment data. */ @property (nonatomic, strong, readonly) NSData *data; /*! @abstract The filename for the attachment. */ @property (nonatomic, copy, readonly) NSString *filename; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphRequestDataAttachment.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKGraphRequestDataAttachment.h" #import "FBSDKMacros.h" @implementation FBSDKGraphRequestDataAttachment - (instancetype)initWithData:(NSData *)data filename:(NSString *)filename contentType:(NSString *)contentType { if ((self = [super init])) { _data = data; _filename = [filename copy]; _contentType = [contentType copy]; } return self; } - (instancetype)init { FBSDK_NOT_DESIGNATED_INITIALIZER(initWithData:filename:contentType:); return [self initWithData:nil filename:nil contentType:nil]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKMacros.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #ifdef __cplusplus #define FBSDK_EXTERN extern "C" __attribute__((visibility ("default"))) #else #define FBSDK_EXTERN extern __attribute__((visibility ("default"))) #endif #define FBSDK_STATIC_INLINE static inline #define FBSDK_NO_DESIGNATED_INITIALIZER() \ @throw [NSException exceptionWithName:NSInvalidArgumentException \ reason:[NSString stringWithFormat:@"unrecognized selector sent to instance %p", self] \ userInfo:nil] #define FBSDK_NOT_DESIGNATED_INITIALIZER(DESIGNATED_INITIALIZER) \ @throw [NSException exceptionWithName:NSInvalidArgumentException \ reason:[NSString stringWithFormat:@"Please use the designated initializer [%p %@]", \ self, \ NSStringFromSelector(@selector(DESIGNATED_INITIALIZER))] \ userInfo:nil] ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKMutableCopying.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /*! @abstract Extension protocol for NSMutableCopying that adds the mutableCopy method, which is implemented on NSObject. @discussion NSObject implicitly conforms to this protocol. */ @protocol FBSDKMutableCopying /*! @abstract Implemented by NSObject as a convenience to mutableCopyWithZone:. @return A mutable copy of the receiver. */ - (id)mutableCopy; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKMacros.h" #import "FBSDKProfilePictureView.h" /*! @abstract Notification indicating that the `currentProfile` has changed. @discussion the userInfo dictionary of the notification will contain keys `FBSDKProfileChangeOldKey` and `FBSDKProfileChangeNewKey`. */ FBSDK_EXTERN NSString *const FBSDKProfileDidChangeNotification; /* @abstract key in notification's userInfo object for getting the old profile. @discussion If there was no old profile, the key will not be present. */ FBSDK_EXTERN NSString *const FBSDKProfileChangeOldKey; /* @abstract key in notification's userInfo object for getting the new profile. @discussion If there is no new profile, the key will not be present. */ FBSDK_EXTERN NSString *const FBSDKProfileChangeNewKey; /*! @abstract Represents an immutable Facebook profile @discussion This class provides a global "currentProfile" instance to more easily add social context to your application. When the profile changes, a notification is posted so that you can update relevant parts of your UI and is persisted to NSUserDefaults. Typically, you will want to call `enableUpdatesOnAccessTokenChange:YES` so that it automatically observes changes to the `[FBSDKAccessToken currentAccessToken]`. You can use this class to build your own `FBSDKProfilePictureView` or in place of typical requests to "/me". */ @interface FBSDKProfile : NSObject /*! @abstract initializes a new instance. @param userID the user ID @param firstName the user's first name @param middleName the user's middle name @param lastName the user's last name @param name the user's complete name @param linkURL the link for this profile @param refreshDate the optional date this profile was fetched. Defaults to [NSDate date]. */ - (instancetype)initWithUserID:(NSString *)userID firstName:(NSString *)firstName middleName:(NSString *)middleName lastName:(NSString *)lastName name:(NSString *)name linkURL:(NSURL *)linkURL refreshDate:(NSDate *)refreshDate NS_DESIGNATED_INITIALIZER; /*! @abstract The user id */ @property (nonatomic, readonly) NSString *userID; /*! @abstract The user's first name */ @property (nonatomic, readonly) NSString *firstName; /*! @abstract The user's middle name */ @property (nonatomic, readonly) NSString *middleName; /*! @abstract The user's last name */ @property (nonatomic, readonly) NSString *lastName; /*! @abstract The user's complete name */ @property (nonatomic, readonly) NSString *name; /*! @abstract A URL to the user's profile. @discussion Consider using Bolts and `FBSDKAppLinkResolver` to resolve this to an app link to link directly to the user's profile in the Facebook app. */ @property (nonatomic, readonly) NSURL *linkURL; /*! @abstract The last time the profile data was fetched. */ @property (nonatomic, readonly) NSDate *refreshDate; /*! @abstract Gets the current FBSDKProfile instance. */ + (FBSDKProfile *)currentProfile; /*! @abstract Sets the current instance and posts the appropriate notification if the profile parameter is different than the receiver. @param profile the profile to set @discussion This persists the profile to NSUserDefaults. */ + (void)setCurrentProfile:(FBSDKProfile *)profile; /*! @abstract Indicates if `currentProfile` will automatically observe `FBSDKAccessTokenDidChangeNotification` notifications @param enable YES is observing @discussion If observing, this class will issue a graph request for public profile data when the current token's userID differs from the current profile. You can observe `FBSDKProfileDidChangeNotification` for when the profile is updated. Note that if `[FBSDKAccessToken currentAccessToken]` is unset, the `currentProfile` instance remains. It's also possible for `currentProfile` to return nil until the data is fetched. */ + (void)enableUpdatesOnAccessTokenChange:(BOOL)enable; /*! @abstract Loads the current profile and passes it to the completion block. @param completion The block to be executed once the profile is loaded @discussion If the profile is already loaded, this method will call the completion block synchronously, otherwise it will begin a graph request to update `currentProfile` and then call the completion block when finished. */ + (void)loadCurrentProfileWithCompletion:(void(^)(FBSDKProfile *profile, NSError *error))completion; /*! @abstract A convenience method for returning a complete `NSURL` for retrieving the user's profile image. @param mode The picture mode @param size The height and width. This will be rounded to integer precision. */ - (NSURL *)imageURLForPictureMode:(FBSDKProfilePictureMode)mode size:(CGSize)size; /*! @abstract A convenience method for returning a Graph API path for retrieving the user's profile image. @deprecated use `imageURLForPictureMode:size:` instead @discussion You can pass this to a `FBSDKGraphRequest` instance to download the image. @param mode The picture mode @param size The height and width. This will be rounded to integer precision. */ - (NSString *)imagePathForPictureMode:(FBSDKProfilePictureMode)mode size:(CGSize)size __attribute__ ((deprecated("use imageURLForPictureMode:size: instead"))); /*! @abstract Returns YES if the profile is equivalent to the receiver. @param profile the profile to compare to. */ - (BOOL)isEqualToProfile:(FBSDKProfile *)profile; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKProfile+Internal.h" #import "FBSDKCoreKit+Internal.h" NSString *const FBSDKProfileDidChangeNotification = @"com.facebook.sdk.FBSDKProfile.FBSDKProfileDidChangeNotification";; NSString *const FBSDKProfileChangeOldKey = @"FBSDKProfileOld"; NSString *const FBSDKProfileChangeNewKey = @"FBSDKProfileNew"; static NSString *const FBSDKProfileUserDefaultsKey = @"com.facebook.sdk.FBSDKProfile.currentProfile"; static FBSDKProfile *g_currentProfile; #define FBSDKPROFILE_USERID_KEY @"userID" #define FBSDKPROFILE_FIRSTNAME_KEY @"firstName" #define FBSDKPROFILE_MIDDLENAME_KEY @"middleName" #define FBSDKPROFILE_LASTNAME_KEY @"lastName" #define FBSDKPROFILE_NAME_KEY @"name" #define FBSDKPROFILE_LINKURL_KEY @"linkURL" #define FBSDKPROFILE_REFRESHDATE_KEY @"refreshDate" // Once a day #define FBSDKPROFILE_STALE_IN_SECONDS (60 * 60 * 24) @implementation FBSDKProfile - (instancetype)init NS_UNAVAILABLE { assert(0); } - (instancetype)initWithUserID:(NSString *)userID firstName:(NSString *)firstName middleName:(NSString *)middleName lastName:(NSString *)lastName name:(NSString *)name linkURL:(NSURL *)linkURL refreshDate:(NSDate *)refreshDate { if ((self = [super init])) { _userID = [userID copy]; _firstName = [firstName copy]; _middleName = [middleName copy]; _lastName = [lastName copy]; _name = [name copy]; _linkURL = [linkURL copy]; _refreshDate = [refreshDate copy] ?: [NSDate date]; } return self; } + (FBSDKProfile *)currentProfile { return g_currentProfile; } + (void)setCurrentProfile:(FBSDKProfile *)profile { if (profile != g_currentProfile && ![profile isEqualToProfile:g_currentProfile]) { [[self class] cacheProfile:profile]; NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; [FBSDKInternalUtility dictionary:userInfo setObject:profile forKey:FBSDKProfileChangeNewKey]; [FBSDKInternalUtility dictionary:userInfo setObject:g_currentProfile forKey:FBSDKProfileChangeOldKey]; g_currentProfile = profile; [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKProfileDidChangeNotification object:[self class] userInfo:userInfo]; } } - (NSURL *)imageURLForPictureMode:(FBSDKProfilePictureMode)mode size:(CGSize)size { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" NSString *path = [self imagePathForPictureMode:FBSDKProfilePictureModeNormal size:size]; #pragma clang diagnostic pop return [FBSDKInternalUtility facebookURLWithHostPrefix:@"graph" path:path queryParameters:nil error:NULL]; } - (NSString *)imagePathForPictureMode:(FBSDKProfilePictureMode)mode size:(CGSize)size { NSString *type; switch (mode) { case FBSDKProfilePictureModeNormal: type = @"normal"; break; case FBSDKProfilePictureModeSquare: type = @"square"; break; } return [NSString stringWithFormat:@"%@/picture?type=%@&width=%d&height=%d", _userID, type, (int) roundf(size.width), (int) roundf(size.height)]; } + (void)enableUpdatesOnAccessTokenChange:(BOOL)enable { if (enable) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(observeChangeAccessTokenChange:) name:FBSDKAccessTokenDidChangeNotification object:nil]; } else { [[NSNotificationCenter defaultCenter] removeObserver:self]; } } + (void)loadCurrentProfileWithCompletion:(void (^)(FBSDKProfile *, NSError *))completion { [self loadProfileWithToken:[FBSDKAccessToken currentAccessToken] completion:completion]; } #pragma mark - NSCopying - (instancetype)copyWithZone:(NSZone *)zone { //immutable return self; } #pragma mark - Equality - (NSUInteger)hash { NSUInteger subhashes[] = { [self.userID hash], [self.firstName hash], [self.middleName hash], [self.lastName hash], [self.name hash], [self.linkURL hash], [self.refreshDate hash] }; return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKProfile class]]){ return NO; } return [self isEqualToProfile:object]; } - (BOOL)isEqualToProfile:(FBSDKProfile *)profile { return ([_userID isEqualToString:profile.userID] && [_firstName isEqualToString:profile.firstName] && [_middleName isEqualToString:profile.middleName] && [_lastName isEqualToString:profile.lastName] && [_name isEqualToString:profile.name] && [_linkURL isEqual:profile.linkURL] && [_refreshDate isEqualToDate:profile.refreshDate]); } #pragma mark NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { NSString *userID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDKPROFILE_USERID_KEY]; NSString *firstName = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDKPROFILE_FIRSTNAME_KEY]; NSString *middleName = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDKPROFILE_MIDDLENAME_KEY]; NSString *lastName = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDKPROFILE_LASTNAME_KEY]; NSString *name = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDKPROFILE_NAME_KEY]; NSURL *linkURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDKPROFILE_LINKURL_KEY]; NSDate *refreshDate = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDKPROFILE_REFRESHDATE_KEY]; return [self initWithUserID:userID firstName:firstName middleName:middleName lastName:lastName name:name linkURL:linkURL refreshDate:refreshDate]; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:self.userID forKey:FBSDKPROFILE_USERID_KEY]; [encoder encodeObject:self.firstName forKey:FBSDKPROFILE_FIRSTNAME_KEY]; [encoder encodeObject:self.middleName forKey:FBSDKPROFILE_MIDDLENAME_KEY]; [encoder encodeObject:self.lastName forKey:FBSDKPROFILE_LASTNAME_KEY]; [encoder encodeObject:self.name forKey:FBSDKPROFILE_NAME_KEY]; [encoder encodeObject:self.linkURL forKey:FBSDKPROFILE_LINKURL_KEY]; [encoder encodeObject:self.refreshDate forKey:FBSDKPROFILE_REFRESHDATE_KEY]; } #pragma mark - Private + (void)loadProfileWithToken:(FBSDKAccessToken *)token completion:(void (^)(FBSDKProfile *, NSError *))completion { static FBSDKGraphRequestConnection *executingRequestConnection = nil; BOOL isStale = [[NSDate date] timeIntervalSinceDate:g_currentProfile.refreshDate] > FBSDKPROFILE_STALE_IN_SECONDS; if (token && (isStale || ![g_currentProfile.userID isEqualToString:token.userID])) { FBSDKProfile *expectedCurrentProfile = g_currentProfile; NSString *graphPath = @"me?fields=id,first_name,middle_name,last_name,name,link"; [executingRequestConnection cancel]; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath parameters:nil flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; executingRequestConnection = [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (expectedCurrentProfile != g_currentProfile) { // current profile has already changed since request was started. Let's not overwrite. if (completion != NULL) { completion(nil, nil); } return; } FBSDKProfile *profile = nil; if (!error) { profile = [[FBSDKProfile alloc] initWithUserID:result[@"id"] firstName:result[@"first_name"] middleName:result[@"middle_name"] lastName:result[@"last_name"] name:result[@"name"] linkURL:[NSURL URLWithString:result[@"link"]] refreshDate:[NSDate date]]; } [[self class] setCurrentProfile:profile]; if (completion != NULL) { completion(profile, error); } }]; } else if (completion != NULL) { completion(g_currentProfile, nil); } } + (void)observeChangeAccessTokenChange:(NSNotification *)notification { FBSDKAccessToken *token = notification.userInfo[FBSDKAccessTokenChangeNewKey]; [self loadProfileWithToken:token completion:NULL]; } @end @implementation FBSDKProfile(Internal) + (void)cacheProfile:(FBSDKProfile *) profile { NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; if (profile) { NSData *data = [NSKeyedArchiver archivedDataWithRootObject:profile]; [userDefaults setObject:data forKey:FBSDKProfileUserDefaultsKey]; } else { [userDefaults removeObjectForKey:FBSDKProfileUserDefaultsKey]; } [userDefaults synchronize]; } + (FBSDKProfile *)fetchCachedProfile { NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSData *data = [userDefaults objectForKey:FBSDKProfileUserDefaultsKey]; return (data != nil) ? [NSKeyedUnarchiver unarchiveObjectWithData:data] : nil; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import /*! @typedef FBSDKProfilePictureMode enum @abstract Defines the aspect ratio mode for the source image of the profile picture. */ typedef NS_ENUM(NSUInteger, FBSDKProfilePictureMode) { /*! @abstract A square cropped version of the image will be included in the view. */ FBSDKProfilePictureModeSquare, /*! @abstract The original picture's aspect ratio will be used for the source image in the view. */ FBSDKProfilePictureModeNormal, }; /*! @abstract A view to display a profile picture. */ @interface FBSDKProfilePictureView : UIView /*! @abstract The mode for the receiver to determine the aspect ratio of the source image. */ @property (nonatomic, assign) FBSDKProfilePictureMode pictureMode; /*! @abstract The profile ID to show the picture for. */ @property (nonatomic, copy) NSString *profileID; /*! @abstract Explicitly marks the receiver as needing to update the image. @discussion This method is called whenever any properties that affect the source image are modified, but this can also be used to trigger a manual update of the image if it needs to be re-downloaded. */ - (void)setNeedsImageUpdate; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKProfilePictureView.h" #import "FBSDKAccessToken.h" #import "FBSDKInternalUtility.h" #import "FBSDKMaleSilhouetteIcon.h" #import "FBSDKMath.h" #import "FBSDKURLConnection.h" #import "FBSDKUtility.h" @interface FBSDKProfilePictureViewState : NSObject - (instancetype)initWithProfileID:(NSString *)profileID size:(CGSize)size scale:(CGFloat)scale pictureMode:(FBSDKProfilePictureMode)pictureMode imageShouldFit:(BOOL)imageShouldFit; @property (nonatomic, assign, readonly) BOOL imageShouldFit; @property (nonatomic, assign, readonly) FBSDKProfilePictureMode pictureMode; @property (nonatomic, copy, readonly) NSString *profileID; @property (nonatomic, assign, readonly) CGFloat scale; @property (nonatomic, assign, readonly) CGSize size; - (BOOL)isEqualToState:(FBSDKProfilePictureViewState *)other; - (BOOL)isValidForState:(FBSDKProfilePictureViewState *)other; @end @implementation FBSDKProfilePictureViewState - (instancetype)initWithProfileID:(NSString *)profileID size:(CGSize)size scale:(CGFloat)scale pictureMode:(FBSDKProfilePictureMode)pictureMode imageShouldFit:(BOOL)imageShouldFit { if ((self = [super init])) { _profileID = [profileID copy]; _size = size; _scale = scale; _pictureMode = pictureMode; _imageShouldFit = imageShouldFit; } return self; } - (NSUInteger)hash { NSUInteger subhashes[] = { (NSUInteger)_imageShouldFit, (NSUInteger)_size.width, (NSUInteger)_size.height, (NSUInteger)_scale, (NSUInteger)_pictureMode, [_profileID hash], }; return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])]; } - (BOOL)isEqual:(id)object { if (![object isKindOfClass:[FBSDKProfilePictureViewState class]]) { return NO; } FBSDKProfilePictureViewState *other = (FBSDKProfilePictureViewState *)object; return [self isEqualToState:other]; } - (BOOL)isEqualToState:(FBSDKProfilePictureViewState *)other { return ([self isValidForState:other] && CGSizeEqualToSize(_size, other->_size) && (_scale == other->_scale)); } - (BOOL)isValidForState:(FBSDKProfilePictureViewState *)other { return (other != nil && (_imageShouldFit == other->_imageShouldFit) && (_pictureMode == other->_pictureMode) && [FBSDKInternalUtility object:_profileID isEqualToObject:other->_profileID]); } @end @implementation FBSDKProfilePictureView { BOOL _hasProfileImage; UIImageView *_imageView; FBSDKProfilePictureViewState *_lastState; BOOL _needsImageUpdate; BOOL _placeholderImageIsValid; } #pragma mark - Object Lifecycle - (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { [self _configureProfilePictureView]; } return self; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [super initWithCoder:decoder])) { [self _configureProfilePictureView]; } return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } #pragma mark - Properties - (void)setBounds:(CGRect)bounds { CGRect currentBounds = self.bounds; if (!CGRectEqualToRect(currentBounds, bounds)) { [super setBounds:bounds]; if (!CGSizeEqualToSize(currentBounds.size, bounds.size)) { _placeholderImageIsValid = NO; [self setNeedsImageUpdate]; } } } - (UIViewContentMode)contentMode { return _imageView.contentMode; } - (void)setContentMode:(UIViewContentMode)contentMode { if (_imageView.contentMode != contentMode) { _imageView.contentMode = contentMode; [super setContentMode:contentMode]; [self setNeedsImageUpdate]; } } - (void)setMode:(FBSDKProfilePictureMode)pictureMode { if (_pictureMode != pictureMode) { _pictureMode = pictureMode; [self setNeedsImageUpdate]; } } - (void)setProfileID:(NSString *)profileID { if (![FBSDKInternalUtility object:_profileID isEqualToObject:profileID]) { _profileID = [profileID copy]; _placeholderImageIsValid = NO; [self setNeedsImageUpdate]; } } #pragma mark - Public Methods - (void)setNeedsImageUpdate { if (!_imageView || CGRectIsEmpty(self.bounds)) { // we can't do anything with an empty view, so just bail out until we have a size return; } // ensure that we have an image. do this here so we can draw the placeholder image synchronously if we don't have one if (!_placeholderImageIsValid && !_hasProfileImage) { [self _setPlaceholderImage]; } // debounce calls to needsImage against the main runloop if (_needsImageUpdate) { return; } _needsImageUpdate = YES; __weak FBSDKProfilePictureView *weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf _needsImageUpdate]; }); } #pragma mark - Helper Methods + (void)_downloadImageWithState:(FBSDKProfilePictureViewState *)state completionBlock:(void(^)(NSData *data))completionBlock; { NSURL *imageURL = [self _imageURLWithState:state]; if (!imageURL) { return; } FBSDKURLConnectionHandler completionHandler = ^(FBSDKURLConnection *connection, NSError *error, NSURLResponse *response, NSData *responseData) { if (!error && [responseData length]) { completionBlock(responseData); } }; NSURLRequest *request = [[NSURLRequest alloc] initWithURL:imageURL]; [[[FBSDKURLConnection alloc] initWithRequest:request completionHandler:completionHandler] start]; } + (NSURL *)_imageURLWithState:(FBSDKProfilePictureViewState *)state { FBSDKAccessToken *accessToken = [FBSDKAccessToken currentAccessToken]; if ([state.profileID isEqualToString:@"me"] && !accessToken) { return nil; } NSString *path = [[NSString alloc] initWithFormat:@"/%@/picture", [FBSDKUtility URLEncode:state.profileID]]; CGSize size = state.size; NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; parameters[@"width"] = @(size.width); parameters[@"height"] = @(size.height); [FBSDKInternalUtility dictionary:parameters setObject:accessToken.tokenString forKey:@"access_token"]; return [FBSDKInternalUtility facebookURLWithHostPrefix:@"graph" path:path queryParameters:parameters error:NULL]; } - (void)_accessTokenDidChangeNotification:(NSNotification *)notification { if (![_profileID isEqualToString:@"me"] || !notification.userInfo[FBSDKAccessTokenDidChangeUserID]) { return; } _lastState = nil; [self setNeedsImageUpdate]; } - (void)_configureProfilePictureView { _imageView = [[UIImageView alloc] initWithFrame:self.bounds]; _imageView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); [self addSubview:_imageView]; _profileID = @"me"; self.backgroundColor = [UIColor whiteColor]; self.contentMode = UIViewContentModeScaleAspectFit; self.userInteractionEnabled = NO; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_accessTokenDidChangeNotification:) name:FBSDKAccessTokenDidChangeNotification object:nil]; [self setNeedsImageUpdate]; } - (BOOL)_imageShouldFit { switch (self.contentMode) { case UIViewContentModeBottom: case UIViewContentModeBottomLeft: case UIViewContentModeBottomRight: case UIViewContentModeCenter: case UIViewContentModeLeft: case UIViewContentModeRedraw: case UIViewContentModeRight: case UIViewContentModeScaleAspectFit: case UIViewContentModeTop: case UIViewContentModeTopLeft: case UIViewContentModeTopRight: return YES; case UIViewContentModeScaleAspectFill: case UIViewContentModeScaleToFill: return NO; } } - (CGSize)_imageSize:(BOOL)imageShouldFit scale:(CGFloat)scale { // get the image size based on the contentMode and pictureMode CGSize size = self.bounds.size; switch (_pictureMode) { case FBSDKProfilePictureModeSquare:{ CGFloat imageSize; if (imageShouldFit) { imageSize = MIN(size.width, size.height); } else { imageSize = MAX(size.width, size.height); } size = CGSizeMake(imageSize, imageSize); break; } case FBSDKProfilePictureModeNormal: // use the bounds size break; } // adjust for the screen scale size = CGSizeMake(size.width * scale, size.height * scale); return size; } - (void)_needsImageUpdate { _needsImageUpdate = NO; if (!_profileID) { if (!_placeholderImageIsValid) { [self _setPlaceholderImage]; } return; } // if the current image is no longer representative of the current state, clear the current value out; otherwise, // leave the current value until the new resolution image is downloaded BOOL imageShouldFit = [self _imageShouldFit]; UIScreen *screen = self.window.screen ?: [UIScreen mainScreen]; CGFloat scale = [screen scale]; CGSize imageSize = [self _imageSize:imageShouldFit scale:scale]; FBSDKProfilePictureViewState *state = [[FBSDKProfilePictureViewState alloc] initWithProfileID:_profileID size:imageSize scale:scale pictureMode:_pictureMode imageShouldFit:imageShouldFit]; if (![_lastState isValidForState:state]) { [self _setPlaceholderImage]; } _lastState = state; __weak FBSDKProfilePictureView *weakSelf = self; [[self class] _downloadImageWithState:state completionBlock:^(NSData *data) { [weakSelf _updateImageWithData:data state:state]; }]; } - (void)_setPlaceholderImage { UIColor *fillColor = [UIColor colorWithRed:157.0/255.0 green:177.0/255.0 blue:204.0/255.0 alpha:1.0]; _imageView.image = [[[FBSDKMaleSilhouetteIcon alloc] initWithColor:fillColor] imageWithSize:_imageView.bounds.size]; _placeholderImageIsValid = YES; _hasProfileImage = NO; } - (void)_updateImageWithData:(NSData *)data state:(FBSDKProfilePictureViewState *)state { // make sure we haven't updated the state since we began fetching the image if (![state isValidForState:_lastState]) { return; } UIImage *image = [[UIImage alloc] initWithData:data scale:state.scale]; if (image) { _imageView.image = image; _hasProfileImage = YES; } else { _hasProfileImage = NO; _placeholderImageIsValid = NO; [self setNeedsImageUpdate]; } } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /* * Constants defining logging behavior. Use with <[FBSDKSettings setLoggingBehavior]>. */ /*! Include access token in logging. */ FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorAccessTokens; /*! Log performance characteristics */ FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorPerformanceCharacteristics; /*! Log FBSDKAppEvents interactions */ FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorAppEvents; /*! Log Informational occurrences */ FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorInformational; /*! Log cache errors. */ FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorCacheErrors; /*! Log errors from SDK UI controls */ FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorUIControlErrors; /*! Log debug warnings from API response, i.e. when friends fields requested, but user_friends permission isn't granted. */ FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorGraphAPIDebugWarning; /*! Log warnings from API response, i.e. when requested feature will be deprecated in next version of API. Info is the lowest level of severity, using it will result in logging all previously mentioned levels. */ FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorGraphAPIDebugInfo; /*! Log errors from SDK network requests */ FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorNetworkRequests; /*! Log errors likely to be preventable by the developer. This is in the default set of enabled logging behaviors. */ FBSDK_EXTERN NSString *const FBSDKLoggingBehaviorDeveloperErrors; @interface FBSDKSettings : NSObject /*! @abstract Get the Facebook App ID used by the SDK. @discussion If not explicitly set, the default will be read from the application's plist (FacebookAppID). */ + (NSString *)appID; /*! @abstract Set the Facebook App ID to be used by the SDK. @param appID The Facebook App ID to be used by the SDK. */ + (void)setAppID:(NSString *)appID; /*! @abstract Get the default url scheme suffix used for sessions. @discussion If not explicitly set, the default will be read from the application's plist (FacebookUrlSchemeSuffix). */ + (NSString *)appURLSchemeSuffix; /*! @abstract Set the app url scheme suffix used by the SDK. @param appURLSchemeSuffix The url scheme suffix to be used by the SDK. */ + (void)setAppURLSchemeSuffix:(NSString *)appURLSchemeSuffix; /*! @abstract Retrieve the Client Token that has been set via [FBSDKSettings setClientToken]. @discussion If not explicitly set, the default will be read from the application's plist (FacebookClientToken). */ + (NSString *)clientToken; /*! @abstract Sets the Client Token for the Facebook App. @discussion This is needed for certain API calls when made anonymously, without a user-based access token. @param clientToken The Facebook App's "client token", which, for a given appid can be found in the Security section of the Advanced tab of the Facebook App settings found at */ + (void)setClientToken:(NSString *)clientToken; /*! @abstract A convenient way to toggle error recovery for all FBSDKGraphRequest instances created after this is set. @param disableGraphErrorRecovery YES or NO. */ + (void)setGraphErrorRecoveryDisabled:(BOOL)disableGraphErrorRecovery; /*! @abstract Get the Facebook Display Name used by the SDK. @discussion If not explicitly set, the default will be read from the application's plist (FacebookDisplayName). */ + (NSString *)displayName; /*! @abstract Set the default Facebook Display Name to be used by the SDK. @discussion This should match the Display Name that has been set for the app with the corresponding Facebook App ID, in the Facebook App Dashboard. @param displayName The Facebook Display Name to be used by the SDK. */ + (void)setDisplayName:(NSString *)displayName; /*! @abstract Get the Facebook domain part. @discussion If not explicitly set, the default will be read from the application's plist (FacebookDomainPart). */ + (NSString *)facebookDomainPart; /*! @abstract Set the subpart of the Facebook domain. @discussion This can be used to change the Facebook domain (e.g. @"beta") so that requests will be sent to graph.beta.facebook.com @param facebookDomainPart The domain part to be inserted into facebook.com. */ + (void)setFacebookDomainPart:(NSString *)facebookDomainPart; /*! @abstract The quality of JPEG images sent to Facebook from the SDK. @discussion If not explicitly set, the default is 0.9. @see [UIImageJPEGRepresentation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIKitFunctionReference/#//apple_ref/c/func/UIImageJPEGRepresentation) */ + (CGFloat)JPEGCompressionQuality; /*! @abstract Set the quality of JPEG images sent to Facebook from the SDK. @param JPEGCompressionQuality The quality for JPEG images, expressed as a value from 0.0 to 1.0. @see [UIImageJPEGRepresentation](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIKitFunctionReference/#//apple_ref/c/func/UIImageJPEGRepresentation) */ + (void)setJPEGCompressionQuality:(CGFloat)JPEGCompressionQuality; /*! @abstract Gets whether data such as that generated through FBSDKAppEvents and sent to Facebook should be restricted from being used for other than analytics and conversions. Defaults to NO. This value is stored on the device and persists across app launches. */ + (BOOL)limitEventAndDataUsage; /*! @abstract Sets whether data such as that generated through FBSDKAppEvents and sent to Facebook should be restricted from being used for other than analytics and conversions. Defaults to NO. This value is stored on the device and persists across app launches. @param limitEventAndDataUsage The desired value. */ + (void)setLimitEventAndDataUsage:(BOOL)limitEventAndDataUsage; /*! @abstract Retrieve the current iOS SDK version. */ + (NSString *)sdkVersion; /*! @abstract Retrieve the current Facebook SDK logging behavior. */ + (NSSet *)loggingBehavior; /*! @abstract Set the current Facebook SDK logging behavior. This should consist of strings defined as constants with FBSDKLoggingBehavior*. @param loggingBehavior A set of strings indicating what information should be logged. If nil is provided, the logging behavior is reset to the default set of enabled behaviors. Set to an empty set in order to disable all logging. @discussion You can also define this via an array in your app plist with key "FacebookLoggingBehavior" or add and remove individual values via enableLoggingBehavior: or disableLogginBehavior: */ + (void)setLoggingBehavior:(NSSet *)loggingBehavior; /*! @abstract Enable a particular Facebook SDK logging behavior. @param loggingBehavior The LoggingBehavior to enable. This should be a string defined as a constant with FBSDKLoggingBehavior*. */ + (void)enableLoggingBehavior:(NSString *)loggingBehavior; /*! @abstract Disable a particular Facebook SDK logging behavior. @param loggingBehavior The LoggingBehavior to disable. This should be a string defined as a constant with FBSDKLoggingBehavior*. */ + (void)disableLoggingBehavior:(NSString *)loggingBehavior; /*! @abstract Set the user defaults key used by legacy token caches. @param tokenInformationKeyName the key used by legacy token caches. @discussion Use this only if you customized FBSessionTokenCachingStrategy in v3.x of the Facebook SDK for iOS. */ + (void)setLegacyUserDefaultTokenInformationKeyName:(NSString *)tokenInformationKeyName; /*! @abstract Get the user defaults key used by legacy token caches. */ + (NSString *)legacyUserDefaultTokenInformationKeyName; /*! @abstract Overrides the default Graph API version to use with `FBSDKGraphRequests`. This overrides `FBSDK_TARGET_PLATFORM_VERSION`. @discussion The string should be of the form `@"v2.7"`. */ + (void)setGraphAPIVersion:(NSString *)version; /*! @abstract Returns the default Graph API version. Defaults to `FBSDK_TARGET_PLATFORM_VERSION` */ + (NSString *)graphAPIVersion; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKSettings+Internal.h" #import "FBSDKCoreKit.h" #define FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(TYPE, PLIST_KEY, GETTER, SETTER, DEFAULT_VALUE) \ static TYPE *g_##PLIST_KEY = nil; \ + (TYPE *)GETTER \ { \ if (!g_##PLIST_KEY) { \ g_##PLIST_KEY = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@#PLIST_KEY] copy] ?: DEFAULT_VALUE; \ } \ return g_##PLIST_KEY; \ } \ + (void)SETTER:(TYPE *)value { \ g_##PLIST_KEY = [value copy]; \ } NSString *const FBSDKLoggingBehaviorAccessTokens = @"include_access_tokens"; NSString *const FBSDKLoggingBehaviorPerformanceCharacteristics = @"perf_characteristics"; NSString *const FBSDKLoggingBehaviorAppEvents = @"app_events"; NSString *const FBSDKLoggingBehaviorInformational = @"informational"; NSString *const FBSDKLoggingBehaviorCacheErrors = @"cache_errors"; NSString *const FBSDKLoggingBehaviorUIControlErrors = @"ui_control_errors"; NSString *const FBSDKLoggingBehaviorDeveloperErrors = @"developer_errors"; NSString *const FBSDKLoggingBehaviorGraphAPIDebugWarning = @"graph_api_debug_warning"; NSString *const FBSDKLoggingBehaviorGraphAPIDebugInfo = @"graph_api_debug_info"; NSString *const FBSDKLoggingBehaviorNetworkRequests = @"network_requests"; static FBSDKAccessTokenCache *g_tokenCache; static NSMutableSet *g_loggingBehavior; static NSString *g_legacyUserDefaultTokenInformationKeyName = @"FBAccessTokenInformationKey"; static NSString *const FBSDKSettingsLimitEventAndDataUsage = @"com.facebook.sdk:FBSDKSettingsLimitEventAndDataUsage"; static BOOL g_disableErrorRecovery; static NSString *g_userAgentSuffix; static NSString *g_defaultGraphAPIVersion; @implementation FBSDKSettings + (void)initialize { if (self == [FBSDKSettings class]) { g_tokenCache = [[FBSDKAccessTokenCache alloc] init]; } } #pragma mark - Plist Configuration Settings FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookAppID, appID, setAppID, nil); FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookUrlSchemeSuffix, appURLSchemeSuffix, setAppURLSchemeSuffix, nil); FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookClientToken, clientToken, setClientToken, nil); FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookDisplayName, displayName, setDisplayName, nil); FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSString, FacebookDomainPart, facebookDomainPart, setFacebookDomainPart, nil); FBSDKSETTINGS_PLIST_CONFIGURATION_SETTING_IMPL(NSNumber, FacebookJpegCompressionQuality, _JPEGCompressionQualityNumber, _setJPEGCompressionQualityNumber, @(0.9)); + (void)setGraphErrorRecoveryDisabled:(BOOL)disableGraphErrorRecovery { g_disableErrorRecovery = disableGraphErrorRecovery; } + (BOOL)isGraphErrorRecoveryDisabled { return g_disableErrorRecovery; } + (CGFloat)JPEGCompressionQuality { return [[self _JPEGCompressionQualityNumber] floatValue]; } + (void)setJPEGCompressionQuality:(CGFloat)JPEGCompressionQuality { [self _setJPEGCompressionQualityNumber:@(JPEGCompressionQuality)]; } + (BOOL)limitEventAndDataUsage { NSNumber *storedValue = [[NSUserDefaults standardUserDefaults] objectForKey:FBSDKSettingsLimitEventAndDataUsage]; if (storedValue == nil) { return NO; } return storedValue.boolValue; } + (void)setLimitEventAndDataUsage:(BOOL)limitEventAndDataUsage { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject:@(limitEventAndDataUsage) forKey:FBSDKSettingsLimitEventAndDataUsage]; [defaults synchronize]; } + (NSSet *)loggingBehavior { if (!g_loggingBehavior) { NSArray *bundleLoggingBehaviors = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FacebookLoggingBehavior"]; if (bundleLoggingBehaviors) { g_loggingBehavior = [[NSMutableSet alloc] initWithArray:bundleLoggingBehaviors]; } else { // Establish set of default enabled logging behaviors. You can completely disable logging by // specifying an empty array for FacebookLoggingBehavior in your Info.plist. g_loggingBehavior = [[NSMutableSet alloc] initWithObjects:FBSDKLoggingBehaviorDeveloperErrors, nil]; } } return [g_loggingBehavior copy]; } + (void)setLoggingBehavior:(NSSet *)loggingBehavior { if (![g_loggingBehavior isEqualToSet:loggingBehavior]) { g_loggingBehavior = [loggingBehavior mutableCopy]; [self updateGraphAPIDebugBehavior]; } } + (void)enableLoggingBehavior:(NSString *)loggingBehavior { if (!g_loggingBehavior) { [self loggingBehavior]; } [g_loggingBehavior addObject:loggingBehavior]; [self updateGraphAPIDebugBehavior]; } + (void)disableLoggingBehavior:(NSString *)loggingBehavior { if (!g_loggingBehavior) { [self loggingBehavior]; } [g_loggingBehavior removeObject:loggingBehavior]; [self updateGraphAPIDebugBehavior]; } + (void)setLegacyUserDefaultTokenInformationKeyName:(NSString *)tokenInformationKeyName { if (![g_legacyUserDefaultTokenInformationKeyName isEqualToString:tokenInformationKeyName]) { g_legacyUserDefaultTokenInformationKeyName = tokenInformationKeyName; } } + (NSString *)legacyUserDefaultTokenInformationKeyName { return g_legacyUserDefaultTokenInformationKeyName; } #pragma mark - Readonly Configuration Settings + (NSString *)sdkVersion { return FBSDK_VERSION_STRING; } #pragma mark - Object Lifecycle - (instancetype)init { FBSDK_NO_DESIGNATED_INITIALIZER(); return nil; } #pragma mark - Internal + (FBSDKAccessTokenCache *)accessTokenCache { return g_tokenCache; } - (void)setAccessTokenCache:(FBSDKAccessTokenCache *)cache { if (g_tokenCache != cache) { g_tokenCache = cache; } } + (NSString *)userAgentSuffix { return g_userAgentSuffix; } + (void)setUserAgentSuffix:(NSString *)suffix { if (![g_userAgentSuffix isEqualToString:suffix]) { g_userAgentSuffix = suffix; } } + (void)setGraphAPIVersion:(NSString *)version { if (![g_defaultGraphAPIVersion isEqualToString:version]) { g_defaultGraphAPIVersion = version; } } + (NSString *)graphAPIVersion { return g_defaultGraphAPIVersion ?: FBSDK_TARGET_PLATFORM_VERSION; } #pragma mark - Internal - Graph API Debug + (void)updateGraphAPIDebugBehavior { // Enable Warnings everytime Info is enabled if ([g_loggingBehavior containsObject:FBSDKLoggingBehaviorGraphAPIDebugInfo] && ![g_loggingBehavior containsObject:FBSDKLoggingBehaviorGraphAPIDebugWarning]) { [g_loggingBehavior addObject:FBSDKLoggingBehaviorGraphAPIDebugWarning]; } } + (NSString *)graphAPIDebugParamValue { if ([[self loggingBehavior] containsObject:FBSDKLoggingBehaviorGraphAPIDebugInfo]) { return @"info"; } else if ([[self loggingBehavior] containsObject:FBSDKLoggingBehaviorGraphAPIDebugWarning]) { return @"warning"; } return nil; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKTestUsersManager.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @class FBSDKAccessToken; /*! @typedef @abstract Callback block for returning an array of FBSDKAccessToken instances (and possibly `NSNull` instances); or an error. */ typedef void (^FBSDKTestUsersManagerRetrieveTestAccountTokensHandler)(NSArray *tokens, NSError *error) ; /*! @typedef @abstract Callback block for removing a test user. */ typedef void (^FBSDKTestUsersManagerRemoveTestAccountHandler)(NSError *error) ; /*! @class FBSDKTestUsersManager @abstract Provides methods for managing test accounts for testing Facebook integration. @discussion Facebook allows developers to create test accounts for testing their applications' Facebook integration (see https://developers.facebook.com/docs/test_users/). This class simplifies use of these accounts for writing tests. It is not designed for use in production application code. This class will make Graph API calls on behalf of your app to manage test accounts and requires an app id and app secret. You will typically use this class to write unit or integration tests. Make sure you NEVER include your app secret in your production app. */ @interface FBSDKTestUsersManager : NSObject /*! @abstract construct or return the shared instance @param appID the Facebook app id @param appSecret the Facebook app secret */ + (instancetype)sharedInstanceForAppID:(NSString *)appID appSecret:(NSString *)appSecret; /*! @abstract retrieve FBSDKAccessToken instances for test accounts with the specific permissions. @param arraysOfPermissions an array of permissions sets, such as @[ [NSSet setWithObject:@"email"], [NSSet setWithObject:@"user_birthday"]] if you needed two test accounts with email and birthday permissions, respectively. You can pass in empty nested sets if you need two arbitrary test accounts. For convenience, passing nil is treated as @[ [NSSet set] ] for fetching a single test user. @param createIfNotFound if YES, new test accounts are created if no test accounts existed that fit the permissions requirement @param handler the callback to invoke which will return an array of `FBAccessTokenData` instances or an `NSError`. If param `createIfNotFound` is NO, the array may contain `[NSNull null]` instances. @discussion If you are requesting test accounts with differing number of permissions, try to order `arrayOfPermissionsArrays` so that the most number of permissions come first to minimize creation of new test accounts. */ - (void)requestTestAccountTokensWithArraysOfPermissions:(NSArray *)arraysOfPermissions createIfNotFound:(BOOL)createIfNotFound completionHandler:(FBSDKTestUsersManagerRetrieveTestAccountTokensHandler)handler; /*! @abstract add a test account with the specified permissions @param permissions the set of permissions, e.g., [NSSet setWithObjects:@"email", @"user_friends"] @param handler the callback handler */ - (void)addTestAccountWithPermissions:(NSSet *)permissions completionHandler:(FBSDKTestUsersManagerRetrieveTestAccountTokensHandler)handler; /*! @abstract remove a test account for the given user id @param userId the user id @param handler the callback handler */ - (void)removeTestAccount:(NSString *)userId completionHandler:(FBSDKTestUsersManagerRemoveTestAccountHandler)handler; /*! @abstract Make two test users friends with each other. @param first the token of the first user @param second the token of the second user @param callback the callback handler */ - (void)makeFriendsWithFirst:(FBSDKAccessToken *)first second:(FBSDKAccessToken *)second callback:(void (^)(NSError *))callback; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKTestUsersManager.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKTestUsersManager.h" #import "FBSDKCoreKit+Internal.h" static NSString *const kFBGraphAPITestUsersPathFormat = @"%@/accounts/test-users"; static NSString *const kAccountsDictionaryTokenKey = @"access_token"; static NSString *const kAccountsDictionaryPermissionsKey = @"permissions"; static NSMutableDictionary *gInstancesDictionary; @interface FBSDKTestUsersManager() - (instancetype)initWithAppID:(NSString *)appID appSecret:(NSString *)appSecret NS_DESIGNATED_INITIALIZER; @end @implementation FBSDKTestUsersManager { NSString *_appID; NSString *_appSecret; // dictionary with format like: // { user_id : { kAccountsDictionaryTokenKey : "token", // kAccountsDictionaryPermissionsKey : [ permissions ] } NSMutableDictionary *_accounts; } - (instancetype)initWithAppID:(NSString *)appID appSecret:(NSString *)appSecret { if ((self = [super init])) { _appID = [appID copy]; _appSecret = [appSecret copy]; _accounts = [NSMutableDictionary dictionary]; } return self; } - (instancetype)init { FBSDK_NOT_DESIGNATED_INITIALIZER(initWithAppID:appSecret:); return [self initWithAppID:nil appSecret:nil]; } + (instancetype)sharedInstanceForAppID:(NSString *)appID appSecret:(NSString *)appSecret { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ gInstancesDictionary = [NSMutableDictionary dictionary]; }); NSString *instanceKey = [NSString stringWithFormat:@"%@|%@", appID, appSecret]; if (!gInstancesDictionary[instanceKey]) { gInstancesDictionary[instanceKey] = [[FBSDKTestUsersManager alloc] initWithAppID:appID appSecret:appSecret]; } return gInstancesDictionary[instanceKey]; } - (void)requestTestAccountTokensWithArraysOfPermissions:(NSArray *)arraysOfPermissions createIfNotFound:(BOOL)createIfNotFound completionHandler:(FBSDKTestUsersManagerRetrieveTestAccountTokensHandler)handler { arraysOfPermissions = arraysOfPermissions ?: @[[NSSet set]]; // wrap work in a block so that we can chain it to after a fetch of existing accounts if we need to. void (^helper)(NSError *) = ^(NSError *error){ if (error) { if (handler) { handler(nil, error); } return; } NSMutableArray *tokenDatum = [NSMutableArray arrayWithCapacity:arraysOfPermissions.count]; NSMutableSet *collectedUserIds = [NSMutableSet setWithCapacity:arraysOfPermissions.count]; __block BOOL canInvokeHandler = YES; __weak id weakSelf = self; [arraysOfPermissions enumerateObjectsUsingBlock:^(NSSet *desiredPermissions, NSUInteger idx, BOOL *stop) { NSArray* userIdAndTokenPair = [self userIdAndTokenOfExistingAccountWithPermissions:desiredPermissions skip:collectedUserIds]; if (!userIdAndTokenPair) { if (createIfNotFound) { [self addTestAccountWithPermissions:desiredPermissions completionHandler:^(NSArray *tokens, NSError *addError) { if (addError) { if (handler) { handler(nil, addError); } } else { [weakSelf requestTestAccountTokensWithArraysOfPermissions:arraysOfPermissions createIfNotFound:createIfNotFound completionHandler:handler]; } }]; // stop the enumeration (ane flag so that callback to addTestAccount* will resolve our handler now). canInvokeHandler = NO; *stop = YES; return; } else { [tokenDatum addObject:[NSNull null]]; } } else { NSString *userId = userIdAndTokenPair[0]; NSString *tokenString = userIdAndTokenPair[1]; [collectedUserIds addObject:userId]; [tokenDatum addObject:[self tokenDataForTokenString:tokenString permissions:desiredPermissions userId:userId]]; } }]; if (canInvokeHandler && handler) { handler(tokenDatum, nil); } }; if (_accounts.count == 0) { [self fetchExistingTestAccountsWithAfterCursor:nil handler:helper]; } else { helper(NULL); } } - (void)addTestAccountWithPermissions:(NSSet *)permissions completionHandler:(FBSDKTestUsersManagerRetrieveTestAccountTokensHandler)handler { NSDictionary *params = @{ @"installed" : @"true", @"permissions" : [[permissions allObjects] componentsJoinedByString:@","], @"access_token" : self.appAccessToken }; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:kFBGraphAPITestUsersPathFormat, _appID] parameters:params tokenString:[self appAccessToken] version:nil HTTPMethod:@"POST"]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (error) { if (handler) { handler(nil, error); } } else { NSMutableDictionary *accountData = [NSMutableDictionary dictionaryWithCapacity:2]; accountData[kAccountsDictionaryPermissionsKey] = [NSSet setWithSet:permissions]; accountData[kAccountsDictionaryTokenKey] = result[@"access_token"]; _accounts[result[@"id"]] = accountData; if (handler) { FBSDKAccessToken *token = [self tokenDataForTokenString:accountData[kAccountsDictionaryTokenKey] permissions:permissions userId:result[@"id"]]; handler(@[token], nil); } } }]; } - (void)makeFriendsWithFirst:(FBSDKAccessToken *)first second:(FBSDKAccessToken *)second callback:(void (^)(NSError *))callback { __block int expectedCount = 2; void (^complete)(NSError *) = ^(NSError *error) { // ignore if they're already friends or pending request if ([error.userInfo[FBSDKGraphRequestErrorGraphErrorCode] integerValue] == 522 || [error.userInfo[FBSDKGraphRequestErrorGraphErrorCode] integerValue] == 520) { error = nil; } if (--expectedCount == 0 || error) { callback(error); } }; FBSDKGraphRequest *one = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/friends/%@", first.userID, second.userID] parameters:nil tokenString:first.tokenString version:nil HTTPMethod:@"POST"]; FBSDKGraphRequest *two = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@/friends/%@", second.userID, first.userID] parameters:nil tokenString:second.tokenString version:nil HTTPMethod:@"POST"]; FBSDKGraphRequestConnection *conn = [[FBSDKGraphRequestConnection alloc] init]; [conn addRequest:one completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { complete(error); } batchEntryName:@"first"]; [conn addRequest:two completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { complete(error); } batchParameters:@{ @"depends_on" : @"first"} ]; [conn start]; } - (void)removeTestAccount:(NSString *)userId completionHandler:(FBSDKTestUsersManagerRemoveTestAccountHandler)handler { FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:userId parameters:nil tokenString:self.appAccessToken version:nil HTTPMethod:@"DELETE"]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (handler) { handler(error); } }]; [_accounts removeObjectForKey:userId]; } #pragma mark - private methods - (FBSDKAccessToken *)tokenDataForTokenString:(NSString *)tokenString permissions:(NSSet *)permissions userId:(NSString *)userId{ return [[FBSDKAccessToken alloc] initWithTokenString:tokenString permissions:[permissions allObjects] declinedPermissions:nil appID:_appID userID:userId expirationDate:nil refreshDate:nil]; } - (NSArray *)userIdAndTokenOfExistingAccountWithPermissions:(NSSet *)permissions skip:(NSSet *)setToSkip { __block NSString *userId = nil; __block NSString *token = nil; [_accounts enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSDictionary *accountData, BOOL *stop) { if ([setToSkip containsObject:key]) { return; } NSSet *accountPermissions = accountData[kAccountsDictionaryPermissionsKey]; if ([permissions isSubsetOfSet:accountPermissions]) { token = accountData[kAccountsDictionaryTokenKey]; userId = key; *stop = YES; } }]; if (userId && token) { return @[userId, token]; } else { return nil; } } - (NSString *)appAccessToken { return [NSString stringWithFormat:@"%@|%@", _appID, _appSecret]; } - (void)fetchExistingTestAccountsWithAfterCursor:(NSString *)after handler:(void(^)(NSError *error))handler { FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; FBSDKGraphRequest *requestForAccountIds = [[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:kFBGraphAPITestUsersPathFormat, _appID] parameters:@{@"limit" : @"50", @"after" : after ?: @"", @"fields": @"" } tokenString:self.appAccessToken version:nil HTTPMethod:nil]; __block NSString *afterCursor = nil; __block NSInteger expectedTestAccounts = 0; FBSDKGraphRequestConnection *permissionConnection = [[FBSDKGraphRequestConnection alloc] init]; [connection addRequest:requestForAccountIds completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id result, NSError *error) { if (error) { if (handler) { handler(error); } // on errors, clear out accounts since it may be in a bad state [_accounts removeAllObjects]; return; } else { for (NSDictionary *account in result[@"data"]) { NSString *userId = account[@"id"]; NSString *token = account[@"access_token"]; if (userId && token) { _accounts[userId] = [NSMutableDictionary dictionaryWithCapacity:2]; _accounts[userId][kAccountsDictionaryTokenKey] = token; expectedTestAccounts++; [permissionConnection addRequest:[[FBSDKGraphRequest alloc] initWithGraphPath:[NSString stringWithFormat:@"%@?fields=permissions", userId] parameters:nil tokenString:self.appAccessToken version:nil HTTPMethod:nil] completionHandler:^(FBSDKGraphRequestConnection *innerConnection2, id innerResult, NSError *innerError) { if (_accounts.count == 0) { // indicates an earlier error that was already passed to handler, so just short circuit. return; } if (innerError) { if (handler) { handler(innerError); } [_accounts removeAllObjects]; return; } else { NSMutableSet *grantedPermissions = [NSMutableSet set]; NSArray *resultPermissionsDictionaries = innerResult[@"permissions"][@"data"]; [resultPermissionsDictionaries enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) { if ([obj[@"status"] isEqualToString:@"granted"]) { [grantedPermissions addObject:obj[@"permission"]]; } }]; _accounts[userId][kAccountsDictionaryPermissionsKey] = grantedPermissions; } expectedTestAccounts--; if (!expectedTestAccounts) { if (afterCursor) { [self fetchExistingTestAccountsWithAfterCursor:afterCursor handler:handler]; } else if (handler) { handler(nil); } } } ]; } } afterCursor = result[@"paging"][@"cursors"][@"after"]; } if (expectedTestAccounts) { // finished fetching ids and tokens, now kick off the request for all the permissions [permissionConnection start]; } else { if (handler) { handler(nil); } } }]; [connection start]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKUtility.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import /*! @abstract Class to contain common utility methods. */ @interface FBSDKUtility : NSObject /*! @abstract Parses a query string into a dictionary. @param queryString The query string value. @return A dictionary with the key/value pairs. */ + (NSDictionary *)dictionaryWithQueryString:(NSString *)queryString; /*! @abstract Constructs a query string from a dictionary. @param dictionary The dictionary with key/value pairs for the query string. @param errorRef If an error occurs, upon return contains an NSError object that describes the problem. @result Query string representation of the parameters. */ + (NSString *)queryStringWithDictionary:(NSDictionary *)dictionary error:(NSError *__autoreleasing *)errorRef; /*! @abstract Decodes a value from an URL. @param value The value to decode. @result The decoded value. */ + (NSString *)URLDecode:(NSString *)value; /*! @abstract Encodes a value for an URL. @param value The value to encode. @result The encoded value. */ + (NSString *)URLEncode:(NSString *)value; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/FBSDKUtility.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKUtility.h" #import "FBSDKInternalUtility.h" #import "FBSDKMacros.h" @implementation FBSDKUtility + (NSDictionary *)dictionaryWithQueryString:(NSString *)queryString { NSMutableDictionary *result = [[NSMutableDictionary alloc] init]; NSArray *parts = [queryString componentsSeparatedByString:@"&"]; for (NSString *part in parts) { if ([part length] == 0) { continue; } NSRange index = [part rangeOfString:@"="]; NSString *key; NSString *value; if (index.location == NSNotFound) { key = part; value = @""; } else { key = [part substringToIndex:index.location]; value = [part substringFromIndex:index.location + index.length]; } key = [self URLDecode:key]; value = [self URLDecode:value]; if (key && value) { result[key] = value; } } return result; } + (NSString *)queryStringWithDictionary:(NSDictionary *)dictionary error:(NSError *__autoreleasing *)errorRef { return [FBSDKInternalUtility queryStringWithDictionary:dictionary error:errorRef invalidObjectHandler:NULL]; } + (NSString *)URLDecode:(NSString *)value { value = [value stringByReplacingOccurrencesOfString:@"+" withString:@" "]; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" value = [value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; #pragma clang diagnostic pop return value; } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" + (NSString *)URLEncode:(NSString *)value { return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)value, NULL, // characters to leave unescaped CFSTR(":!*();@/&?+$,='"), kCFStringEncodingUTF8); } #pragma clang diagnostic pop - (instancetype)init { FBSDK_NO_DESIGNATED_INITIALIZER(); return nil; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEvents+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import "FBSDKAppEventsUtility.h" @class FBSDKGraphRequest; // Internally known event names FBSDK_EXTERN NSString *const FBSDKAppEventNamePurchased; /*! Use to log that the share dialog was launched */ FBSDK_EXTERN NSString *const FBSDKAppEventNameShareSheetLaunch; /*! Use to log that the share dialog was dismissed */ FBSDK_EXTERN NSString *const FBSDKAppEventNameShareSheetDismiss; /*! Use to log that the permissions UI was launched */ FBSDK_EXTERN NSString *const FBSDKAppEventNamePermissionsUILaunch; /*! Use to log that the permissions UI was dismissed */ FBSDK_EXTERN NSString *const FBSDKAppEventNamePermissionsUIDismiss; /*! Use to log that the login view was used */ FBSDK_EXTERN NSString *const FBSDKAppEventNameLoginViewUsage; // Internally known event parameters /*! String parameter specifying the outcome of a dialog invocation */ FBSDK_EXTERN NSString *const FBSDKAppEventParameterDialogOutcome; /*! Parameter key used to specify which application launches this application. */ FBSDK_EXTERN NSString *const FBSDKAppEventParameterLaunchSource; /*! Use to log the result of a call to FBDialogs presentShareDialogWithParams: */ FBSDK_EXTERN NSString *const FBSDKAppEventNameFBDialogsPresentShareDialog; /*! Use to log the result of a call to FBDialogs presentShareDialogWithOpenGraphActionParams: */ FBSDK_EXTERN NSString *const FBSDKAppEventNameFBDialogsPresentShareDialogOG; /*! Use to log the result of a call to FBDialogs presentLikeDialogWithLikeParams: */ FBSDK_EXTERN NSString *const FBSDKAppEventNameFBDialogsPresentLikeDialogOG; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBDialogsPresentShareDialogPhoto; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBDialogsPresentMessageDialog; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBDialogsPresentMessageDialogPhoto; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBDialogsPresentMessageDialogOG; /*! Use to log the start of an auth request that cannot be fulfilled by the token cache */ FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSessionAuthStart; /*! Use to log the end of an auth request that was not fulfilled by the token cache */ FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSessionAuthEnd; /*! Use to log the start of a specific auth method as part of an auth request */ FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSessionAuthMethodStart; /*! Use to log the end of the last tried auth method as part of an auth request */ FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSessionAuthMethodEnd; /*! Use to log the timestamp for the transition to the Facebook native login dialog */ FBSDK_EXTERN NSString *const FBSDKAppEventNameFBDialogsNativeLoginDialogStart; /*! Use to log the timestamp for the transition back to the app after the Facebook native login dialog */ FBSDK_EXTERN NSString *const FBSDKAppEventNameFBDialogsNativeLoginDialogEnd; /*! Use to log the e2e timestamp metrics for web login */ FBSDK_EXTERN NSString *const FBSDKAppEventNameFBDialogsWebLoginCompleted; /*! Use to log the results of a share dialog */ FBSDK_EXTERN NSString *const FBSDLAppEventNameFBSDKEventShareDialogResult; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKEventMessengerShareDialogResult; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKEventAppInviteShareDialogResult; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKEventShareDialogShow; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKEventMessengerShareDialogShow; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKEventAppInviteShareDialogShow; FBSDK_EXTERN NSString *const FBSDKAppEventParameterDialogMode; FBSDK_EXTERN NSString *const FBSDKAppEventParameterDialogShareContentType; // Internally known event parameter values FBSDK_EXTERN NSString *const FBSDKAppEventsDialogOutcomeValue_Completed; FBSDK_EXTERN NSString *const FBSDKAppEventsDialogOutcomeValue_Cancelled; FBSDK_EXTERN NSString *const FBSDKAppEventsDialogOutcomeValue_Failed; FBSDK_EXTERN NSString *const FBSDKAppEventsDialogShareContentTypeOpenGraph; FBSDK_EXTERN NSString *const FBSDKAppEventsDialogShareContentTypeStatus; FBSDK_EXTERN NSString *const FBSDKAppEventsDialogShareContentTypePhoto; FBSDK_EXTERN NSString *const FBSDKAppEventsDialogShareContentTypeVideo; FBSDK_EXTERN NSString *const FBSDKAppEventsDialogShareContentTypeUnknown; FBSDK_EXTERN NSString *const FBSDKAppEventsDialogShareModeAutomatic; FBSDK_EXTERN NSString *const FBSDKAppEventsDialogShareModeBrowser; FBSDK_EXTERN NSString *const FBSDKAppEventsDialogShareModeNative; FBSDK_EXTERN NSString *const FBSDKAppEventsDialogShareModeShareSheet; FBSDK_EXTERN NSString *const FBSDKAppEventsDialogShareModeWeb; FBSDK_EXTERN NSString *const FBSDKAppEventsDialogShareModeFeedBrowser; FBSDK_EXTERN NSString *const FBSDKAppEventsDialogShareModeFeedWeb; FBSDK_EXTERN NSString *const FBSDKAppEventsDialogShareModeUnknown; FBSDK_EXTERN NSString *const FBSDKAppEventsNativeLoginDialogStartTime; FBSDK_EXTERN NSString *const FBSDKAppEventsNativeLoginDialogEndTime; FBSDK_EXTERN NSString *const FBSDKAppEventsWebLoginE2E; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKLikeButtonImpression; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKLoginButtonImpression; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKSendButtonImpression; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKShareButtonImpression; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKLikeButtonDidTap; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKLoginButtonDidTap; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKSendButtonDidTap; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKShareButtonDidTap; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKLikeControlDidDisable; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKLikeControlDidLike; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKLikeControlDidPresentDialog; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKLikeControlDidTap; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKLikeControlDidUnlike; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKLikeControlError; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKLikeControlImpression; FBSDK_EXTERN NSString *const FBSDKAppEventNameFBSDKLikeControlNetworkUnavailable; FBSDK_EXTERN NSString *const FBSDKAppEventParameterDialogErrorMessage; FBSDK_EXTERN NSString *const FBSDKAppEventParameterLogTime; @interface FBSDKAppEvents (Internal) + (void)logImplicitEvent:(NSString *)eventName valueToSum:(NSNumber *)valueToSum parameters:(NSDictionary *)parameters accessToken:(FBSDKAccessToken *)accessToken; + (FBSDKAppEvents *)singleton; - (void)flushForReason:(FBSDKAppEventsFlushReason)flushReason; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsDeviceInfo.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @interface FBSDKAppEventsDeviceInfo : NSObject + (void)extendDictionaryWithDeviceInfo:(NSMutableDictionary *)dictionary; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsDeviceInfo.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAppEventsDeviceInfo.h" #import #import #if !TARGET_OS_TV #import #import #endif #import #import #import "FBSDKAppEvents+Internal.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKInternalUtility.h" #import "FBSDKUtility.h" #define FB_ARRAY_COUNT(x) sizeof(x) / sizeof(x[0]) static const u_int FB_GROUP1_RECHECK_DURATION = 30 * 60; // seconds // Apple reports storage in binary gigabytes (1024^3) in their About menus, etc. static const u_int FB_GIGABYTE = 1024 * 1024 * 1024; // bytes @implementation FBSDKAppEventsDeviceInfo { // Ephemeral data, may change during the lifetime of an app. We collect them in different // 'group' frequencies - group1 may gets collected once every 30 minutes. // group1 NSString *_carrierName; NSString *_timeZoneAbbrev; unsigned long long _remainingDiskSpaceGB; NSString *_timeZoneName; // Persistent data, but we maintain it to make rebuilding the device info as fast as possible. NSString *_bundleIdentifier; NSString *_longVersion; NSString *_shortVersion; NSString *_sysVersion; NSString *_machine; NSString *_language; unsigned long long _totalDiskSpaceGB; unsigned long long _coreCount; CGFloat _width; CGFloat _height; CGFloat _density; // Other state long _lastGroup1CheckTime; BOOL _isEncodingDirty; NSString *_encodedDeviceInfo; } #pragma mark - Public Methods + (void)extendDictionaryWithDeviceInfo:(NSMutableDictionary *)dictionary { dictionary[@"extinfo"] = [[self sharedDeviceInfo] encodedDeviceInfo]; } #pragma mark - Internal Methods + (void)initialize { if (self == [FBSDKAppEventsDeviceInfo class]) { [[self sharedDeviceInfo] _collectPersistentData]; } } + (instancetype)sharedDeviceInfo { static FBSDKAppEventsDeviceInfo *_sharedDeviceInfo = nil; if (_sharedDeviceInfo == nil) { _sharedDeviceInfo = [[FBSDKAppEventsDeviceInfo alloc] init]; } return _sharedDeviceInfo; } - (instancetype)init { if ((self = [super init])) { _isEncodingDirty = YES; } return self; } - (NSString *)encodedDeviceInfo { @synchronized (self) { BOOL isGroup1Expired = [self _isGroup1Expired]; BOOL isEncodingExpired = isGroup1Expired; // Can || other groups in if we add them // As long as group1 hasn't expired, we can just return the last generated value if (_encodedDeviceInfo && !isEncodingExpired) { return _encodedDeviceInfo; } if (isGroup1Expired) { [self _collectGroup1Data]; } if (_isEncodingDirty) { self.encodedDeviceInfo = [self _generateEncoding]; _isEncodingDirty = NO; } return _encodedDeviceInfo; } } - (void)setEncodedDeviceInfo:(NSString *)encodedDeviceInfo { @synchronized (self) { if (![_encodedDeviceInfo isEqualToString:encodedDeviceInfo]) { _encodedDeviceInfo = [encodedDeviceInfo copy]; } } } // This data need only be collected once. - (void)_collectPersistentData { // Bundle stuff NSBundle *mainBundle = [NSBundle mainBundle]; _bundleIdentifier = mainBundle.bundleIdentifier; _longVersion = [mainBundle objectForInfoDictionaryKey:@"CFBundleVersion"]; _shortVersion = [mainBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; // Locale stuff _language = [[NSLocale currentLocale] localeIdentifier]; // Device stuff UIDevice *device = [UIDevice currentDevice]; _sysVersion = device.systemVersion; _coreCount = [FBSDKAppEventsDeviceInfo _coreCount]; UIScreen *sc = [UIScreen mainScreen]; CGRect sr = sc.bounds; _width = sr.size.width; _height = sr.size.height; _density = sc.scale; struct utsname systemInfo; uname(&systemInfo); _machine = @(systemInfo.machine); // Disk space stuff float totalDiskSpace = [[FBSDKAppEventsDeviceInfo _getTotalDiskSpace] floatValue]; _totalDiskSpaceGB = (unsigned long long)round(totalDiskSpace / FB_GIGABYTE); } - (BOOL)_isGroup1Expired { return ([FBSDKAppEventsUtility unixTimeNow] - _lastGroup1CheckTime) > FB_GROUP1_RECHECK_DURATION; } // This data is collected only once every GROUP1_RECHECK_DURATION. - (void)_collectGroup1Data { // Carrier NSString *newCarrierName = [FBSDKAppEventsDeviceInfo _getCarrier]; if (![newCarrierName isEqualToString:_carrierName]) { _carrierName = newCarrierName; _isEncodingDirty = YES; } // Time zone NSTimeZone *timeZone = [NSTimeZone systemTimeZone]; NSString *timeZoneName = timeZone.name; if (![timeZoneName isEqualToString:_timeZoneName]) { _timeZoneName = timeZoneName; _timeZoneAbbrev = timeZone.abbreviation; _isEncodingDirty = YES; } // Remaining disk space float remainingDiskSpace = [[FBSDKAppEventsDeviceInfo _getRemainingDiskSpace] floatValue]; unsigned long long newRemainingDiskSpaceGB = (unsigned long long)round(remainingDiskSpace / FB_GIGABYTE); if (_remainingDiskSpaceGB != newRemainingDiskSpaceGB) { _remainingDiskSpaceGB = newRemainingDiskSpaceGB; _isEncodingDirty = YES; } _lastGroup1CheckTime = [FBSDKAppEventsUtility unixTimeNow]; } - (NSString *)_generateEncoding { // Keep a bit of precision on density as it's the most likely to become non-integer. NSString *densityString = _density ? [NSString stringWithFormat:@"%.02f", _density] : @""; NSArray *arr = @[ @"i2", // version - starts with 'i' for iOS, we'll use 'a' for Android _bundleIdentifier ?: @"", _longVersion ?: @"", _shortVersion ?: @"", _sysVersion ?: @"", _machine ?: @"", _language ?: @"", _timeZoneAbbrev ?: @"", _carrierName ?: @"", _width ? @((unsigned long)_width) : @"", _height ? @((unsigned long)_height) : @"", densityString, @(_coreCount) ?: @"", @(_totalDiskSpaceGB) ?: @"", @(_remainingDiskSpaceGB) ?: @"", _timeZoneName ?: @"" ]; return [FBSDKInternalUtility JSONStringForObject:arr error:NULL invalidObjectHandler:NULL]; } #pragma mark - Helper Methods + (NSNumber *)_getTotalDiskSpace { NSDictionary *attrs = [[[NSFileManager alloc] init] attributesOfFileSystemForPath:NSHomeDirectory() error:nil]; return [attrs objectForKey:NSFileSystemSize]; } + (NSNumber *)_getRemainingDiskSpace { NSDictionary *attrs = [[[NSFileManager alloc] init] attributesOfFileSystemForPath:NSHomeDirectory() error:nil]; return [attrs objectForKey:NSFileSystemFreeSize]; } + (uint)_coreCount { return [FBSDKAppEventsDeviceInfo _readSysCtlUInt:CTL_HW type:HW_AVAILCPU]; } + (uint)_readSysCtlUInt:(int)ctl type:(int)type { int mib[2] = {ctl, type}; uint value; size_t size = sizeof value; if (0 != sysctl(mib, FB_ARRAY_COUNT(mib), &value, &size, NULL, 0)) { return 0; } return value; } + (NSString *)_getCarrier { #if TARGET_OS_TV return @"NoCarrier"; #else // Dynamically load class for this so calling app doesn't need to link framework in. CTTelephonyNetworkInfo *networkInfo = [[fbsdkdfl_CTTelephonyNetworkInfoClass() alloc] init]; CTCarrier *carrier = [networkInfo subscriberCellularProvider]; return [carrier carrierName] ?: @"NoCarrier"; #endif } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsState.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import // this type is not thread safe. @interface FBSDKAppEventsState : NSObject @property (readonly, copy) NSArray *events; @property (readonly, assign) NSUInteger numSkipped; @property (readonly, copy) NSString *tokenString; @property (readonly, copy) NSString *appID; - (instancetype)initWithToken:(NSString *)tokenString appID:(NSString *)appID NS_DESIGNATED_INITIALIZER; - (void)addEvent:(NSDictionary *)eventDictionary isImplicit:(BOOL)isImplicit; - (void)addEventsFromAppEventState:(FBSDKAppEventsState *)appEventsState; - (BOOL)areAllEventsImplicit; - (BOOL)isCompatibleWithAppEventsState:(FBSDKAppEventsState *)appEventsState; - (BOOL)isCompatibleWithTokenString:(NSString *)tokenString appID:(NSString *)appID; - (NSString *)JSONStringForEvents:(BOOL)includeImplicitEvents; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsState.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAppEventsState.h" #import "FBSDKInternalUtility.h" #import "FBSDKMacros.h" #define FBSDK_APPEVENTSTATE_ISIMPLICIT_KEY @"isImplicit" #define FBSDK_APPEVENTSSTATE_MAX_EVENTS 1000 #define FBSDK_APPEVENTSSTATE_APPID_KEY @"appID" #define FBSDK_APPEVENTSSTATE_EVENTS_KEY @"events" #define FBSDK_APPEVENTSSTATE_NUMSKIPPED_KEY @"numSkipped" #define FBSDK_APPEVENTSSTATE_TOKENSTRING_KEY @"tokenString" @implementation FBSDKAppEventsState { NSMutableArray *_mutableEvents; } - (instancetype)init { FBSDK_NOT_DESIGNATED_INITIALIZER(initWithToken:appID:); return [self initWithToken:nil appID:nil]; } - (instancetype)initWithToken:(NSString *)tokenString appID:(NSString *)appID { if ((self = [super init])) { _tokenString = [tokenString copy]; _appID = [appID copy]; _mutableEvents = [NSMutableArray array]; } return self; } - (instancetype)copyWithZone:(NSZone *)zone { FBSDKAppEventsState *copy = [[FBSDKAppEventsState allocWithZone:zone] initWithToken:_tokenString appID:_appID]; if (copy) { [copy->_mutableEvents addObjectsFromArray:_mutableEvents]; copy->_numSkipped = _numSkipped; } return copy; } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { NSString *appID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_APPEVENTSSTATE_APPID_KEY]; NSString *tokenString = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_APPEVENTSSTATE_TOKENSTRING_KEY]; NSArray *events = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_APPEVENTSSTATE_EVENTS_KEY]; NSUInteger numSkipped = [[decoder decodeObjectOfClass:[NSNumber class] forKey:FBSDK_APPEVENTSSTATE_NUMSKIPPED_KEY] unsignedIntegerValue]; if ((self = [self initWithToken:tokenString appID:appID])) { _mutableEvents = [NSMutableArray arrayWithArray:events]; _numSkipped = numSkipped; } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_appID forKey:FBSDK_APPEVENTSSTATE_APPID_KEY]; [encoder encodeObject:_tokenString forKey:FBSDK_APPEVENTSSTATE_TOKENSTRING_KEY]; [encoder encodeObject:@(_numSkipped) forKey:FBSDK_APPEVENTSSTATE_NUMSKIPPED_KEY]; [encoder encodeObject:_mutableEvents forKey:FBSDK_APPEVENTSSTATE_EVENTS_KEY]; } #pragma mark - Implementation - (NSArray *)events { return [_mutableEvents copy]; } - (void)addEventsFromAppEventState:(FBSDKAppEventsState *)appEventsState { NSArray *toAdd = appEventsState->_mutableEvents; NSInteger excess = _mutableEvents.count + toAdd.count - FBSDK_APPEVENTSSTATE_MAX_EVENTS; if (excess > 0) { NSInteger range = FBSDK_APPEVENTSSTATE_MAX_EVENTS - _mutableEvents.count; toAdd = [toAdd subarrayWithRange:NSMakeRange(0, range)]; _numSkipped += excess; } [_mutableEvents addObjectsFromArray:toAdd]; } - (void)addEvent:(NSDictionary *)eventDictionary isImplicit:(BOOL)isImplicit { if (_mutableEvents.count >= FBSDK_APPEVENTSSTATE_MAX_EVENTS) { _numSkipped++; } else { [_mutableEvents addObject:@{ @"event" : eventDictionary, FBSDK_APPEVENTSTATE_ISIMPLICIT_KEY : @(isImplicit) }]; } } - (BOOL)areAllEventsImplicit { for (NSDictionary *event in _mutableEvents) { if (![[event valueForKey:FBSDK_APPEVENTSTATE_ISIMPLICIT_KEY] boolValue]) { return NO; } } return YES; } - (BOOL)isCompatibleWithAppEventsState:(FBSDKAppEventsState *)appEventsState { return ([self isCompatibleWithTokenString:appEventsState.tokenString appID:appEventsState.appID]); } - (BOOL)isCompatibleWithTokenString:(NSString *)tokenString appID:(NSString *)appID { // token strings can be nil (e.g., no user token) but appIDs should not. BOOL tokenCompatible = ([self.tokenString isEqualToString:tokenString] || (self.tokenString == nil && tokenString == nil)); return (tokenCompatible && [self.appID isEqualToString:appID]); } - (NSString *)JSONStringForEvents:(BOOL)includeImplicitEvents { NSMutableArray *events = [[NSMutableArray alloc] initWithCapacity:_mutableEvents.count]; for (NSDictionary *eventAndImplicitFlag in _mutableEvents) { if (!includeImplicitEvents && [eventAndImplicitFlag[FBSDK_APPEVENTSTATE_ISIMPLICIT_KEY] boolValue]) { continue; } [events addObject:eventAndImplicitFlag[@"event"]]; } return [FBSDKInternalUtility JSONStringForObject:events error:NULL invalidObjectHandler:NULL]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsStateManager.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @class FBSDKAppEventsState; @interface FBSDKAppEventsStateManager : NSObject + (void)clearPersistedAppEventsStates; // reads all saved event states, appends the param, and writes them all. + (void)persistAppEventsData:(FBSDKAppEventsState *)appEventsState; // returns the array of saved app event states and deletes them. + (NSArray *)retrievePersistedAppEventsStates; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsStateManager.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAppEventsStateManager.h" #import #import "FBSDKAppEventsState.h" #import "FBSDKAppEventsUtility.h" #import "FBSDKLogger.h" #import "FBSDKSettings.h" // A quick optimization to allow returning empty array if we know there are no persisted events. static BOOL g_canSkipDiskCheck = NO; @implementation FBSDKAppEventsStateManager + (void)clearPersistedAppEventsStates { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAppEvents logEntry:@"FBSDKAppEvents Persist: Clearing"]; [[NSFileManager defaultManager] removeItemAtPath:[[self class] filePath] error:NULL]; g_canSkipDiskCheck = YES; } + (void)persistAppEventsData:(FBSDKAppEventsState *)appEventsState { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAppEvents formatString:@"FBSDKAppEvents Persist: Writing %lu events", (unsigned long)appEventsState.events.count]; if (!appEventsState.events.count) { return; } NSMutableArray *existingEvents = [NSMutableArray arrayWithArray:[[self class] retrievePersistedAppEventsStates]]; [existingEvents addObject:appEventsState]; [NSKeyedArchiver archiveRootObject:existingEvents toFile:[[self class] filePath]]; g_canSkipDiskCheck = NO; } + (NSArray *)retrievePersistedAppEventsStates { NSMutableArray *eventsStates = [NSMutableArray array]; if (!g_canSkipDiskCheck) { [eventsStates addObjectsFromArray:[NSKeyedUnarchiver unarchiveObjectWithFile:[[self class] filePath]]]; [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAppEvents formatString:@"FBSDKAppEvents Persist: Read %lu event states. First state has %lu events", (unsigned long)eventsStates.count, (unsigned long)(eventsStates.count > 0 ? ((FBSDKAppEventsState *)eventsStates[0]).events.count : 0)]; [[self class] clearPersistedAppEventsStates]; } return eventsStates; } #pragma mark - Private Helpers + (NSString *)filePath { return [FBSDKAppEventsUtility persistenceFilePath:@"com-facebook-sdk-AppEventsPersistedEvents.json"]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsUtility.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @class FBSDKAccessToken; typedef NS_ENUM(NSUInteger, FBSDKAdvertisingTrackingStatus) { FBSDKAdvertisingTrackingAllowed, FBSDKAdvertisingTrackingDisallowed, FBSDKAdvertisingTrackingUnspecified }; typedef NS_ENUM(NSUInteger, FBSDKAppEventsFlushReason) { FBSDKAppEventsFlushReasonExplicit, FBSDKAppEventsFlushReasonTimer, FBSDKAppEventsFlushReasonSessionChange, FBSDKAppEventsFlushReasonPersistedEvents, FBSDKAppEventsFlushReasonEventThreshold, FBSDKAppEventsFlushReasonEagerlyFlushingEvent }; @interface FBSDKAppEventsUtility : NSObject + (NSMutableDictionary *)activityParametersDictionaryForEvent:(NSString *)eventCategory implicitEventsOnly:(BOOL)implicitEventsOnly shouldAccessAdvertisingID:(BOOL)shouldAccessAdvertisingID; + (NSString *)advertiserID; + (FBSDKAdvertisingTrackingStatus)advertisingTrackingStatus; + (NSString *)attributionID; + (void)ensureOnMainThread:(NSString *)methodName className:(NSString *)className; + (NSString *)flushReasonToString:(FBSDKAppEventsFlushReason)flushReason; + (void)logAndNotify:(NSString *)msg allowLogAsDeveloperError:(BOOL)allowLogAsDeveloperError; + (void)logAndNotify:(NSString *)msg; + (NSString *)persistenceFilePath:(NSString *)filename; + (NSString *)tokenStringToUseFor:(FBSDKAccessToken *)token; + (long)unixTimeNow; + (BOOL)validateIdentifier:(NSString *)identifier; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsUtility.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAppEventsUtility.h" #import #import "FBSDKAccessToken.h" #import "FBSDKAppEvents.h" #import "FBSDKAppEventsDeviceInfo.h" #import "FBSDKConstants.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKError.h" #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKMacros.h" #import "FBSDKSettings.h" #import "FBSDKTimeSpentData.h" #define FBSDK_APPEVENTSUTILITY_ANONYMOUSIDFILENAME @"com-facebook-sdk-PersistedAnonymousID.json" #define FBSDK_APPEVENTSUTILITY_ANONYMOUSID_KEY @"anon_id" #define FBSDK_APPEVENTSUTILITY_MAX_IDENTIFIER_LENGTH 40 @implementation FBSDKAppEventsUtility + (NSMutableDictionary *)activityParametersDictionaryForEvent:(NSString *)eventCategory implicitEventsOnly:(BOOL)implicitEventsOnly shouldAccessAdvertisingID:(BOOL)shouldAccessAdvertisingID { NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; parameters[@"event"] = eventCategory; NSString *attributionID = [[self class] attributionID]; // Only present on iOS 6 and below. [FBSDKInternalUtility dictionary:parameters setObject:attributionID forKey:@"attribution"]; if (!implicitEventsOnly && shouldAccessAdvertisingID) { NSString *advertiserID = [[self class] advertiserID]; [FBSDKInternalUtility dictionary:parameters setObject:advertiserID forKey:@"advertiser_id"]; } parameters[FBSDK_APPEVENTSUTILITY_ANONYMOUSID_KEY] = [self anonymousID]; FBSDKAdvertisingTrackingStatus advertisingTrackingStatus = [[self class] advertisingTrackingStatus]; if (advertisingTrackingStatus != FBSDKAdvertisingTrackingUnspecified) { BOOL allowed = (advertisingTrackingStatus == FBSDKAdvertisingTrackingAllowed); parameters[@"advertiser_tracking_enabled"] = [@(allowed) stringValue]; } parameters[@"application_tracking_enabled"] = [@(!FBSDKSettings.limitEventAndDataUsage) stringValue]; [FBSDKAppEventsDeviceInfo extendDictionaryWithDeviceInfo:parameters]; static dispatch_once_t fetchBundleOnce; static NSMutableArray *urlSchemes; dispatch_once(&fetchBundleOnce, ^{ NSBundle *mainBundle = [NSBundle mainBundle]; urlSchemes = [[NSMutableArray alloc] init]; for (NSDictionary *fields in [mainBundle objectForInfoDictionaryKey:@"CFBundleURLTypes"]) { NSArray *schemesForType = [fields objectForKey:@"CFBundleURLSchemes"]; if (schemesForType) { [urlSchemes addObjectsFromArray:schemesForType]; } } }); if (urlSchemes.count > 0) { [parameters setObject:[FBSDKInternalUtility JSONStringForObject:urlSchemes error:NULL invalidObjectHandler:NULL] forKey:@"url_schemes"]; } return parameters; } + (NSString *)advertiserID { NSString *result = nil; Class ASIdentifierManagerClass = fbsdkdfl_ASIdentifierManagerClass(); if ([ASIdentifierManagerClass class]) { ASIdentifierManager *manager = [ASIdentifierManagerClass sharedManager]; result = [[manager advertisingIdentifier] UUIDString]; } return result; } + (FBSDKAdvertisingTrackingStatus)advertisingTrackingStatus { static dispatch_once_t fetchAdvertisingTrackingStatusOnce; static FBSDKAdvertisingTrackingStatus status; dispatch_once(&fetchAdvertisingTrackingStatusOnce, ^{ status = FBSDKAdvertisingTrackingUnspecified; Class ASIdentifierManagerClass = fbsdkdfl_ASIdentifierManagerClass(); if ([ASIdentifierManagerClass class]) { ASIdentifierManager *manager = [ASIdentifierManagerClass sharedManager]; if (manager) { status = [manager isAdvertisingTrackingEnabled] ? FBSDKAdvertisingTrackingAllowed : FBSDKAdvertisingTrackingDisallowed; } } }); return status; } + (NSString *)anonymousID { // Grab previously written anonymous ID and, if none have been generated, create and // persist a new one which will remain associated with this app. NSString *result = [[self class] retrievePersistedAnonymousID]; if (!result) { // Generate a new anonymous ID. Create as a UUID, but then prepend the fairly // arbitrary 'XZ' to the front so it's easily distinguishable from IDFA's which // will only contain hex. result = [NSString stringWithFormat:@"XZ%@", [[NSUUID UUID] UUIDString]]; [self persistAnonymousID:result]; } return result; } + (NSString *)attributionID { #if TARGET_OS_TV return nil; #else return [[UIPasteboard pasteboardWithName:@"fb_app_attribution" create:NO] string]; #endif } // for tests only. + (void)clearLibraryFiles { [[NSFileManager defaultManager] removeItemAtPath:[[self class] persistenceFilePath:FBSDK_APPEVENTSUTILITY_ANONYMOUSIDFILENAME] error:NULL]; [[NSFileManager defaultManager] removeItemAtPath:[[self class] persistenceFilePath:FBSDKTimeSpentFilename] error:NULL]; } + (void)ensureOnMainThread:(NSString *)methodName className:(NSString *)className { FBSDKConditionalLog([NSThread isMainThread], FBSDKLoggingBehaviorDeveloperErrors, @"*** <%@, %@> is not called on the main thread. This can lead to errors.", methodName, className); } + (NSString *)flushReasonToString:(FBSDKAppEventsFlushReason)flushReason { NSString *result = @"Unknown"; switch (flushReason) { case FBSDKAppEventsFlushReasonExplicit: result = @"Explicit"; break; case FBSDKAppEventsFlushReasonTimer: result = @"Timer"; break; case FBSDKAppEventsFlushReasonSessionChange: result = @"SessionChange"; break; case FBSDKAppEventsFlushReasonPersistedEvents: result = @"PersistedEvents"; break; case FBSDKAppEventsFlushReasonEventThreshold: result = @"EventCountThreshold"; break; case FBSDKAppEventsFlushReasonEagerlyFlushingEvent: result = @"EagerlyFlushingEvent"; break; } return result; } + (void)logAndNotify:(NSString *)msg { [[self class] logAndNotify:msg allowLogAsDeveloperError:YES]; } + (void)logAndNotify:(NSString *)msg allowLogAsDeveloperError:(BOOL)allowLogAsDeveloperError { NSString *behaviorToLog = FBSDKLoggingBehaviorAppEvents; if (allowLogAsDeveloperError) { if ([[FBSDKSettings loggingBehavior] containsObject:FBSDKLoggingBehaviorDeveloperErrors]) { // Rather than log twice, prefer 'DeveloperErrors' if it's set over AppEvents. behaviorToLog = FBSDKLoggingBehaviorDeveloperErrors; } } [FBSDKLogger singleShotLogEntry:behaviorToLog logEntry:msg]; NSError *error = [FBSDKError errorWithCode:FBSDKAppEventsFlushErrorCode message:msg]; [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKAppEventsLoggingResultNotification object:error]; } + (BOOL)matchString:(NSString *)string firstCharacterSet:(NSCharacterSet *)firstCharacterSet restOfStringCharacterSet:(NSCharacterSet *)restOfStringCharacterSet { if (string.length == 0) { return NO; } for (NSUInteger i = 0; i < string.length; i++) { const unichar c = [string characterAtIndex:i]; if (i == 0) { if (![firstCharacterSet characterIsMember:c]) { return NO; } } else { if (![restOfStringCharacterSet characterIsMember:c]) { return NO; } } } return YES; } + (BOOL)regexValidateIdentifier:(NSString *)identifier { static NSCharacterSet *firstCharacterSet; static NSCharacterSet *restOfStringCharacterSet; static dispatch_once_t onceToken; static NSMutableSet *cachedIdentifiers; dispatch_once(&onceToken, ^{ NSMutableCharacterSet *mutableSet = [NSMutableCharacterSet alphanumericCharacterSet]; [mutableSet addCharactersInString:@"_"]; firstCharacterSet = [mutableSet copy]; [mutableSet addCharactersInString:@"- "]; restOfStringCharacterSet = [mutableSet copy]; cachedIdentifiers = [[NSMutableSet alloc] init]; }); @synchronized(self) { if (![cachedIdentifiers containsObject:identifier]) { if ([self matchString:identifier firstCharacterSet:firstCharacterSet restOfStringCharacterSet:restOfStringCharacterSet]) { [cachedIdentifiers addObject:identifier]; } else { return NO; } } } return YES; } + (BOOL)validateIdentifier:(NSString *)identifier { if (identifier == nil || identifier.length == 0 || identifier.length > FBSDK_APPEVENTSUTILITY_MAX_IDENTIFIER_LENGTH || ![[self class] regexValidateIdentifier:identifier]) { [[self class] logAndNotify:[NSString stringWithFormat:@"Invalid identifier: '%@'. Must be between 1 and %d characters, and must be contain only alphanumerics, _, - or spaces, starting with alphanumeric or _.", identifier, FBSDK_APPEVENTSUTILITY_MAX_IDENTIFIER_LENGTH]]; return NO; } return YES; } + (void)persistAnonymousID:(NSString *)anonymousID { [[self class] ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass(self)]; NSDictionary *data = @{ FBSDK_APPEVENTSUTILITY_ANONYMOUSID_KEY : anonymousID }; NSString *content = [FBSDKInternalUtility JSONStringForObject:data error:NULL invalidObjectHandler:NULL]; [content writeToFile:[[self class] persistenceFilePath:FBSDK_APPEVENTSUTILITY_ANONYMOUSIDFILENAME] atomically:YES encoding:NSASCIIStringEncoding error:nil]; } + (NSString *)persistenceFilePath:(NSString *)filename { NSSearchPathDirectory directory = NSLibraryDirectory; NSArray *paths = NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES); NSString *docDirectory = [paths objectAtIndex:0]; return [docDirectory stringByAppendingPathComponent:filename]; } + (NSString *)retrievePersistedAnonymousID { [[self class] ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass(self)]; NSString *file = [[self class] persistenceFilePath:FBSDK_APPEVENTSUTILITY_ANONYMOUSIDFILENAME]; NSString *content = [[NSString alloc] initWithContentsOfFile:file encoding:NSASCIIStringEncoding error:nil]; NSDictionary *results = [FBSDKInternalUtility objectForJSONString:content error:NULL]; return [results objectForKey:FBSDK_APPEVENTSUTILITY_ANONYMOUSID_KEY]; } // Given a candidate token (which may be nil), find the real token to string to use. // Precedence: 1) provided token, 2) current token, 3) app | client token, 4) fully anonymous session. + (NSString *)tokenStringToUseFor:(FBSDKAccessToken *)token { if (!token) { token = [FBSDKAccessToken currentAccessToken]; } NSString *appID = [FBSDKAppEvents loggingOverrideAppID] ?: token.appID ?: [FBSDKSettings appID]; NSString *tokenString = token.tokenString; if (!tokenString || ![appID isEqualToString:token.appID]) { // If there's an logging override app id present, then we don't want to use the client token since the client token // is intended to match up with the primary app id (and AppEvents doesn't require a client token). NSString *clientTokenString = [FBSDKSettings clientToken]; if (clientTokenString && appID && [appID isEqualToString:token.appID]){ tokenString = [NSString stringWithFormat:@"%@|%@", appID, clientTokenString]; } else if (appID) { tokenString = nil; } } return tokenString; } + (long)unixTimeNow { return (long)round([[NSDate date] timeIntervalSince1970]); } - (instancetype)init { FBSDK_NO_DESIGNATED_INITIALIZER(); return nil; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKPaymentObserver.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import // Class to encapsulate implicit logging of purchase events @interface FBSDKPaymentObserver : NSObject + (void)startObservingTransactions; + (void)stopObservingTransactions; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKPaymentObserver.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKPaymentObserver.h" #import #import "FBSDKAppEvents+Internal.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKLogger.h" #import "FBSDKSettings.h" static NSString *const FBSDKAppEventParameterImplicitlyLoggedPurchase = @"_implicitlyLoggedPurchaseEvent"; static NSString *const FBSDKAppEventNamePurchaseFailed = @"fb_mobile_purchase_failed"; static NSString *const FBSDKAppEventParameterNameProductTitle = @"fb_content_title"; static NSString *const FBSDKAppEventParameterNameTransactionID = @"fb_transaction_id"; static int const FBSDKMaxParameterValueLength = 100; static NSMutableArray *g_pendingRequestors; @interface FBSDKPaymentProductRequestor : NSObject @property (nonatomic, retain) SKPaymentTransaction *transaction; - (instancetype)initWithTransaction:(SKPaymentTransaction*)transaction; - (void)resolveProducts; @end @interface FBSDKPaymentObserver() @end @implementation FBSDKPaymentObserver { BOOL _observingTransactions; } + (void)startObservingTransactions { [[self singleton] startObservingTransactions]; } + (void)stopObservingTransactions { [[self singleton] stopObservingTransactions]; } // // Internal methods // + (FBSDKPaymentObserver *)singleton { static dispatch_once_t pred; static FBSDKPaymentObserver *shared = nil; dispatch_once(&pred, ^{ shared = [[FBSDKPaymentObserver alloc] init]; }); return shared; } - (instancetype) init { self = [super init]; if (self) { _observingTransactions = NO; } return self; } - (void)startObservingTransactions { @synchronized (self) { if (!_observingTransactions) { [(SKPaymentQueue *)[fbsdkdfl_SKPaymentQueueClass() defaultQueue] addTransactionObserver:self]; _observingTransactions = YES; } } } - (void)stopObservingTransactions { @synchronized (self) { if (_observingTransactions) { [(SKPaymentQueue *)[fbsdkdfl_SKPaymentQueueClass() defaultQueue] removeTransactionObserver:self]; _observingTransactions = NO; } } } - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { for (SKPaymentTransaction *transaction in transactions) { switch (transaction.transactionState) { case SKPaymentTransactionStatePurchasing: case SKPaymentTransactionStatePurchased: case SKPaymentTransactionStateFailed: [self handleTransaction:transaction]; break; case SKPaymentTransactionStateDeferred: case SKPaymentTransactionStateRestored: break; } } } - (void)handleTransaction:(SKPaymentTransaction *)transaction { FBSDKPaymentProductRequestor *productRequest = [[FBSDKPaymentProductRequestor alloc] initWithTransaction:transaction]; [productRequest resolveProducts]; } @end @interface FBSDKPaymentProductRequestor() @property (nonatomic, retain) SKProductsRequest *productRequest; @end @implementation FBSDKPaymentProductRequestor + (void)initialize { if ([self class] == [FBSDKPaymentProductRequestor class]) { g_pendingRequestors = [[NSMutableArray alloc] init]; } } - (instancetype)initWithTransaction:(SKPaymentTransaction*)transaction { self = [super init]; if (self) { _transaction = transaction; } return self; } - (void)setProductRequest:(SKProductsRequest *)productRequest { if (productRequest != _productRequest) { if (_productRequest) { _productRequest.delegate = nil; } _productRequest = productRequest; } } - (void)resolveProducts { NSString *productId = self.transaction.payment.productIdentifier; NSSet *productIdentifiers = [NSSet setWithObjects:productId, nil]; self.productRequest = [[fbsdkdfl_SKProductsRequestClass() alloc] initWithProductIdentifiers:productIdentifiers]; self.productRequest.delegate = self; @synchronized(g_pendingRequestors) { [g_pendingRequestors addObject:self]; } [self.productRequest start]; } - (NSString *)getTruncatedString:(NSString *)inputString { if (!inputString) { return @""; } return [inputString length] <= FBSDKMaxParameterValueLength ? inputString : [inputString substringToIndex:FBSDKMaxParameterValueLength]; } - (void)logTransactionEvent:(SKProduct *)product { NSString *eventName = nil; NSString *transactionID = nil; switch (self.transaction.transactionState) { case SKPaymentTransactionStatePurchasing: eventName = FBSDKAppEventNameInitiatedCheckout; break; case SKPaymentTransactionStatePurchased: eventName = FBSDKAppEventNamePurchased; transactionID = self.transaction.transactionIdentifier; break; case SKPaymentTransactionStateFailed: eventName = FBSDKAppEventNamePurchaseFailed; break; case SKPaymentTransactionStateDeferred: case SKPaymentTransactionStateRestored: return; } if (!eventName) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAppEvents formatString:@"FBSDKPaymentObserver logTransactionEvent: event name cannot be nil"]; return; } SKPayment *payment = self.transaction.payment; NSMutableDictionary *eventParameters = [NSMutableDictionary dictionaryWithDictionary: @{ FBSDKAppEventParameterNameContentID: payment.productIdentifier ?: @"", FBSDKAppEventParameterNameNumItems: @(payment.quantity), }]; double totalAmount = 0; if (product) { totalAmount = payment.quantity * product.price.doubleValue; [eventParameters addEntriesFromDictionary: @{ FBSDKAppEventParameterNameCurrency: [product.priceLocale objectForKey:NSLocaleCurrencyCode], FBSDKAppEventParameterNameNumItems: @(payment.quantity), FBSDKAppEventParameterNameProductTitle: [self getTruncatedString:product.localizedTitle], FBSDKAppEventParameterNameDescription: [self getTruncatedString:product.localizedDescription], }]; if (transactionID) { [eventParameters setObject:transactionID forKey:FBSDKAppEventParameterNameTransactionID]; } } [self logImplicitPurchaseEvent:eventName valueToSum:totalAmount parameters:eventParameters]; } - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { NSArray* products = response.products; NSArray* invalidProductIdentifiers = response.invalidProductIdentifiers; if (products.count + invalidProductIdentifiers.count != 1) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAppEvents formatString:@"FBSDKPaymentObserver: Expect to resolve one product per request"]; } SKProduct *product = nil; if (products.count) { product = products[0]; } [self logTransactionEvent:product]; } - (void)requestDidFinish:(SKRequest *)request { [self cleanUp]; } - (void)request:(SKRequest *)request didFailWithError:(NSError *)error { [self logTransactionEvent:nil]; [self cleanUp]; } - (void)cleanUp { @synchronized(g_pendingRequestors) { [g_pendingRequestors removeObject:self]; } } - (void)logImplicitPurchaseEvent:(NSString *)eventName valueToSum:(double)valueToSum parameters:(NSDictionary *)parameters { NSMutableDictionary *eventParameters = [NSMutableDictionary dictionaryWithDictionary:parameters]; [eventParameters setObject:@"1" forKey:FBSDKAppEventParameterImplicitlyLoggedPurchase]; [FBSDKAppEvents logEvent:eventName valueToSum:valueToSum parameters:parameters]; // Unless the behavior is set to only allow explicit flushing, we go ahead and flush, since purchase events // are relatively rare and relatively high value and worth getting across on wire right away. if ([FBSDKAppEvents flushBehavior] != FBSDKAppEventsFlushBehaviorExplicitOnly) { [[FBSDKAppEvents singleton] flushForReason:FBSDKAppEventsFlushReasonEagerlyFlushingEvent]; } } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKTimeSpentData.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import FBSDK_EXTERN NSString *const FBSDKTimeSpentFilename; // Class to encapsulate persisting of time spent data collected by [FBSDKAppEvents activateApp]. The activate app App Event is // logged when restore: is called with sufficient time since the last deactivation. @interface FBSDKTimeSpentData : NSObject + (void)suspend; + (void)restore:(BOOL)calledFromActivateApp; + (void)setSourceApplication:(NSString *)sourceApplication openURL:(NSURL *)url; + (void)setSourceApplication:(NSString *)sourceApplication isFromAppLink:(BOOL)isFromAppLink; + (void)registerAutoResetSourceApplication; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKTimeSpentData.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKTimeSpentData.h" #import "FBSDKAppEvents+Internal.h" #import "FBSDKAppEventsUtility.h" #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKServerConfiguration.h" #import "FBSDKServerConfigurationManager.h" #import "FBSDKSettings.h" // Filename and keys for session length NSString *const FBSDKTimeSpentFilename = @"com-facebook-sdk-AppEventsTimeSpent.json"; static NSString *const FBSDKTimeSpentPersistKeySessionSecondsSpent = @"secondsSpentInCurrentSession"; static NSString *const FBSDKTimeSpentPersistKeySessionNumInterruptions = @"numInterruptions"; static NSString *const FBSDKTimeSpentPersistKeyLastSuspendTime = @"lastSuspendTime"; static NSString *const FBSDKTimeSpentPersistKeySessionID = @"sessionID"; static NSString *const FBSDKAppEventNameActivatedApp = @"fb_mobile_activate_app"; static NSString *const FBSDKAppEventNameDeactivatedApp = @"fb_mobile_deactivate_app"; static NSString *const FBSDKAppEventParameterNameSessionInterruptions = @"fb_mobile_app_interruptions"; static NSString *const FBSDKAppEventParameterNameTimeBetweenSessions = @"fb_mobile_time_between_sessions"; static NSString *const FBSDKAppEventParameterNameSessionID = @"_session_id"; static const int SECS_PER_MIN = 60; static const int SECS_PER_HOUR = 60 * SECS_PER_MIN; static const int SECS_PER_DAY = 24 * SECS_PER_HOUR; static NSString *g_sourceApplication; static BOOL g_isOpenedFromAppLink; // Will be translated and displayed in App Insights. Need to maintain same number and value of quanta on the server. static const long INACTIVE_SECONDS_QUANTA[] = { 5 * SECS_PER_MIN, 15 * SECS_PER_MIN, 30 * SECS_PER_MIN, 1 * SECS_PER_HOUR, 6 * SECS_PER_HOUR, 12 * SECS_PER_HOUR, 1 * SECS_PER_DAY, 2 * SECS_PER_DAY, 3 * SECS_PER_DAY, 7 * SECS_PER_DAY, 14 * SECS_PER_DAY, 21 * SECS_PER_DAY, 28 * SECS_PER_DAY, 60 * SECS_PER_DAY, 90 * SECS_PER_DAY, 120 * SECS_PER_DAY, 150 * SECS_PER_DAY, 180 * SECS_PER_DAY, 365 * SECS_PER_DAY, LONG_MAX, // keep as LONG_MAX to guarantee loop will terminate }; /** * This class encapsulates the notion of an app 'session' - the length of time that the user has * spent in the app that can be considered a single usage of the app. Apps may be frequently interrupted * do to other device activity, like a text message, so this class allows those interruptions to be smoothed * out and the time actually spent in the app excluding this interruption time to be accumulated. Also, * once a certain amount of time has gone by where the app is not in the foreground, we consider the * session to be complete, and a new session beginning. When this occurs, we log an 'activate app' event * with the duration of the previous session as the 'value' of this event, along with the number of * interruptions from that previous session as an event parameter. */ @implementation FBSDKTimeSpentData { BOOL _isCurrentlyLoaded; BOOL _shouldLogActivateEvent; BOOL _shouldLogDeactivateEvent; long _secondsSpentInCurrentSession; long _timeSinceLastSuspend; int _numInterruptionsInCurrentSession; long _lastRestoreTime; long _lastSuspendTime; NSString *_sessionID; } // // Public methods // + (void)suspend { [self.singleton instanceSuspend]; } + (void)restore:(BOOL)calledFromActivateApp { [self.singleton instanceRestore:calledFromActivateApp]; } // // Internal methods // + (FBSDKTimeSpentData *)singleton { static dispatch_once_t pred; static FBSDKTimeSpentData *shared = nil; dispatch_once(&pred, ^{ shared = [[FBSDKTimeSpentData alloc] init]; }); return shared; } // Calculate and persist time spent data for this instance of the app activation. - (void)instanceSuspend { [FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; if (!_isCurrentlyLoaded) { FBSDKConditionalLog(YES, FBSDKLoggingBehaviorInformational, @"[FBSDKTimeSpentData suspend] invoked without corresponding restore"); return; } long now = [FBSDKAppEventsUtility unixTimeNow]; long timeSinceRestore = now - _lastRestoreTime; // Can happen if the clock on the device is changed if (timeSinceRestore < 0) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAppEvents formatString:@"Clock skew detected"]; timeSinceRestore = 0; } _secondsSpentInCurrentSession += timeSinceRestore; NSDictionary *timeSpentData = @{ FBSDKTimeSpentPersistKeySessionSecondsSpent : @(_secondsSpentInCurrentSession), FBSDKTimeSpentPersistKeySessionNumInterruptions : @(_numInterruptionsInCurrentSession), FBSDKTimeSpentPersistKeyLastSuspendTime : @(now), FBSDKTimeSpentPersistKeySessionID : _sessionID, }; NSString *content = [FBSDKInternalUtility JSONStringForObject:timeSpentData error:NULL invalidObjectHandler:NULL]; [content writeToFile:[FBSDKAppEventsUtility persistenceFilePath:FBSDKTimeSpentFilename] atomically:YES encoding:NSASCIIStringEncoding error:nil]; [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAppEvents formatString:@"FBSDKTimeSpentData Persist: %@", content]; _isCurrentlyLoaded = NO; } // Called during activation - either through an explicit 'activateApp' call or implicitly when the app is foregrounded. // In both cases, we restore the persisted event data. In the case of the activateApp, we log an 'app activated' // event if there's been enough time between the last deactivation and now. - (void)instanceRestore:(BOOL)calledFromActivateApp { [FBSDKAppEventsUtility ensureOnMainThread:NSStringFromSelector(_cmd) className:NSStringFromClass([self class])]; // It's possible to call this multiple times during the time the app is in the foreground. If this is the case, // just restore persisted data the first time. if (!_isCurrentlyLoaded) { NSString *content = [[NSString alloc] initWithContentsOfFile:[FBSDKAppEventsUtility persistenceFilePath:FBSDKTimeSpentFilename] usedEncoding:nil error:nil]; [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAppEvents formatString:@"FBSDKTimeSpentData Restore: %@", content]; long now = [FBSDKAppEventsUtility unixTimeNow]; if (!content) { // Nothing persisted, so this is the first launch. _sessionID = [[NSUUID UUID] UUIDString]; _secondsSpentInCurrentSession = 0; _numInterruptionsInCurrentSession = 0; _lastSuspendTime = 0; // We want to log the app activation event on the first launch, but not the deactivate event _shouldLogActivateEvent = YES; _shouldLogDeactivateEvent = NO; } else { NSDictionary *results = [FBSDKInternalUtility objectForJSONString:content error:NULL]; _lastSuspendTime = [[results objectForKey:FBSDKTimeSpentPersistKeyLastSuspendTime] longValue]; _timeSinceLastSuspend = now - _lastSuspendTime; _secondsSpentInCurrentSession = [[results objectForKey:FBSDKTimeSpentPersistKeySessionSecondsSpent] intValue]; _sessionID = results[FBSDKTimeSpentPersistKeySessionID] ? : [[NSUUID UUID] UUIDString]; _numInterruptionsInCurrentSession = [[results objectForKey:FBSDKTimeSpentPersistKeySessionNumInterruptions] intValue]; _shouldLogActivateEvent = (_timeSinceLastSuspend > [FBSDKServerConfigurationManager cachedServerConfiguration].sessionTimoutInterval); // Other than the first launch, we always log the last session's deactivate with this session's activate. _shouldLogDeactivateEvent = _shouldLogActivateEvent; if (!_shouldLogDeactivateEvent) { // If we're not logging, then the time we spent deactivated is considered another interruption. But cap it // so errant or test uses doesn't blow out the cardinality on the backend processing _numInterruptionsInCurrentSession = MIN(_numInterruptionsInCurrentSession + 1, 200); } } _lastRestoreTime = now; _isCurrentlyLoaded = YES; if (calledFromActivateApp) { // It's important to log deactivate first to reset sessionID if (_shouldLogDeactivateEvent) { [FBSDKAppEvents logEvent:FBSDKAppEventNameDeactivatedApp valueToSum:_secondsSpentInCurrentSession parameters:[self appEventsParametersForDeactivate]]; // We've logged the session stats, now reset. _secondsSpentInCurrentSession = 0; _numInterruptionsInCurrentSession = 0; _sessionID = [[NSUUID UUID] UUIDString]; } if (_shouldLogActivateEvent) { [FBSDKAppEvents logEvent:FBSDKAppEventNameActivatedApp parameters:[self appEventsParametersForActivate]]; } } } } - (NSDictionary *)appEventsParametersForActivate { return @{ FBSDKAppEventParameterLaunchSource: [[self class] getSourceApplication], FBSDKAppEventParameterNameSessionID: _sessionID, }; } - (NSDictionary *)appEventsParametersForDeactivate { int quantaIndex = 0; while (_timeSinceLastSuspend > INACTIVE_SECONDS_QUANTA[quantaIndex]) { quantaIndex++; } NSMutableDictionary *params = [@{ FBSDKAppEventParameterNameSessionInterruptions : @(_numInterruptionsInCurrentSession), FBSDKAppEventParameterNameTimeBetweenSessions : [NSString stringWithFormat:@"session_quanta_%d", quantaIndex], FBSDKAppEventParameterLaunchSource: [[self class] getSourceApplication], FBSDKAppEventParameterNameSessionID : _sessionID ?: @"", } mutableCopy]; if (_lastSuspendTime) { params[FBSDKAppEventParameterLogTime] = @(_lastSuspendTime); } return [params copy]; } + (void)setSourceApplication:(NSString *)sourceApplication openURL:(NSURL *)url { [self setSourceApplication:sourceApplication isFromAppLink:[FBSDKInternalUtility dictionaryFromFBURL:url][@"al_applink_data"] != nil]; } + (void)setSourceApplication:(NSString *)sourceApplication isFromAppLink:(BOOL)isFromAppLink { g_isOpenedFromAppLink = isFromAppLink; g_sourceApplication = sourceApplication; } + (NSString *)getSourceApplication { NSString *openType = @"Unclassified"; if (g_isOpenedFromAppLink) { openType = @"AppLink"; } return (g_sourceApplication ? [NSString stringWithFormat:@"%@(%@)", openType, g_sourceApplication] : openType); } + (void)resetSourceApplication { g_sourceApplication = nil; g_isOpenedFromAppLink = NO; } + (void)registerAutoResetSourceApplication { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resetSourceApplication) name:UIApplicationDidEnterBackgroundNotification object:nil]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/AppLink/FBSDKBoltsMeasurementEventListener.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @interface FBSDKBoltsMeasurementEventListener : NSObject + (FBSDKBoltsMeasurementEventListener *)defaultListener; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/AppLink/FBSDKBoltsMeasurementEventListener.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKBoltsMeasurementEventListener.h" #import "FBSDKAppEvents+Internal.h" #import "FBSDKTimeSpentData.h" static NSString *const BoltsMeasurementEventNotificationName = @"com.parse.bolts.measurement_event"; static NSString *const BoltsMeasurementEventName = @"event_name"; static NSString *const BoltsMeasurementEventArgs = @"event_args"; static NSString *const BoltsMeasurementEventPrefix = @"bf_"; @implementation FBSDKBoltsMeasurementEventListener + (instancetype)defaultListener { static dispatch_once_t dispatchOnceLocker = 0; static FBSDKBoltsMeasurementEventListener *defaultListener = nil; dispatch_once(&dispatchOnceLocker, ^{ defaultListener = [[self alloc] init]; NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [center addObserver:defaultListener selector:@selector(logFBAppEventForNotification:) name:BoltsMeasurementEventNotificationName object:nil]; }); return defaultListener; } - (void)logFBAppEventForNotification:(NSNotification *)note { // when catch al_nav_in event, we set source application for FBAppEvents. if ([note.userInfo[BoltsMeasurementEventName] isEqualToString:@"al_nav_in"]) { NSString *sourceApplication = note.userInfo[BoltsMeasurementEventArgs][@"sourceApplication"]; if (sourceApplication) { [FBSDKTimeSpentData setSourceApplication:sourceApplication isFromAppLink:YES]; } } NSDictionary *eventArgs = note.userInfo[BoltsMeasurementEventArgs]; NSMutableDictionary *logData = [[NSMutableDictionary alloc] init]; for(NSString *key in eventArgs.allKeys) { NSError *error = nil; NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^0-9a-zA-Z _-]" options:0 error:&error]; NSString *safeKey = [regex stringByReplacingMatchesInString:key options:0 range:NSMakeRange(0, [key length]) withTemplate:@"-"]; safeKey = [safeKey stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" -"]]; logData[safeKey] = eventArgs[key]; } [FBSDKAppEvents logImplicitEvent:[BoltsMeasurementEventPrefix stringByAppendingString:note.userInfo[BoltsMeasurementEventName]] valueToSum:nil parameters:logData accessToken:nil]; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @interface FBSDKBase64 : NSObject /*! @abstract Decodes a base-64 encoded string. @param string The base-64 encoded string. @return NSData containing the decoded bytes. */ + (NSData *)decodeAsData:(NSString *)string; /*! @abstract Decodes a base-64 encoded string into a string. @param string The base-64 encoded string. @return NSString with the decoded UTF-8 value. */ + (NSString *)decodeAsString:(NSString *)string; /*! @abstract Encodes data into a string. @param data The data to be encoded. @return The base-64 encoded string. */ + (NSString *)encodeData:(NSData *)data; /*! @abstract Encodes string into a base-64 representation. @param string The string to be encoded. @return The base-64 encoded string. */ + (NSString *)encodeString:(NSString *)string; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKBase64.h" #import "FBSDKMacros.h" @implementation FBSDKBase64 { BOOL _optionsEnabled; } static FBSDKBase64 *_decoder; static FBSDKBase64 *_encoder; #pragma mark - Class Methods + (void)initialize { if (self == [FBSDKBase64 class]) { BOOL optionsEnabled; optionsEnabled = [NSData instancesRespondToSelector:@selector(initWithBase64EncodedString:options:)]; _decoder = [[FBSDKBase64 alloc] initWithOptionsEnabled:optionsEnabled]; optionsEnabled = [NSData instancesRespondToSelector:@selector(base64EncodedStringWithOptions:)]; _encoder = [[FBSDKBase64 alloc] initWithOptionsEnabled:optionsEnabled]; } } + (NSData *)decodeAsData:(NSString *)string { return [_decoder decodeAsData:string]; } + (NSString *)decodeAsString:(NSString *)string { return [_decoder decodeAsString:string]; } + (NSString *)encodeData:(NSData *)data { return [_encoder encodeData:data]; } + (NSString *)encodeString:(NSString *)string { return [_encoder encodeString:string]; } #pragma mark - Object Lifecycle - (instancetype)init { FBSDK_NOT_DESIGNATED_INITIALIZER(initWithOptionsEnabled:); return nil; } - (instancetype)initWithOptionsEnabled:(BOOL)optionsEnabled { if ((self = [super init])) { _optionsEnabled = optionsEnabled; } return self; } #pragma mark - Implementation Methods - (NSData *)decodeAsData:(NSString *)string { if (!string) { return nil; } // This padding will be appended before stripping unknown characters, so if there are unknown characters of count % 4 // it will not be able to decode. Since we assume valid base64 data, we will take this as is. int needPadding = string.length % 4; if (needPadding > 0) { needPadding = 4 - needPadding; string = [string stringByPaddingToLength:string.length+needPadding withString:@"=" startingAtIndex:0]; } if (_optionsEnabled) { return [[NSData alloc] initWithBase64EncodedString:string options:NSDataBase64DecodingIgnoreUnknownCharacters]; } else { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" return [[NSData alloc] initWithBase64Encoding:string]; #pragma clang diagnostic pop } } - (NSString *)decodeAsString:(NSString *)string { NSData *data = [self decodeAsData:string]; if (!data) { return nil; } return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; } - (NSString *)encodeData:(NSData *)data { if (!data) { return nil; } if (_optionsEnabled) { return [data base64EncodedStringWithOptions:0]; } else { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" return [data base64Encoding]; #pragma clang diagnostic pop } } - (NSString *)encodeString:(NSString *)string { return [self encodeData:[string dataUsingEncoding:NSUTF8StringEncoding]]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPICrypto.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKBridgeAPIRequest.h" @interface FBSDKBridgeAPICrypto : NSObject + (void)addCipherKeyToQueryParameters:(NSMutableDictionary *)queryParameters; + (NSDictionary *)decryptResponseForRequest:(FBSDKBridgeAPIRequest *)request queryParameters:(NSDictionary *)queryParameters error:(NSError *__autoreleasing *)errorRef; + (void)reset; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPICrypto.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKBridgeAPICrypto.h" #import "FBSDKBridgeAPIProtocol.h" #import "FBSDKConstants.h" #import "FBSDKCrypto.h" #import "FBSDKError.h" #import "FBSDKInternalUtility.h" #import "FBSDKMacros.h" #import "FBSDKSettings.h" #import "FBSDKUtility.h" static NSString *const FBSDKBridgeAPICryptoCipherKey = @"cipher"; static NSString *const FBSDKBridgeAPICryptoCipherKeyKey = @"cipher_key"; static NSString *g_cipherKey = nil; @implementation FBSDKBridgeAPICrypto #pragma mark - Class Methods + (void)addCipherKeyToQueryParameters:(NSMutableDictionary *)queryParameters { [FBSDKInternalUtility dictionary:queryParameters setObject:[self _cipherKey] forKey:FBSDKBridgeAPICryptoCipherKeyKey]; } + (NSDictionary *)decryptResponseForRequest:(FBSDKBridgeAPIRequest *)request queryParameters:(NSDictionary *)queryParameters error:(NSError *__autoreleasing *)errorRef { if (errorRef != NULL) { *errorRef = nil; } NSString *cipher = queryParameters[FBSDKBridgeAPICryptoCipherKey]; if (!cipher) { return queryParameters ?: @{}; } NSString *version = queryParameters[FBSDKBridgeAPIVersionKey]; NSString *cipherKey = [self _cipherKey]; if (!version || !cipherKey) { if (errorRef != NULL) { NSDictionary *userInfo = @{ FBSDKErrorArgumentValueKey: queryParameters, }; *errorRef = [FBSDKError errorWithCode:FBSDKEncryptionErrorCode userInfo:userInfo message:@"Error decrypting incoming query parameters." underlyingError:nil]; } return nil; } NSArray *additionalSignedDataArray = @[ [[NSBundle mainBundle] bundleIdentifier], [FBSDKSettings appID] ?: @"", @"bridge", request.methodName ?: @"", version, ]; NSString *additionalSignedDataString = [additionalSignedDataArray componentsJoinedByString:@":"]; NSData *additionalSignedData = [additionalSignedDataString dataUsingEncoding:NSUTF8StringEncoding]; FBSDKCrypto *crypto = [[FBSDKCrypto alloc] initWithMasterKey:cipherKey]; NSData *decryptedData = [crypto decrypt:cipher additionalSignedData:additionalSignedData]; if (!decryptedData) { if (errorRef != NULL) { NSDictionary *userInfo = @{ FBSDKErrorArgumentValueKey: @{ @"cipher": cipher, @"bundleIdentifier": additionalSignedDataArray[0], @"appID": additionalSignedDataArray[1], @"host": additionalSignedDataArray[2], @"methodName": additionalSignedDataArray[3], @"version": additionalSignedDataArray[4], }, }; *errorRef = [FBSDKError errorWithCode:FBSDKEncryptionErrorCode userInfo:userInfo message:@"Error decrypting incoming query parameters." underlyingError:nil]; } return nil; } NSString *decryptedString = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding]; NSDictionary *decryptedDictionary = [FBSDKUtility dictionaryWithQueryString:decryptedString]; NSMutableDictionary *decryptedQueryParameters = [[NSMutableDictionary alloc] initWithDictionary:decryptedDictionary]; decryptedQueryParameters[FBSDKBridgeAPIVersionKey] = version; return [decryptedQueryParameters copy]; } + (void)reset { [self _resetCipherKey]; } #pragma mark - Object Lifecycle - (instancetype)init { FBSDK_NO_DESIGNATED_INITIALIZER(); return nil; } #pragma mark - Helper Methods + (NSString *)_cipherKey { if (g_cipherKey) { return g_cipherKey; } g_cipherKey = [[[NSUserDefaults standardUserDefaults] stringForKey:FBSDKBridgeAPICryptoCipherKeyKey] copy]; if (g_cipherKey) { return g_cipherKey; } return [self _resetCipherKey]; } + (NSString *)_resetCipherKey { g_cipherKey = [[FBSDKCrypto makeMasterKey] copy]; [[NSUserDefaults standardUserDefaults] setObject:g_cipherKey forKey:FBSDKBridgeAPICryptoCipherKeyKey]; return g_cipherKey; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIProtocol.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import "FBSDKBridgeAPIProtocolType.h" @class FBSDKBridgeAPIRequest; FBSDK_EXTERN NSString *const FBSDKBridgeAPIAppIDKey; FBSDK_EXTERN NSString *const FBSDKBridgeAPISchemeSuffixKey; FBSDK_EXTERN NSString *const FBSDKBridgeAPIVersionKey; @protocol FBSDKBridgeAPIProtocol - (NSURL *)requestURLWithActionID:(NSString *)actionID scheme:(NSString *)scheme methodName:(NSString *)methodName methodVersion:(NSString *)methodVersion parameters:(NSDictionary *)parameters error:(NSError *__autoreleasing *)errorRef; - (NSDictionary *)responseParametersForActionID:(NSString *)actionID queryParameters:(NSDictionary *)queryParameters cancelled:(BOOL *)cancelledRef error:(NSError *__autoreleasing *)errorRef; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIProtocolType.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import typedef NS_ENUM(NSUInteger, FBSDKBridgeAPIProtocolType) { FBSDKBridgeAPIProtocolTypeNative, FBSDKBridgeAPIProtocolTypeWeb, }; ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest+Private.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKBridgeAPIProtocol.h" #import "FBSDKBridgeAPIRequest.h" @interface FBSDKBridgeAPIRequest () - (instancetype)initWithProtocol:(id)protocol protocolType:(FBSDKBridgeAPIProtocolType)protocolType scheme:(NSString *)scheme methodName:(NSString *)methodName methodVersion:(NSString *)methodVersion parameters:(NSDictionary *)parameters userInfo:(NSDictionary *)userInfo NS_DESIGNATED_INITIALIZER; @property (nonatomic, strong, readonly) id protocol; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import "FBSDKBridgeAPIProtocolType.h" @interface FBSDKBridgeAPIRequest : NSObject + (instancetype)bridgeAPIRequestWithProtocolType:(FBSDKBridgeAPIProtocolType)protocolType scheme:(NSString *)scheme methodName:(NSString *)methodName methodVersion:(NSString *)methodVersion parameters:(NSDictionary *)parameters userInfo:(NSDictionary *)userInfo; @property (nonatomic, copy, readonly) NSString *actionID; @property (nonatomic, copy, readonly) NSString *methodName; @property (nonatomic, copy, readonly) NSString *methodVersion; @property (nonatomic, copy, readonly) NSDictionary *parameters; @property (nonatomic, assign, readonly) FBSDKBridgeAPIProtocolType protocolType; @property (nonatomic, copy, readonly) NSString *scheme; @property (nonatomic, copy, readonly) NSDictionary *userInfo; - (NSURL *)requestURL:(NSError *__autoreleasing *)errorRef; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKBridgeAPIRequest.h" #import "FBSDKBridgeAPIRequest+Private.h" #import "FBSDKBridgeAPICrypto.h" #import "FBSDKBridgeAPIProtocolNativeV1.h" #import "FBSDKBridgeAPIProtocolWebV1.h" #import "FBSDKBridgeAPIProtocolWebV2.h" #import "FBSDKInternalUtility.h" #import "FBSDKMacros.h" #import "FBSDKSettings.h" #import "FBSDKUtility.h" NSString *const FBSDKBridgeAPIAppIDKey = @"app_id"; NSString *const FBSDKBridgeAPISchemeSuffixKey = @"scheme_suffix"; NSString *const FBSDKBridgeAPIVersionKey = @"version"; @implementation FBSDKBridgeAPIRequest #pragma mark - Class Methods + (instancetype)bridgeAPIRequestWithProtocolType:(FBSDKBridgeAPIProtocolType)protocolType scheme:(NSString *)scheme methodName:(NSString *)methodName methodVersion:(NSString *)methodVersion parameters:(NSDictionary *)parameters userInfo:(NSDictionary *)userInfo { return [[self alloc] initWithProtocol:[self _protocolForType:protocolType scheme:scheme] protocolType:protocolType scheme:scheme methodName:methodName methodVersion:methodVersion parameters:parameters userInfo:userInfo]; } + (NSDictionary *)protocolMap { static NSDictionary *_protocolMap; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _protocolMap = @{ @(FBSDKBridgeAPIProtocolTypeNative): @{ FBSDK_CANOPENURL_FACEBOOK:[[FBSDKBridgeAPIProtocolNativeV1 alloc] initWithAppScheme:@"fbapi20130214"], FBSDK_CANOPENURL_MESSENGER:[[FBSDKBridgeAPIProtocolNativeV1 alloc] initWithAppScheme:@"fb-messenger-api20140430"] }, @(FBSDKBridgeAPIProtocolTypeWeb): @{ @"https": [[FBSDKBridgeAPIProtocolWebV1 alloc] init], @"web": [[FBSDKBridgeAPIProtocolWebV2 alloc] init] }, }; }); return _protocolMap; } #pragma mark - Object Lifecycle - (instancetype)initWithProtocol:(id)protocol protocolType:(FBSDKBridgeAPIProtocolType)protocolType scheme:(NSString *)scheme methodName:(NSString *)methodName methodVersion:(NSString *)methodVersion parameters:(NSDictionary *)parameters userInfo:(NSDictionary *)userInfo { if (!protocol) { return nil; } if ((self = [super init])) { _protocol = protocol; _protocolType = protocolType; _scheme = [scheme copy]; _methodName = [methodName copy]; _methodVersion = [methodVersion copy]; _parameters = [parameters copy]; _userInfo = [userInfo copy]; _actionID = [[NSUUID UUID] UUIDString]; } return self; } - (instancetype)init { FBSDK_NOT_DESIGNATED_INITIALIZER(initWithProtocol:protocolType:scheme:methodName:methodVersion:parameters:userInfo:); return [self initWithProtocol:nil protocolType:FBSDKBridgeAPIProtocolTypeWeb scheme:nil methodName:nil methodVersion:nil parameters:nil userInfo:nil]; } #pragma mark - Public Methods - (NSURL *)requestURL:(NSError *__autoreleasing *)errorRef { NSURL *requestURL = [_protocol requestURLWithActionID:self.actionID scheme:self.scheme methodName:self.methodName methodVersion:self.methodVersion parameters:self.parameters error:errorRef]; if (!requestURL) { return nil; } [FBSDKInternalUtility validateURLSchemes]; NSDictionary *requestQueryParameters = [FBSDKUtility dictionaryWithQueryString:requestURL.query]; NSMutableDictionary *queryParameters = [[NSMutableDictionary alloc] initWithDictionary:requestQueryParameters]; [FBSDKBridgeAPICrypto addCipherKeyToQueryParameters:queryParameters]; [FBSDKInternalUtility dictionary:queryParameters setObject:[FBSDKSettings appID] forKey:FBSDKBridgeAPIAppIDKey]; [FBSDKInternalUtility dictionary:queryParameters setObject:[FBSDKSettings appURLSchemeSuffix] forKey:FBSDKBridgeAPISchemeSuffixKey]; requestURL = [FBSDKInternalUtility URLWithScheme:requestURL.scheme host:requestURL.host path:requestURL.path queryParameters:queryParameters error:errorRef]; return requestURL; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { return self; } + (id)_protocolForType:(FBSDKBridgeAPIProtocolType)type scheme:(NSString *)scheme { id protocol = [self protocolMap][@(type)][scheme]; if (type == FBSDKBridgeAPIProtocolTypeWeb) { return protocol; } NSURLComponents *components = [[NSURLComponents alloc] init]; components.scheme = scheme; components.path = @"/"; if ([[UIApplication sharedApplication] canOpenURL:components.URL]) { return protocol; } return nil; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import "FBSDKBridgeAPIRequest.h" @interface FBSDKBridgeAPIResponse : NSObject + (instancetype)bridgeAPIResponseWithRequest:(FBSDKBridgeAPIRequest *)request error:(NSError *)error; + (instancetype)bridgeAPIResponseWithRequest:(FBSDKBridgeAPIRequest *)request responseURL:(NSURL *)responseURL sourceApplication:(NSString *)sourceApplication error:(NSError *__autoreleasing *)errorRef; + (instancetype)bridgeAPIResponseCancelledWithRequest:(FBSDKBridgeAPIRequest *)request; @property (nonatomic, assign, readonly, getter=isCancelled) BOOL cancelled; @property (nonatomic, copy, readonly) NSError *error; @property (nonatomic, copy, readonly) FBSDKBridgeAPIRequest *request; @property (nonatomic, copy, readonly) NSDictionary *responseParameters; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKBridgeAPIResponse.h" #import "FBSDKBridgeAPICrypto.h" #import "FBSDKBridgeAPIProtocol.h" #import "FBSDKBridgeAPIProtocolType.h" #import "FBSDKBridgeAPIRequest+Private.h" #import "FBSDKInternalUtility.h" #import "FBSDKMacros.h" #import "FBSDKTypeUtility.h" #import "FBSDKUtility.h" @interface FBSDKBridgeAPIResponse () - (instancetype)initWithRequest:(FBSDKBridgeAPIRequest *)request responseParameters:(NSDictionary *)responseParameters cancelled:(BOOL)cancelled error:(NSError *)error NS_DESIGNATED_INITIALIZER; @end @implementation FBSDKBridgeAPIResponse #pragma mark - Class Methods + (instancetype)bridgeAPIResponseWithRequest:(FBSDKBridgeAPIRequest *)request error:(NSError *)error { return [[self alloc] initWithRequest:request responseParameters:nil cancelled:NO error:error]; } + (instancetype)bridgeAPIResponseWithRequest:(FBSDKBridgeAPIRequest *)request responseURL:(NSURL *)responseURL sourceApplication:(NSString *)sourceApplication error:(NSError *__autoreleasing *)errorRef { FBSDKBridgeAPIProtocolType protocolType = request.protocolType; switch (protocolType) { case FBSDKBridgeAPIProtocolTypeNative:{ if (![FBSDKInternalUtility isFacebookBundleIdentifier:sourceApplication]) { [FBSDKBridgeAPICrypto reset]; return nil; } break; } case FBSDKBridgeAPIProtocolTypeWeb:{ if (![FBSDKInternalUtility isSafariBundleIdentifier:sourceApplication]) { [FBSDKBridgeAPICrypto reset]; return nil; } break; } } NSDictionary *queryParameters = [FBSDKUtility dictionaryWithQueryString:responseURL.query]; queryParameters = [FBSDKBridgeAPICrypto decryptResponseForRequest:request queryParameters:queryParameters error:errorRef]; if (!queryParameters) { return nil; } id protocol = request.protocol; BOOL cancelled; NSError *error; NSDictionary *responseParameters = [protocol responseParametersForActionID:request.actionID queryParameters:queryParameters cancelled:&cancelled error:&error]; if (errorRef != NULL) { *errorRef = error; } if (!responseParameters) { return nil; } return [[self alloc] initWithRequest:request responseParameters:responseParameters cancelled:cancelled error:error]; } + (instancetype)bridgeAPIResponseCancelledWithRequest:(FBSDKBridgeAPIRequest *)request { return [[self alloc] initWithRequest:request responseParameters:nil cancelled:YES error:nil]; } #pragma mark - Object Lifecycle - (instancetype)initWithRequest:(FBSDKBridgeAPIRequest *)request responseParameters:(NSDictionary *)responseParameters cancelled:(BOOL)cancelled error:(NSError *)error { if ((self = [super init])) { _request = [request copy]; _responseParameters = [responseParameters copy]; _cancelled = cancelled; _error = [error copy]; } return self; } - (instancetype)init { FBSDK_NOT_DESIGNATED_INITIALIZER(initWithRequest:responseParameters:cancelled:error:); return [self initWithRequest:nil responseParameters:nil cancelled:NO error:nil]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { return self; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKURLOpening.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright 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. @protocol FBSDKURLOpening // Implementations should make sure they can handle nil parameters // which is possible in SafariViewController. - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation; - (void)applicationDidBecomeActive:(UIApplication *)application; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolNativeV1.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import "FBSDKBridgeAPIProtocol.h" typedef struct { __unsafe_unretained NSString *bridgeArgs; __unsafe_unretained NSString *methodArgs; __unsafe_unretained NSString *methodVersion; } FBSDKBridgeAPIProtocolNativeV1OutputKeysStruct; FBSDK_EXTERN const FBSDKBridgeAPIProtocolNativeV1OutputKeysStruct FBSDKBridgeAPIProtocolNativeV1OutputKeys; typedef struct { __unsafe_unretained NSString *actionID; __unsafe_unretained NSString *appIcon; __unsafe_unretained NSString *appName; __unsafe_unretained NSString *sdkVersion; } FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeysStruct; FBSDK_EXTERN const FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeysStruct FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeys; typedef struct { __unsafe_unretained NSString *bridgeArgs; __unsafe_unretained NSString *methodResults; } FBSDKBridgeAPIProtocolNativeV1InputKeysStruct; FBSDK_EXTERN const FBSDKBridgeAPIProtocolNativeV1InputKeysStruct FBSDKBridgeAPIProtocolNativeV1InputKeys; typedef struct { __unsafe_unretained NSString *actionID; __unsafe_unretained NSString *error; } FBSDKBridgeAPIProtocolNativeV1BridgeParameterInputKeysStruct; FBSDK_EXTERN const FBSDKBridgeAPIProtocolNativeV1BridgeParameterInputKeysStruct FBSDKBridgeAPIProtocolNativeV1BridgeParameterInputKeys; @interface FBSDKBridgeAPIProtocolNativeV1 : NSObject - (instancetype)initWithAppScheme:(NSString *)appScheme; - (instancetype)initWithAppScheme:(NSString *)appScheme pasteboard:(UIPasteboard *)pasteboard dataLengthThreshold:(NSUInteger)dataLengthThreshold includeAppIcon:(BOOL)includeAppIcon NS_DESIGNATED_INITIALIZER; @property (nonatomic, copy, readonly) NSString *appScheme; @property (nonatomic, assign, readonly) NSUInteger dataLengthThreshold; @property (nonatomic, assign, readonly) BOOL includeAppIcon; @property (nonatomic, strong, readonly) UIPasteboard *pasteboard; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolNativeV1.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKBridgeAPIProtocolNativeV1.h" #import #import #import "FBSDKApplicationDelegate+Internal.h" #import "FBSDKBase64.h" #import "FBSDKBridgeAPIRequest.h" #import "FBSDKConstants.h" #import "FBSDKError.h" #import "FBSDKInternalUtility.h" #import "FBSDKSettings.h" #import "FBSDKTypeUtility.h" #define FBSDKBridgeAPIProtocolNativeV1BridgeMaxBase64DataLengthThreshold (1024 * 16) const FBSDKBridgeAPIProtocolNativeV1OutputKeysStruct FBSDKBridgeAPIProtocolNativeV1OutputKeys = { .bridgeArgs = @"bridge_args", .methodArgs = @"method_args", .methodVersion = @"version", }; const FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeysStruct FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeys = { .actionID = @"action_id", .appIcon = @"app_icon", .appName = @"app_name", .sdkVersion = @"sdk_version", }; const FBSDKBridgeAPIProtocolNativeV1InputKeysStruct FBSDKBridgeAPIProtocolNativeV1InputKeys = { .bridgeArgs = @"bridge_args", .methodResults = @"method_results", }; const FBSDKBridgeAPIProtocolNativeV1BridgeParameterInputKeysStruct FBSDKBridgeAPIProtocolNativeV1BridgeParameterInputKeys = { .actionID = @"action_id", .error = @"error", }; static const struct { __unsafe_unretained NSString *isBase64; __unsafe_unretained NSString *isPasteboard; __unsafe_unretained NSString *tag; __unsafe_unretained NSString *value; } FBSDKBridgeAPIProtocolNativeV1DataKeys = { .isBase64 = @"isBase64", .isPasteboard = @"isPasteboard", .tag = @"tag", .value = @"fbAppBridgeType_jsonReadyValue", }; static NSString *const FBSDKBridgeAPIProtocolNativeV1DataPasteboardKey = @"com.facebook.Facebook.FBAppBridgeType"; static const struct { __unsafe_unretained NSString *data; __unsafe_unretained NSString *image; } FBSDKBridgeAPIProtocolNativeV1DataTypeTags = { .data = @"data", // we serialize jpegs but use png for backward compatibility - it is any image format that UIImage can handle .image = @"png", }; static const struct { __unsafe_unretained NSString *code; __unsafe_unretained NSString *domain; __unsafe_unretained NSString *userInfo; } FBSDKBridgeAPIProtocolNativeV1ErrorKeys = { .code = @"code", .domain = @"domain", .userInfo = @"user_info", }; @implementation FBSDKBridgeAPIProtocolNativeV1 #pragma mark - Object Lifecycle - (instancetype)initWithAppScheme:(NSString *)appScheme { return [self initWithAppScheme:appScheme pasteboard:[UIPasteboard generalPasteboard] dataLengthThreshold:FBSDKBridgeAPIProtocolNativeV1BridgeMaxBase64DataLengthThreshold includeAppIcon:YES]; } - (instancetype)initWithAppScheme:(NSString *)appScheme pasteboard:(UIPasteboard *)pasteboard dataLengthThreshold:(NSUInteger)dataLengthThreshold includeAppIcon:(BOOL)includeAppIcon { if ((self = [super init])) { _appScheme = [appScheme copy]; _pasteboard = pasteboard; _dataLengthThreshold = dataLengthThreshold; _includeAppIcon = includeAppIcon; } return self; } - (instancetype)init { FBSDK_NOT_DESIGNATED_INITIALIZER(initWithAppScheme:); return [self initWithAppScheme:nil]; } #pragma mark - FBSDKBridgeAPIProtocol - (NSURL *)requestURLWithActionID:(NSString *)actionID scheme:(NSString *)scheme methodName:(NSString *)methodName methodVersion:(NSString *)methodVersion parameters:(NSDictionary *)parameters error:(NSError *__autoreleasing *)errorRef { NSString *host = @"dialog"; NSString *path = [@"/" stringByAppendingString:methodName]; NSMutableDictionary *queryParameters = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:queryParameters setObject:methodVersion forKey:FBSDKBridgeAPIProtocolNativeV1OutputKeys.methodVersion]; if ([parameters count]) { NSString *parametersString = [self _JSONStringForObject:parameters enablePasteboard:YES error:errorRef]; if (!parametersString) { return nil; } [FBSDKInternalUtility dictionary:queryParameters setObject:parametersString forKey:FBSDKBridgeAPIProtocolNativeV1OutputKeys.methodArgs]; } NSDictionary *bridgeParameters = [self _bridgeParametersWithActionID:actionID error:errorRef]; if (!bridgeParameters) { return nil; } NSString *bridgeParametersString = [self _JSONStringForObject:bridgeParameters enablePasteboard:NO error:errorRef]; if (!bridgeParametersString) { return nil; } [FBSDKInternalUtility dictionary:queryParameters setObject:bridgeParametersString forKey:FBSDKBridgeAPIProtocolNativeV1OutputKeys.bridgeArgs]; return [FBSDKInternalUtility URLWithScheme:self.appScheme host:host path:path queryParameters:queryParameters error:errorRef]; } - (NSDictionary *)responseParametersForActionID:(NSString *)actionID queryParameters:(NSDictionary *)queryParameters cancelled:(BOOL *)cancelledRef error:(NSError *__autoreleasing *)errorRef { if (cancelledRef != NULL) { *cancelledRef = NO; } if (errorRef != NULL) { *errorRef = nil; } NSError *error; NSString *bridgeParametersJSON = queryParameters[FBSDKBridgeAPIProtocolNativeV1InputKeys.bridgeArgs]; NSDictionary *bridgeParameters = [FBSDKInternalUtility objectForJSONString:bridgeParametersJSON error:&error]; bridgeParameters = [FBSDKTypeUtility dictionaryValue:bridgeParameters]; if (!bridgeParameters) { if (error && (errorRef != NULL)) { *errorRef = [FBSDKError invalidArgumentErrorWithName:FBSDKBridgeAPIProtocolNativeV1InputKeys.bridgeArgs value:bridgeParametersJSON message:@"Invalid bridge_args." underlyingError:error]; } return nil; } NSString *responseActionID = bridgeParameters[FBSDKBridgeAPIProtocolNativeV1BridgeParameterInputKeys.actionID]; responseActionID = [FBSDKTypeUtility stringValue:responseActionID]; if (![responseActionID isEqualToString:actionID]) { return nil; } NSDictionary *errorDictionary = bridgeParameters[FBSDKBridgeAPIProtocolNativeV1BridgeParameterInputKeys.error]; errorDictionary = [FBSDKTypeUtility dictionaryValue:errorDictionary]; if (errorDictionary) { error = [self _errorWithDictionary:errorDictionary]; if (errorRef != NULL) { *errorRef = error; } return nil; } NSString *resultParametersJSON = queryParameters[FBSDKBridgeAPIProtocolNativeV1InputKeys.methodResults]; NSDictionary *resultParameters = [FBSDKInternalUtility objectForJSONString:resultParametersJSON error:&error]; if (!resultParameters) { if (errorRef != NULL) { *errorRef = [FBSDKError invalidArgumentErrorWithName:FBSDKBridgeAPIProtocolNativeV1InputKeys.methodResults value:resultParametersJSON message:@"Invalid method_results." underlyingError:error]; } return nil; } if (cancelledRef != NULL) { NSString *completionGesture = [FBSDKTypeUtility stringValue:resultParameters[@"completionGesture"]]; *cancelledRef = [completionGesture isEqualToString:@"cancel"]; } return resultParameters; } #pragma mark - Helper Methods - (UIImage *)_appIcon { if (!_includeAppIcon) { return nil; } NSArray *files = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIcons"] [@"CFBundlePrimaryIcon"] [@"CFBundleIconFiles"]; if (![files count]) { return nil; } return [UIImage imageNamed:files[0]]; } - (NSDictionary *)_bridgeParametersWithActionID:(NSString *)actionID error:(NSError *__autoreleasing *)errorRef { NSMutableDictionary *bridgeParameters = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:bridgeParameters setObject:actionID forKey:FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeys.actionID]; [FBSDKInternalUtility dictionary:bridgeParameters setObject:[self _appIcon] forKey:FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeys.appIcon]; [FBSDKInternalUtility dictionary:bridgeParameters setObject:[FBSDKSettings displayName] forKey:FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeys.appName]; [FBSDKInternalUtility dictionary:bridgeParameters setObject:[FBSDKSettings sdkVersion] forKey:FBSDKBridgeAPIProtocolNativeV1BridgeParameterOutputKeys.sdkVersion]; return bridgeParameters; } - (NSError *)_errorWithDictionary:(NSDictionary *)dictionary { if (!dictionary) { return nil; } NSString *domain = [FBSDKTypeUtility stringValue:dictionary[FBSDKBridgeAPIProtocolNativeV1ErrorKeys.domain]] ?: FBSDKErrorDomain; NSInteger code = [FBSDKTypeUtility integerValue:dictionary[FBSDKBridgeAPIProtocolNativeV1ErrorKeys.code]] ?: FBSDKUnknownErrorCode; NSDictionary *userInfo = [FBSDKTypeUtility dictionaryValue:dictionary[FBSDKBridgeAPIProtocolNativeV1ErrorKeys.userInfo]]; return [NSError errorWithDomain:domain code:code userInfo:userInfo]; } - (NSString *)_JSONStringForObject:(id)object enablePasteboard:(BOOL)enablePasteboard error:(NSError **)errorRef { __block BOOL didAddToPasteboard = NO; return [FBSDKInternalUtility JSONStringForObject:object error:errorRef invalidObjectHandler:^id(id invalidObject, BOOL *stop) { NSString *dataTag = FBSDKBridgeAPIProtocolNativeV1DataTypeTags.data; if ([invalidObject isKindOfClass:[UIImage class]]) { UIImage *image = (UIImage *)invalidObject; // due to backward compatibility, we must send UIImage as NSData even though UIPasteboard can handle UIImage invalidObject = UIImageJPEGRepresentation(image, [FBSDKSettings JPEGCompressionQuality]); dataTag = FBSDKBridgeAPIProtocolNativeV1DataTypeTags.image; } if ([invalidObject isKindOfClass:[NSData class]]) { NSData *data = (NSData *)invalidObject; NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; if (didAddToPasteboard || !enablePasteboard || !_pasteboard || (data.length < _dataLengthThreshold)) { dictionary[FBSDKBridgeAPIProtocolNativeV1DataKeys.isBase64] = @YES; dictionary[FBSDKBridgeAPIProtocolNativeV1DataKeys.tag] = dataTag; [FBSDKInternalUtility dictionary:dictionary setObject:[FBSDKBase64 encodeData:data] forKey:FBSDKBridgeAPIProtocolNativeV1DataKeys.value]; } else { dictionary[FBSDKBridgeAPIProtocolNativeV1DataKeys.isPasteboard] = @YES; dictionary[FBSDKBridgeAPIProtocolNativeV1DataKeys.tag] = dataTag; dictionary[FBSDKBridgeAPIProtocolNativeV1DataKeys.value] = _pasteboard.name; [_pasteboard setData:data forPasteboardType:FBSDKBridgeAPIProtocolNativeV1DataPasteboardKey]; // this version of the protocol only supports a single item on the pasteboard, so if when we add an item, make // sure we don't add another item didAddToPasteboard = YES; // if we are adding this to the general pasteboard, then we want to remove it when we are done with the share. // the Facebook app will not clear the value with this version of the protocol, so we should do it when the app // becomes active again NSString *pasteboardName = _pasteboard.name; if ([pasteboardName isEqualToString:UIPasteboardNameGeneral] || [pasteboardName isEqualToString:UIPasteboardNameFind]) { [[self class] clearData:data fromPasteboardOnApplicationDidBecomeActive:_pasteboard]; } } return dictionary; } else if ([invalidObject isKindOfClass:[NSURL class]]) { return [(NSURL *)invalidObject absoluteString]; } return invalidObject; }]; } + (void)clearData:(NSData *)data fromPasteboardOnApplicationDidBecomeActive:(UIPasteboard *)pasteboard { void(^notificationBlock)(NSNotification *) = ^(NSNotification *note){ NSData *pasteboardData = [pasteboard dataForPasteboardType:FBSDKBridgeAPIProtocolNativeV1DataPasteboardKey]; if ([data isEqualToData:pasteboardData]) { [pasteboard setData:[NSData data] forPasteboardType:FBSDKBridgeAPIProtocolNativeV1DataPasteboardKey]; } }; [[NSNotificationCenter defaultCenter] addObserverForName:FBSDKApplicationDidBecomeActiveNotification object:[FBSDKApplicationDelegate sharedInstance] queue:nil usingBlock:notificationBlock]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV1.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKBridgeAPIProtocol.h" @interface FBSDKBridgeAPIProtocolWebV1 : NSObject @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV1.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKBridgeAPIProtocolWebV1.h" #import #import "FBSDKBase64.h" #import "FBSDKBridgeAPIRequest.h" #import "FBSDKError.h" #import "FBSDKInternalUtility.h" #import "FBSDKMacros.h" #import "FBSDKSettings.h" #import "FBSDKTypeUtility.h" #define FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_ACTION_ID_KEY @"action_id" #define FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_BRIDGE_ARGS_KEY @"bridge_args" @implementation FBSDKBridgeAPIProtocolWebV1 #pragma mark - FBSDKBridgeAPIProtocol - (NSURL *)requestURLWithActionID:(NSString *)actionID scheme:(NSString *)scheme methodName:(NSString *)methodName methodVersion:(NSString *)methodVersion parameters:(NSDictionary *)parameters error:(NSError *__autoreleasing *)errorRef { NSMutableDictionary *queryParameters = [[NSMutableDictionary alloc] initWithDictionary:parameters]; queryParameters[@"display"] = @"touch"; NSString *bridgeArgs = [FBSDKInternalUtility JSONStringForObject:@{ FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_ACTION_ID_KEY: actionID } error:NULL invalidObjectHandler:NULL]; NSDictionary *redirectQueryParameters = @{ FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_BRIDGE_ARGS_KEY: bridgeArgs }; NSURL *redirectURL = [FBSDKInternalUtility appURLWithHost:@"bridge" path:methodName queryParameters:redirectQueryParameters error:NULL]; [FBSDKInternalUtility dictionary:queryParameters setObject:redirectURL forKey:@"redirect_uri"]; [queryParameters addEntriesFromDictionary:parameters]; return [FBSDKInternalUtility facebookURLWithHostPrefix:@"m" path:[@"/dialog/" stringByAppendingString:methodName] queryParameters:queryParameters error:NULL]; } - (NSDictionary *)responseParametersForActionID:(NSString *)actionID queryParameters:(NSDictionary *)queryParameters cancelled:(BOOL *)cancelledRef error:(NSError *__autoreleasing *)errorRef { if (errorRef != NULL) { *errorRef = nil; } NSInteger errorCode = [FBSDKTypeUtility integerValue:queryParameters[@"error_code"]]; switch (errorCode) { case 0:{ // good to go, handle the other codes and bail break; } case 4201:{ return @{ @"completionGesture": @"cancel", }; break; } default:{ if (errorRef != NULL) { *errorRef = [FBSDKError errorWithCode:errorCode message:[FBSDKTypeUtility stringValue:queryParameters[@"error_message"]]]; } return nil; break; } } NSError *error; NSString *bridgeParametersJSON = [FBSDKTypeUtility stringValue:queryParameters[FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_BRIDGE_ARGS_KEY]]; NSDictionary *bridgeParameters = [FBSDKInternalUtility objectForJSONString:bridgeParametersJSON error:&error]; if (!bridgeParameters) { if (error && (errorRef != NULL)) { *errorRef = [FBSDKError invalidArgumentErrorWithName:FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_BRIDGE_ARGS_KEY value:bridgeParametersJSON message:nil underlyingError:error]; } return nil; } NSString *responseActionID = bridgeParameters[FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_ACTION_ID_KEY]; responseActionID = [FBSDKTypeUtility stringValue:responseActionID]; if (![responseActionID isEqualToString:actionID]) { return nil; } NSMutableDictionary *resultParameters = [queryParameters mutableCopy]; [resultParameters removeObjectForKey:FBSDK_BRIDGE_API_PROTOCOL_WEB_V1_BRIDGE_ARGS_KEY]; resultParameters[@"didComplete"] = @YES; return resultParameters; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV2.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKBridgeAPIProtocol.h" @interface FBSDKBridgeAPIProtocolWebV2 : NSObject @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV2.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKBridgeAPIProtocolWebV2.h" #import "FBSDKBridgeAPIProtocolNativeV1.h" #import "FBSDKDialogConfiguration.h" #import "FBSDKError.h" #import "FBSDKInternalUtility.h" #import "FBSDKServerConfiguration.h" #import "FBSDKServerConfigurationManager.h" #import "FBSDKUtility.h" @implementation FBSDKBridgeAPIProtocolWebV2 { FBSDKBridgeAPIProtocolNativeV1 *_nativeProtocol; } #pragma mark - Object Lifecycle - (instancetype)init { if ((self = [super init])) { _nativeProtocol = [[FBSDKBridgeAPIProtocolNativeV1 alloc] initWithAppScheme:nil pasteboard:nil dataLengthThreshold:0 includeAppIcon:NO]; } return self; } #pragma mark - FBSDKBridgeAPIProtocol - (NSURL *)_redirectURLWithActionID:(NSString *)actionID methodName:(NSString *)methodName error:(NSError **)errorRef { NSDictionary *queryParameters = nil; if (actionID) { NSDictionary *bridgeArgs = @{ FBSDKBridgeAPIProtocolNativeV1BridgeParameterInputKeys.actionID: actionID }; NSString *bridgeArgsString = [FBSDKInternalUtility JSONStringForObject:bridgeArgs error:NULL invalidObjectHandler:NULL]; queryParameters = @{ FBSDKBridgeAPIProtocolNativeV1InputKeys.bridgeArgs: bridgeArgsString }; } return [FBSDKInternalUtility appURLWithHost:@"bridge" path:methodName queryParameters:queryParameters error:errorRef]; } - (NSURL *)_requestURLForDialogConfiguration:(FBSDKDialogConfiguration *)dialogConfiguration error:(NSError **)errorRef { NSURL *requestURL = dialogConfiguration.URL; if (!requestURL.scheme) { requestURL = [FBSDKInternalUtility facebookURLWithHostPrefix:@"m" path:requestURL.path queryParameters:nil defaultVersion:@"" error:errorRef]; } return requestURL; } - (NSURL *)requestURLWithActionID:(NSString *)actionID scheme:(NSString *)scheme methodName:(NSString *)methodName methodVersion:(NSString *)methodVersion parameters:(NSDictionary *)parameters error:(NSError *__autoreleasing *)errorRef { FBSDKServerConfiguration *serverConfiguration = [FBSDKServerConfigurationManager cachedServerConfiguration]; FBSDKDialogConfiguration *dialogConfiguration = [serverConfiguration dialogConfigurationForDialogName:methodName]; if (!dialogConfiguration) { if (errorRef != NULL) { *errorRef = [FBSDKError errorWithCode:FBSDKDialogUnavailableErrorCode message:nil]; } return nil; } NSURL *requestURL = [_nativeProtocol requestURLWithActionID:actionID scheme:scheme methodName:methodName methodVersion:methodVersion parameters:parameters error:errorRef]; if (!requestURL) { return nil; } NSMutableDictionary *queryParameters = [[FBSDKUtility dictionaryWithQueryString:requestURL.query] mutableCopy]; queryParameters[@"ios_bundle_id"] = [[NSBundle mainBundle] bundleIdentifier]; NSURL *redirectURL = [self _redirectURLWithActionID:nil methodName:methodName error:errorRef]; if (!redirectURL) { return nil; } queryParameters[@"redirect_url"] = redirectURL; requestURL = [self _requestURLForDialogConfiguration:dialogConfiguration error:errorRef]; if (!requestURL) { return nil; } return [FBSDKInternalUtility URLWithScheme:requestURL.scheme host:requestURL.host path:requestURL.path queryParameters:queryParameters error:errorRef]; } - (NSDictionary *)responseParametersForActionID:(NSString *)actionID queryParameters:(NSDictionary *)queryParameters cancelled:(BOOL *)cancelledRef error:(NSError *__autoreleasing *)errorRef { return [_nativeProtocol responseParametersForActionID:actionID queryParameters:queryParameters cancelled:cancelledRef error:errorRef]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Cryptography/FBSDKCrypto.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @interface FBSDKCrypto : NSObject /*! @abstract Generate numOfBytes random data. @discussion This calls the system-provided function SecRandomCopyBytes, based on /dev/random. */ + (NSData *)randomBytes:(NSUInteger)numOfBytes; /** * Generate numOfBytes random data, base64-encoded. * This calls the system-provided function SecRandomCopyBytes, based on /dev/random. */ + (NSString *)randomString:(NSUInteger)numOfBytes; /*! @abstract Generate a fresh master key using SecRandomCopyBytes, the result is encoded in base64/. */ + (NSString *)makeMasterKey; /*! @abstract Initialize with a base64-encoded master key. @discussion This key and the current derivation function will be used to generate the encryption key and the mac key. */ - (instancetype)initWithMasterKey:(NSString *)masterKey; /*! @abstract Initialize with base64-encoded encryption key and mac key. */ - (instancetype)initWithEncryptionKey:(NSString *)encryptionKey macKey:(NSString *)macKey; /*! @abstract Encrypt plainText and return the base64 encoded result. @discussion MAC computation involves additionalDataToSign. */ - (NSString *)encrypt:(NSData *)plainText additionalDataToSign:(NSData *)additionalDataToSign; /*! @abstract Decrypt base64EncodedCipherText. @discussion MAC computation involves additionalSignedData. */ - (NSData *)decrypt:(NSString *)base64EncodedCipherText additionalSignedData:(NSData *)additionalSignedData; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Cryptography/FBSDKCrypto.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKCrypto.h" #import #import #import #import "FBSDKBase64.h" #import "FBSDKDynamicFrameworkLoader.h" static const uint8_t kFBSDK_CRYPTO_CURRENT_VERSION = 1; static const uint8_t kFBSDK_CRYPTO_CURRENT_MASTER_KEY_LENGTH = 16; FBSDK_STATIC_INLINE void FBSDKCryptoWriteIntBigEndian(uint8_t *buffer, uint32_t value) { buffer[3] = (uint8_t)(value & 0xff); buffer[2] = (uint8_t)((value >> 8) & 0xff); buffer[1] = (uint8_t)((value >> 16) & 0xff); buffer[0] = (uint8_t)((value >> 24) & 0xff); } FBSDK_STATIC_INLINE void FBSDKCryptoBlankData(NSData *data) { if (!data) { return; } bzero((void *) [data bytes], [data length]); } // Note: the following simple derivation function is NOT suitable for passwords or weak keys FBSDK_STATIC_INLINE NSData *FBSDKCryptoMakeSubKey(uint8_t *key, size_t len, uint32_t idx) { if (!key || len < 10) { return nil; } size_t macBufferLength = 4; uint8_t macBuffer[4]; FBSDKCryptoWriteIntBigEndian(macBuffer, idx); uint8_t *result = malloc(CC_SHA256_DIGEST_LENGTH); if (!result) { return nil; } CCHmac(kCCHmacAlgSHA256, key, len, macBuffer, macBufferLength, result); return [NSData dataWithBytesNoCopy:result length:CC_SHA256_DIGEST_LENGTH]; } @implementation FBSDKCrypto { NSData *_encryptionKeyData; NSData *_macKeyData; } #pragma mark - Class Methods + (NSString *)makeMasterKey { NSData *masterKeyData = [FBSDKCrypto randomBytes:kFBSDK_CRYPTO_CURRENT_MASTER_KEY_LENGTH + 1]; // force the first byte to be the crypto version uint8_t *first = (uint8_t *) [masterKeyData bytes]; *first = kFBSDK_CRYPTO_CURRENT_VERSION; NSString *masterKey = [FBSDKBase64 encodeData:masterKeyData]; FBSDKCryptoBlankData(masterKeyData); return masterKey; } + (NSData *)randomBytes:(NSUInteger)numOfBytes { uint8_t *buffer = malloc(numOfBytes); int result = fbsdkdfl_SecRandomCopyBytes([FBSDKDynamicFrameworkLoader loadkSecRandomDefault], numOfBytes, buffer); if (result != 0) { free(buffer); return nil; } return [NSData dataWithBytesNoCopy:buffer length:numOfBytes]; } + (NSString *)randomString:(NSUInteger)numOfBytes { NSData *randomStringData = [FBSDKCrypto randomBytes:numOfBytes]; NSString *randomString = [FBSDKBase64 encodeData:randomStringData]; FBSDKCryptoBlankData(randomStringData); return randomString; } #pragma mark - Object Lifecycle - (instancetype)initWithMasterKey:(NSString *)masterKey { if ((self = [super init])) { NSData *masterKeyData = [FBSDKBase64 decodeAsData:masterKey]; NSUInteger len = [masterKeyData length]; uint8_t *first = (uint8_t *) [masterKeyData bytes]; if (len == 0 || first == nil || *first != kFBSDK_CRYPTO_CURRENT_VERSION) { // only one version supported at the moment return nil; } _encryptionKeyData = FBSDKCryptoMakeSubKey(first+1, len-1, 1); _macKeyData = FBSDKCryptoMakeSubKey(first+1, len-1, 2); FBSDKCryptoBlankData(masterKeyData); return self; } else { return nil; } } - (instancetype)initWithEncryptionKey:(NSString *)encryptionKey macKey:(NSString *)macKey { if ((self = [super init])) { _macKeyData = [FBSDKBase64 decodeAsData:macKey]; _encryptionKeyData = [FBSDKBase64 decodeAsData:encryptionKey]; } return self; } - (void)dealloc { FBSDKCryptoBlankData(_encryptionKeyData); FBSDKCryptoBlankData(_macKeyData); } #pragma mark - Public Methods /** * return base64_encode([VERSION 1 byte] + [MAC 32 bytes] + [IV 16 bytes] + [AES256(Padded Data, multiples of 16)] */ - (NSString *)encrypt:(NSData *)plainText additionalDataToSign:(NSData *)additionalDataToSign { NSAssert(plainText.length <= INT_MAX, @""); int plainTextLength = (int)plainText.length; uint8_t numPaddingBytes = kCCBlockSizeAES128 - (plainText.length % kCCBlockSizeAES128); // Pad 1 .. 16 bytes int cipherDataLength = plainTextLength + numPaddingBytes; size_t bufferSize = 1 + CC_SHA256_DIGEST_LENGTH + kCCBlockSizeAES128 + cipherDataLength; int offsetMAC = 1; int offsetIV = offsetMAC + CC_SHA256_DIGEST_LENGTH; int offsetCipherData = offsetIV + kCCBlockSizeAES128; uint8_t *buffer = calloc(bufferSize, sizeof(uint8_t)); buffer[0] = kFBSDK_CRYPTO_CURRENT_VERSION; // First byte is the version number NSData *IV = [[self class] randomBytes:kCCBlockSizeAES128]; memcpy(buffer + offsetIV, IV.bytes, IV.length); memcpy(buffer + offsetCipherData, plainText.bytes, plainTextLength); // Copy input in fbsdkdfl_SecRandomCopyBytes([FBSDKDynamicFrameworkLoader loadkSecRandomDefault], numPaddingBytes, buffer + offsetCipherData + plainTextLength); // Random pad buffer[offsetCipherData + cipherDataLength - 1] = numPaddingBytes; // Record the number of padded bytes at the end size_t numOutputBytes = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, 0, _encryptionKeyData.bytes, kCCKeySizeAES256, IV.bytes, buffer + offsetCipherData, cipherDataLength, buffer + offsetCipherData, cipherDataLength, &numOutputBytes); NSData *mac = [self _macForIV:IV cipherData:[NSData dataWithBytesNoCopy:buffer + offsetCipherData length:cipherDataLength freeWhenDone:NO] additionalDataToSign:additionalDataToSign]; memcpy(buffer + offsetMAC, mac.bytes, CC_SHA256_DIGEST_LENGTH); if (cryptStatus == kCCSuccess) { return [FBSDKBase64 encodeData:[NSData dataWithBytesNoCopy:buffer length:bufferSize]]; } free(buffer); return nil; } - (NSData *)decrypt:(NSString *)base64EncodedCipherText additionalSignedData:(NSData *)additionalSignedData { NSData *cipherText = [FBSDKBase64 decodeAsData:base64EncodedCipherText]; NSAssert(cipherText.length <= INT_MAX, @""); int cipherTextLength = (int)cipherText.length; if (!cipherText || cipherTextLength < 1 + CC_SHA256_DIGEST_LENGTH + kCCBlockSizeAES128) { return nil; } int cipherDataLength = cipherTextLength - (1 + CC_SHA256_DIGEST_LENGTH + kCCBlockSizeAES128); if (cipherDataLength % kCCBlockSizeAES128 != 0) { return nil; } uint8_t *buffer = (uint8_t *)cipherText.bytes; int offsetMAC = 1; int offsetIV = offsetMAC + CC_SHA256_DIGEST_LENGTH; int offsetCipherData = offsetIV + kCCBlockSizeAES128; if (buffer[0] != kFBSDK_CRYPTO_CURRENT_VERSION) { return nil; // Version does not match } NSData *IV = [NSData dataWithBytesNoCopy:buffer + offsetIV length:kCCBlockSizeAES128 freeWhenDone:NO]; NSData *cipherData = [NSData dataWithBytesNoCopy:buffer + offsetCipherData length:cipherDataLength freeWhenDone:NO]; NSData *mac = [self _macForIV:IV cipherData:cipherData additionalDataToSign:additionalSignedData]; NSData *macFromStream = [NSData dataWithBytesNoCopy:buffer + offsetMAC length:CC_SHA256_DIGEST_LENGTH freeWhenDone:NO]; if (![mac isEqualToData:macFromStream]) { return nil; // MAC does not match } uint8_t *outputBuffer = malloc(cipherDataLength); size_t numOutputBytes = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, 0, _encryptionKeyData.bytes, kCCKeySizeAES256, IV.bytes, buffer + offsetCipherData, cipherDataLength, outputBuffer, cipherDataLength, &numOutputBytes); if (cryptStatus == kCCSuccess) { int numPaddingBytes = outputBuffer[cipherDataLength - 1]; if (!(numPaddingBytes >= 1 && numPaddingBytes <= kCCBlockSizeAES128)) { numPaddingBytes = 0; } return [NSData dataWithBytesNoCopy:outputBuffer length:cipherDataLength - numPaddingBytes]; } free(outputBuffer); return nil; } #pragma mark - Helper Methods /** * * [IV 16 bytes] . [length of ciphertext 4 bytes] . [ciphertext] . [length of additionalDataToSign, 4 bytes] . [additionalDataToSign]) * length is written in big-endian */ - (NSData *)_macForIV:(NSData *)IV cipherData:(NSData *)cipherData additionalDataToSign:(NSData *)additionalDataToSign { NSAssert(cipherData.length <= INT_MAX, @""); int cipherDataLength = (int)cipherData.length; NSAssert(additionalDataToSign.length <= INT_MAX, @""); int additionalDataToSignLength = (int)additionalDataToSign.length; size_t macBufferLength = kCCBlockSizeAES128 + 4 + cipherData.length + 4 + additionalDataToSign.length; uint8_t *macBuffer = malloc(macBufferLength); int offsetIV = 0; int offsetCipherTextLength = offsetIV + kCCBlockSizeAES128; int offsetCipherText = offsetCipherTextLength + 4; int offsetAdditionalDataLength = offsetCipherText + cipherDataLength; int offsetAdditionalData = offsetAdditionalDataLength + 4; // [IV 16 bytes] memcpy(macBuffer + offsetIV, IV.bytes, kCCBlockSizeAES128); // [length of ciphertext 4 bytes] FBSDKCryptoWriteIntBigEndian(macBuffer + offsetCipherTextLength, cipherDataLength); // [ciphertext] memcpy(macBuffer + offsetCipherText, cipherData.bytes, cipherDataLength); // [length of additionalDataToSign, 4 bytes] FBSDKCryptoWriteIntBigEndian(macBuffer + offsetAdditionalDataLength, additionalDataToSignLength); memcpy(macBuffer + offsetAdditionalData, additionalDataToSign.bytes, additionalDataToSignLength); uint8_t *result = malloc(CC_SHA256_DIGEST_LENGTH); CCHmac(kCCHmacAlgSHA256, _macKeyData.bytes, _macKeyData.length, macBuffer, macBufferLength, result); free(macBuffer); return [NSData dataWithBytesNoCopy:result length:CC_SHA256_DIGEST_LENGTH]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/FBSDKErrorRecoveryAttempter.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @class FBSDKErrorRecoveryConfiguration; @interface FBSDKErrorRecoveryAttempter : NSObject // can return nil if configuration is not supported. + (instancetype)recoveryAttempterFromConfiguration:(FBSDKErrorRecoveryConfiguration *)configuration; @end @interface FBSDKErrorRecoveryAttempter (Protected) - (void)completeRecovery:(BOOL)didRecover delegate:(id)delegate didRecoverSelector:(SEL)didRecoverSelector contextInfo:(void *)contextInfo; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/FBSDKErrorRecoveryAttempter.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKErrorRecoveryAttempter.h" #import "_FBSDKTemporaryErrorRecoveryAttempter.h" #import "FBSDKErrorRecoveryConfiguration.h" @implementation FBSDKErrorRecoveryAttempter + (instancetype)recoveryAttempterFromConfiguration:(FBSDKErrorRecoveryConfiguration *)configuration { if (configuration.errorCategory == FBSDKGraphRequestErrorCategoryTransient) { return [[_FBSDKTemporaryErrorRecoveryAttempter alloc] init]; } else if (configuration.errorCategory == FBSDKGraphRequestErrorCategoryOther) { return nil; } if ([configuration.recoveryActionName isEqualToString:@"login"]) { Class loginRecoveryAttmpterClass = NSClassFromString(@"_FBSDKLoginRecoveryAttempter"); if (loginRecoveryAttmpterClass) { return [[loginRecoveryAttmpterClass alloc] init]; } } return nil; } - (void)attemptRecoveryFromError:(NSError *)error optionIndex:(NSUInteger)recoveryOptionIndex delegate:(id)delegate didRecoverSelector:(SEL)didRecoverSelector contextInfo:(void *)contextInfo { // should be implemented by subclasses. } @end @implementation FBSDKErrorRecoveryAttempter(Protected) - (void)completeRecovery:(BOOL)didRecover delegate:(id)delegate didRecoverSelector:(SEL)didRecoverSelector contextInfo:(void *)contextInfo { void (*callback)(id, SEL, BOOL, void *) = (void *)[delegate methodForSelector:didRecoverSelector]; (*callback)(delegate, didRecoverSelector, didRecover, contextInfo); } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/_FBSDKTemporaryErrorRecoveryAttempter.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKErrorRecoveryAttempter.h" @interface _FBSDKTemporaryErrorRecoveryAttempter : FBSDKErrorRecoveryAttempter @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/_FBSDKTemporaryErrorRecoveryAttempter.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "_FBSDKTemporaryErrorRecoveryAttempter.h" @implementation _FBSDKTemporaryErrorRecoveryAttempter - (void)attemptRecoveryFromError:(NSError *)error optionIndex:(NSUInteger)recoveryOptionIndex delegate:(id)delegate didRecoverSelector:(SEL)didRecoverSelector contextInfo:(void *)contextInfo { [super completeRecovery:YES delegate:delegate didRecoverSelector:didRecoverSelector contextInfo:contextInfo]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKApplicationDelegate+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import "FBSDKCoreKit+Internal.h" FBSDK_EXTERN NSString *const FBSDKApplicationDidBecomeActiveNotification; @class FBSDKApplicationCall; #if !TARGET_OS_TV typedef void(^FBSDKBridgeAPICallbackBlock)(FBSDKBridgeAPIResponse *response); #endif @interface FBSDKApplicationDelegate () #if !TARGET_OS_TV - (void)openBridgeAPIRequest:(FBSDKBridgeAPIRequest *)request useSafariViewController:(BOOL)useSafariViewController fromViewController:(UIViewController *)fromViewController completionBlock:(FBSDKBridgeAPICallbackBlock)completionBlock; - (void)openURLWithSafariViewController:(NSURL *)url sender:(id)sender fromViewController:(UIViewController *)fromViewController handler:(void(^)(BOOL))handler; - (void)openURL:(NSURL *)url sender:(id)sender handler:(void(^)(BOOL))handler; #endif @property (nonatomic, readonly, getter=isActive) BOOL active; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAudioResourceLoader.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @interface FBSDKAudioResourceLoader : NSObject + (instancetype)sharedLoader; - (BOOL)loadSound:(NSError **)error; - (void)playSound; @end @interface FBSDKAudioResourceLoader (Subclass) + (NSString *)name; + (NSUInteger)version; + (NSData *)data; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAudioResourceLoader.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAudioResourceLoader.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKLogger.h" #import "FBSDKSettings.h" @implementation FBSDKAudioResourceLoader { NSFileManager *_fileManager; NSURL *_fileURL; SystemSoundID _systemSoundID; } #pragma mark - Class Methods + (instancetype)sharedLoader { static NSMutableDictionary *_loaderCache = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _loaderCache = [[NSMutableDictionary alloc] init]; }); NSString *name = [self name]; FBSDKAudioResourceLoader *loader; @synchronized(_loaderCache) { loader = _loaderCache[name]; if (!loader) { loader = [[self alloc] init]; NSError *error = nil; if ([loader loadSound:&error]) { _loaderCache[name] = loader; } else { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors formatString:@"%@ error: %@", self, error]; } } } return loader; } #pragma mark - Object Lifecycle - (instancetype)init { if ((self = [super init])) { _fileManager = [[NSFileManager alloc] init]; } return self; } - (void)dealloc { fbsdkdfl_AudioServicesDisposeSystemSoundID(_systemSoundID); } #pragma mark - Public API - (BOOL)loadSound:(NSError **)errorRef { NSURL *fileURL = [self _fileURL:errorRef]; if (![_fileManager fileExistsAtPath:[fileURL path]]) { NSData *data = [[self class] data]; if (![data writeToURL:fileURL options:NSDataWritingAtomic error:errorRef]) { return NO; } } OSStatus status = fbsdkdfl_AudioServicesCreateSystemSoundID((__bridge CFURLRef)fileURL, &_systemSoundID); return (status == kAudioServicesNoError); } - (void)playSound { if ((_systemSoundID == 0) && ![self loadSound:NULL]) { return; } fbsdkdfl_AudioServicesPlaySystemSound(_systemSoundID); } #pragma mark - Helper Methods - (NSURL *)_fileURL:(NSError **)errorRef { if (_fileURL) { return _fileURL; } NSURL *baseURL = [_fileManager URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:errorRef]; if (!baseURL) { return nil; } NSURL *directoryURL = [baseURL URLByAppendingPathComponent:@"fb_audio" isDirectory:YES]; NSURL *versionURL = [directoryURL URLByAppendingPathComponent:[NSString stringWithFormat:@"%lu", (unsigned long)[[self class] version]] isDirectory:YES]; if (![_fileManager createDirectoryAtURL:versionURL withIntermediateDirectories:YES attributes:nil error:errorRef]) { return nil; } _fileURL = [[versionURL URLByAppendingPathComponent:[[self class] name]] copy]; return _fileURL; } @end @implementation FBSDKAudioResourceLoader (Subclass) #pragma mark - Subclass Methods + (NSString *)name { return nil; } + (NSUInteger)version { return 0; } + (NSData *)data { return nil; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKContainerViewController.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @class FBSDKContainerViewController; @protocol FBSDKContainerViewControllerDelegate - (void)viewControllerDidDisappear:(FBSDKContainerViewController *)viewController animated:(BOOL)animated; @end @interface FBSDKContainerViewController : UIViewController @property (nonatomic, weak) id delegate; - (void)displayChildController:(UIViewController *)childController; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKContainerViewController.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKContainerViewController.h" @implementation FBSDKContainerViewController - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; if ([self.delegate respondsToSelector:@selector(viewControllerDidDisappear:animated:)]) { [self.delegate viewControllerDidDisappear:self animated:animated]; } } - (void)displayChildController:(UIViewController *)childController { [self addChildViewController:childController]; UIView *view = self.view; UIView *childView = childController.view; childView.translatesAutoresizingMaskIntoConstraints = NO; childView.frame = view.frame; [view addSubview:childView]; [view addConstraints: @[ [NSLayoutConstraint constraintWithItem:childView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:childView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:childView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0], [NSLayoutConstraint constraintWithItem:childView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0.0], ]]; [childController didMoveToParentViewController:self]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #if !TARGET_OS_TV #import "BridgeAPI/FBSDKBridgeAPIProtocol.h" #import "BridgeAPI/FBSDKBridgeAPIProtocolType.h" #import "BridgeAPI/FBSDKBridgeAPIRequest.h" #import "BridgeAPI/FBSDKBridgeAPIResponse.h" #import "BridgeAPI/FBSDKURLOpening.h" #import "Cryptography/FBSDKCrypto.h" #import "FBSDKAudioResourceLoader.h" #import "FBSDKContainerViewController.h" #import "FBSDKMonotonicTime.h" #import "FBSDKSystemAccountStoreAdapter.h" #import "FBSDKTriStateBOOL.h" #import "UI/FBSDKCloseIcon.h" #import "UI/FBSDKColor.h" #import "UI/FBSDKMaleSilhouetteIcon.h" #import "UI/FBSDKUIUtility.h" #import "UI/FBSDKViewImpressionTracker.h" #import "WebDialog/FBSDKWebDialog.h" #else #import "Device/FBSDKDeviceButton+Internal.h" #import "Device/FBSDKDeviceDialogView.h" #import "Device/FBSDKDeviceViewControllerBase+Internal.h" #import "Device/FBSDKModalFormPresentationController.h" #endif #import "AppEvents/FBSDKAppEvents+Internal.h" #import "AppEvents/FBSDKAppEventsState.h" #import "AppEvents/FBSDKAppEventsStateManager.h" #import "AppEvents/FBSDKAppEventsUtility.h" #import "AppEvents/FBSDKTimeSpentData.h" #import "Base64/FBSDKBase64.h" #import "ErrorRecovery/FBSDKErrorRecoveryAttempter.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKApplicationDelegate+Internal.h" #import "FBSDKError.h" #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKMath.h" #import "FBSDKTypeUtility.h" #import "Network/FBSDKGraphRequest+Internal.h" #import "Network/FBSDKGraphRequestConnection+Internal.h" #import "Network/FBSDKGraphRequestMetadata.h" #import "ServerConfiguration/FBSDKDialogConfiguration.h" #import "ServerConfiguration/FBSDKServerConfiguration+Internal.h" #import "ServerConfiguration/FBSDKServerConfiguration.h" #import "ServerConfiguration/FBSDKServerConfigurationManager+Internal.h" #import "ServerConfiguration/FBSDKServerConfigurationManager.h" #import "TokenCaching/FBSDKAccessTokenCache.h" #import "TokenCaching/FBSDKAccessTokenCaching.h" #import "TokenCaching/FBSDKKeychainStore.h" #import "TokenCaching/FBSDKKeychainStoreViaBundleID.h" #import "UI/FBSDKButton+Subclass.h" #import "UI/FBSDKIcon.h" #import "UI/FBSDKLogo.h" ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKDynamicFrameworkLoader.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import /*! @class FBSDKDynamicFrameworkLoader @abstract This class provides a way to load constants and methods from Apple Frameworks in a dynamic fashion. It allows the SDK to be just dragged into a project without having to specify additional frameworks to link against. It is an internal class and not to be used by 3rd party developers. As new types are needed, they should be added and strongly typed. */ @interface FBSDKDynamicFrameworkLoader : NSObject #pragma mark - Security Constants /*! @abstract Load the kSecRandomDefault value from the Security Framework @return The kSecRandomDefault value or nil. */ + (SecRandomRef)loadkSecRandomDefault; /*! @abstract Load the kSecAttrAccessible value from the Security Framework @return The kSecAttrAccessible value or nil. */ + (CFTypeRef)loadkSecAttrAccessible; /*! @abstract Load the kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly value from the Security Framework @return The kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly value or nil. */ + (CFTypeRef)loadkSecAttrAccessibleAfterFirstUnlockThisDeviceOnly; /*! @abstract Load the kSecAttrAccount value from the Security Framework @return The kSecAttrAccount value or nil. */ + (CFTypeRef)loadkSecAttrAccount; /*! @abstract Load the kSecAttrService value from the Security Framework @return The kSecAttrService value or nil. */ + (CFTypeRef)loadkSecAttrService; /*! @abstract Load the kSecAttrGeneric value from the Security Framework @return The kSecAttrGeneric value or nil. */ + (CFTypeRef)loadkSecAttrGeneric; /*! @abstract Load the kSecValueData value from the Security Framework @return The kSecValueData value or nil. */ + (CFTypeRef)loadkSecValueData; /*! @abstract Load the kSecClassGenericPassword value from the Security Framework @return The kSecClassGenericPassword value or nil. */ + (CFTypeRef)loadkSecClassGenericPassword; /*! @abstract Load the kSecAttrAccessGroup value from the Security Framework @return The kSecAttrAccessGroup value or nil. */ + (CFTypeRef)loadkSecAttrAccessGroup; /*! @abstract Load the kSecMatchLimitOne value from the Security Framework @return The kSecMatchLimitOne value or nil. */ + (CFTypeRef)loadkSecMatchLimitOne; /*! @abstract Load the kSecMatchLimit value from the Security Framework @return The kSecMatchLimit value or nil. */ + (CFTypeRef)loadkSecMatchLimit; /*! @abstract Load the kSecReturnData value from the Security Framework @return The kSecReturnData value or nil. */ + (CFTypeRef)loadkSecReturnData; /*! @abstract Load the kSecClass value from the Security Framework @return The kSecClass value or nil. */ + (CFTypeRef)loadkSecClass; @end #pragma mark - Security APIs // These are local wrappers around the corresponding methods in Security/SecRandom.h FBSDK_EXTERN int fbsdkdfl_SecRandomCopyBytes(SecRandomRef rnd, size_t count, uint8_t *bytes); // These are local wrappers around Keychain API FBSDK_EXTERN OSStatus fbsdkdfl_SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate); FBSDK_EXTERN OSStatus fbsdkdfl_SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result); FBSDK_EXTERN OSStatus fbsdkdfl_SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result); FBSDK_EXTERN OSStatus fbsdkdfl_SecItemDelete(CFDictionaryRef query); #pragma mark - Social Constants FBSDK_EXTERN NSString *fbsdkdfl_SLServiceTypeFacebook(void); #pragma mark - Social Classes FBSDK_EXTERN Class fbsdkdfl_SLComposeViewControllerClass(void); #pragma mark - QuartzCore Classes FBSDK_EXTERN Class fbsdkdfl_CATransactionClass(void); #pragma mark - QuartzCore APIs // These are local wrappers around the corresponding transform methods from QuartzCore.framework/CATransform3D.h FBSDK_EXTERN CATransform3D fbsdkdfl_CATransform3DMakeScale (CGFloat sx, CGFloat sy, CGFloat sz); FBSDK_EXTERN CATransform3D fbsdkdfl_CATransform3DMakeTranslation (CGFloat tx, CGFloat ty, CGFloat tz); FBSDK_EXTERN CATransform3D fbsdkdfl_CATransform3DConcat (CATransform3D a, CATransform3D b); FBSDK_EXTERN const CATransform3D fbsdkdfl_CATransform3DIdentity; #pragma mark - AudioToolbox APIs // These are local wrappers around the corresponding methods in AudioToolbox/AudioToolbox.h FBSDK_EXTERN OSStatus fbsdkdfl_AudioServicesCreateSystemSoundID(CFURLRef inFileURL, SystemSoundID *outSystemSoundID); FBSDK_EXTERN OSStatus fbsdkdfl_AudioServicesDisposeSystemSoundID(SystemSoundID inSystemSoundID); FBSDK_EXTERN void fbsdkdfl_AudioServicesPlaySystemSound(SystemSoundID inSystemSoundID); #pragma mark - AdSupport Classes FBSDK_EXTERN Class fbsdkdfl_ASIdentifierManagerClass(void); #pragma mark - SafariServices Classes FBSDK_EXTERN Class fbsdkdfl_SFSafariViewControllerClass(void); #pragma mark - Accounts Constants FBSDK_EXTERN NSString *fbsdkdfl_ACFacebookAppIdKey(void); FBSDK_EXTERN NSString *fbsdkdfl_ACFacebookAudienceEveryone(void); FBSDK_EXTERN NSString *fbsdkdfl_ACFacebookAudienceFriends(void); FBSDK_EXTERN NSString *fbsdkdfl_ACFacebookAudienceKey(void); FBSDK_EXTERN NSString *fbsdkdfl_ACFacebookAudienceOnlyMe(void); FBSDK_EXTERN NSString *fbsdkdfl_ACFacebookPermissionsKey(void); #pragma mark - Accounts Classes FBSDK_EXTERN Class fbsdkdfl_ACAccountStoreClass(void); #pragma mark - StoreKit classes FBSDK_EXTERN Class fbsdkdfl_SKPaymentQueueClass(void); FBSDK_EXTERN Class fbsdkdfl_SKProductsRequestClass(void); #pragma mark - AssetsLibrary Classes FBSDK_EXTERN Class fbsdkdfl_ALAssetsLibraryClass(void); #pragma mark - CoreTelephony Classes FBSDK_EXTERN Class fbsdkdfl_CTTelephonyNetworkInfoClass(void); ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKError.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @interface FBSDKError : NSObject + (NSString *)errorDomain; + (BOOL)errorIsNetworkError:(NSError *)error; + (NSError *)errorWithCode:(NSInteger)code message:(NSString *)message; + (NSError *)errorWithCode:(NSInteger)code message:(NSString *)message underlyingError:(NSError *)underlyingError; + (NSError *)errorWithCode:(NSInteger)code userInfo:(NSDictionary *)userInfo message:(NSString *)message underlyingError:(NSError *)underlyingError; + (NSError *)invalidArgumentErrorWithName:(NSString *)name value:(id)value message:(NSString *)message; + (NSError *)invalidArgumentErrorWithName:(NSString *)name value:(id)value message:(NSString *)message underlyingError:(NSError *)underlyingError; + (NSError *)invalidCollectionErrorWithName:(NSString *)name collection:(id)collection item:(id)item message:(NSString *)message; + (NSError *)invalidCollectionErrorWithName:(NSString *)name collection:(id)collection item:(id)item message:(NSString *)message underlyingError:(NSError *)underlyingError; + (NSError *)requiredArgumentErrorWithName:(NSString *)name message:(NSString *)message; + (NSError *)requiredArgumentErrorWithName:(NSString *)name message:(NSString *)message underlyingError:(NSError *)underlyingError; + (NSError *)unknownErrorWithMessage:(NSString *)message; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKError.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKError.h" #import "FBSDKConstants.h" #import "FBSDKInternalUtility.h" #import "FBSDKTypeUtility.h" @implementation FBSDKError #pragma mark - Class Methods + (NSString *)errorDomain { return FBSDKErrorDomain; } + (BOOL)errorIsNetworkError:(NSError *)error { if (error == nil) { return NO; } NSError *innerError = error.userInfo[NSUnderlyingErrorKey]; if ([self errorIsNetworkError:innerError]) { return YES; } switch (error.code) { case NSURLErrorTimedOut: case NSURLErrorCannotFindHost: case NSURLErrorCannotConnectToHost: case NSURLErrorNetworkConnectionLost: case NSURLErrorDNSLookupFailed: case NSURLErrorNotConnectedToInternet: case NSURLErrorInternationalRoamingOff: case NSURLErrorCallIsActive: case NSURLErrorDataNotAllowed: return YES; default: return NO; } } + (NSError *)errorWithCode:(NSInteger)code message:(NSString *)message { return [self errorWithCode:code message:message underlyingError:nil]; } + (NSError *)errorWithCode:(NSInteger)code message:(NSString *)message underlyingError:(NSError *)underlyingError { return [self errorWithCode:code userInfo:nil message:message underlyingError:underlyingError]; } + (NSError *)errorWithCode:(NSInteger)code userInfo:(NSDictionary *)userInfo message:(NSString *)message underlyingError:(NSError *)underlyingError { NSMutableDictionary *fullUserInfo = [[NSMutableDictionary alloc] initWithDictionary:userInfo]; [FBSDKInternalUtility dictionary:fullUserInfo setObject:message forKey:FBSDKErrorDeveloperMessageKey]; [FBSDKInternalUtility dictionary:fullUserInfo setObject:underlyingError forKey:NSUnderlyingErrorKey]; userInfo = ([fullUserInfo count] ? [fullUserInfo copy] : nil); return [[NSError alloc] initWithDomain:[self errorDomain] code:code userInfo:userInfo]; } + (NSError *)invalidArgumentErrorWithName:(NSString *)name value:(id)value message:(NSString *)message { return [self invalidArgumentErrorWithName:name value:value message:message underlyingError:nil]; } + (NSError *)invalidArgumentErrorWithName:(NSString *)name value:(id)value message:(NSString *)message underlyingError:(NSError *)underlyingError { if (!message) { message = [[NSString alloc] initWithFormat:@"Invalid value for %@: %@", name, value]; } NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:userInfo setObject:name forKey:FBSDKErrorArgumentNameKey]; [FBSDKInternalUtility dictionary:userInfo setObject:value forKey:FBSDKErrorArgumentValueKey]; return [self errorWithCode:FBSDKInvalidArgumentErrorCode userInfo:userInfo message:message underlyingError:underlyingError]; } + (NSError *)invalidCollectionErrorWithName:(NSString *)name collection:(id)collection item:(id)item message:(NSString *)message { return [self invalidCollectionErrorWithName:name collection:collection item:item message:message underlyingError:nil]; } + (NSError *)invalidCollectionErrorWithName:(NSString *)name collection:(id)collection item:(id)item message:(NSString *)message underlyingError:(NSError *)underlyingError { if (!message) { message = [[NSString alloc] initWithFormat:@"Invalid item (%@) found in collection for %@: %@", item, name, collection]; } NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:userInfo setObject:name forKey:FBSDKErrorArgumentNameKey]; [FBSDKInternalUtility dictionary:userInfo setObject:item forKey:FBSDKErrorArgumentValueKey]; [FBSDKInternalUtility dictionary:userInfo setObject:collection forKey:FBSDKErrorArgumentCollectionKey]; return [self errorWithCode:FBSDKInvalidArgumentErrorCode userInfo:userInfo message:message underlyingError:underlyingError]; } + (NSError *)requiredArgumentErrorWithName:(NSString *)name message:(NSString *)message { return [self requiredArgumentErrorWithName:name message:message underlyingError:nil]; } + (NSError *)requiredArgumentErrorWithName:(NSString *)name message:(NSString *)message underlyingError:(NSError *)underlyingError { if (!message) { message = [[NSString alloc] initWithFormat:@"Value for %@ is required.", name]; } return [self invalidArgumentErrorWithName:name value:nil message:message underlyingError:underlyingError]; } + (NSError *)unknownErrorWithMessage:(NSString *)message { return [self errorWithCode:FBSDKUnknownErrorCode userInfo:nil message:message underlyingError:nil]; } #pragma mark - Object Lifecycle - (instancetype)init { FBSDK_NO_DESIGNATED_INITIALIZER(); return nil; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #define FBSDK_CANOPENURL_FACEBOOK @"fbauth2" #define FBSDK_CANOPENURL_FBAPI @"fbapi" #define FBSDK_CANOPENURL_MESSENGER @"fb-messenger-api" #define FBSDK_CANOPENURL_SHARE_EXTENSION @"fbshareextension" typedef NS_ENUM(int32_t, FBSDKUIKitVersion) { FBSDKUIKitVersion_6_0 = 0x0944, FBSDKUIKitVersion_6_1 = 0x094C, FBSDKUIKitVersion_7_0 = 0x0B57, FBSDKUIKitVersion_7_1 = 0x0B77, FBSDKUIKitVersion_8_0 = 0x0CF6, }; @interface FBSDKInternalUtility : NSObject /*! @abstract Constructs the scheme for apps that come to the current app through the bridge. */ + (NSString *)appURLScheme; /*! @abstract Constructs an URL for the current app. @param host The host for the URL. @param path The path for the URL. @param queryParameters The query parameters for the URL. This will be converted into a query string. @param errorRef If an error occurs, upon return contains an NSError object that describes the problem. @return The app URL. */ + (NSURL *)appURLWithHost:(NSString *)host path:(NSString *)path queryParameters:(NSDictionary *)queryParameters error:(NSError *__autoreleasing *)errorRef; /*! @abstract Parses an FB url's query params (and potentially fragment) into a dictionary. @param url The FB url. @return A dictionary with the key/value pairs. */ + (NSDictionary *)dictionaryFromFBURL:(NSURL *)url; /*! @abstract Adds an object to an array if it is not nil. @param array The array to add the object to. @param object The object to add to the array. */ + (void)array:(NSMutableArray *)array addObject:(id)object; /*! @abstract Returns bundle for returning localized strings @discussion We assume a convention of a bundle named FBSDKStrings.bundle, otherwise we return the main bundle. */ + (NSBundle *)bundleForStrings; /*! @abstract Converts simple value types to the string equivalent for serializing to a request query or body. @param value The value to be converted. @return The value that may have been converted if able (otherwise the input param). */ + (id)convertRequestValue:(id)value; /*! @abstract Gets the milliseconds since the Unix Epoch. @discussion Changes in the system clock will affect this value. @return The number of milliseconds since the Unix Epoch. */ + (unsigned long)currentTimeInMilliseconds; /*! @abstract Sets an object for a key in a dictionary if it is not nil. @param dictionary The dictionary to set the value for. @param object The value to set after serializing to JSON. @param key The key to set the value for. @param errorRef If an error occurs, upon return contains an NSError object that describes the problem. @return NO if an error occurred while serializing the object, otherwise YES. */ + (BOOL)dictionary:(NSMutableDictionary *)dictionary setJSONStringForObject:(id)object forKey:(id)key error:(NSError *__autoreleasing *)errorRef; /*! @abstract Sets an object for a key in a dictionary if it is not nil. @param dictionary The dictionary to set the value for. @param object The value to set. @param key The key to set the value for. */ + (void)dictionary:(NSMutableDictionary *)dictionary setObject:(id)object forKey:(id)key; /*! @abstract Constructs a Facebook URL. @param hostPrefix The prefix for the host, such as 'm', 'graph', etc. @param path The path for the URL. This may or may not include a version. @param queryParameters The query parameters for the URL. This will be converted into a query string. @param errorRef If an error occurs, upon return contains an NSError object that describes the problem. @return The Facebook URL. */ + (NSURL *)facebookURLWithHostPrefix:(NSString *)hostPrefix path:(NSString *)path queryParameters:(NSDictionary *)queryParameters error:(NSError *__autoreleasing *)errorRef; /*! @abstract Constructs a Facebook URL. @param hostPrefix The prefix for the host, such as 'm', 'graph', etc. @param path The path for the URL. This may or may not include a version. @param queryParameters The query parameters for the URL. This will be converted into a query string. @param defaultVersion A version to add to the URL if none is found in the path. @param errorRef If an error occurs, upon return contains an NSError object that describes the problem. @return The Facebook URL. */ + (NSURL *)facebookURLWithHostPrefix:(NSString *)hostPrefix path:(NSString *)path queryParameters:(NSDictionary *)queryParameters defaultVersion:(NSString *)defaultVersion error:(NSError *__autoreleasing *)errorRef; /*! @abstract Tests whether the supplied URL is a valid URL for opening in the browser. @param URL The URL to test. @return YES if the URL refers to an http or https resource, otherwise NO. */ + (BOOL)isBrowserURL:(NSURL *)URL; /*! @abstract Tests whether the supplied bundle identifier references a Facebook app. @param bundleIdentifier The bundle identifier to test. @return YES if the bundle identifier refers to a Facebook app, otherwise NO. */ + (BOOL)isFacebookBundleIdentifier:(NSString *)bundleIdentifier; /*! @abstract Tests whether the operating system is at least the specified version. @param version The version to test against. @return YES if the operating system is greater than or equal to the specified version, otherwise NO. */ + (BOOL)isOSRunTimeVersionAtLeast:(NSOperatingSystemVersion)version; /*! @abstract Tests whether the supplied bundle identifier references the Safari app. @param bundleIdentifier The bundle identifier to test. @return YES if the bundle identifier refers to the Safari app, otherwise NO. */ + (BOOL)isSafariBundleIdentifier:(NSString *)bundleIdentifier; /*! @abstract Tests whether the UIKit version that the current app was linked to is at least the specified version. @param version The version to test against. @return YES if the linked UIKit version is greater than or equal to the specified version, otherwise NO. */ + (BOOL)isUIKitLinkTimeVersionAtLeast:(FBSDKUIKitVersion)version; /*! @abstract Tests whether the UIKit version in the runtime is at least the specified version. @param version The version to test against. @return YES if the runtime UIKit version is greater than or equal to the specified version, otherwise NO. */ + (BOOL)isUIKitRunTimeVersionAtLeast:(FBSDKUIKitVersion)version; /*! @abstract Converts an object into a JSON string. @param object The object to convert to JSON. @param errorRef If an error occurs, upon return contains an NSError object that describes the problem. @param invalidObjectHandler Handles objects that are invalid, returning a replacement value or nil to ignore. @return A JSON string or nil if the object cannot be converted to JSON. */ + (NSString *)JSONStringForObject:(id)object error:(NSError *__autoreleasing *)errorRef invalidObjectHandler:(id(^)(id object, BOOL *stop))invalidObjectHandler; /*! @abstract Checks equality between 2 objects. @discussion Checks for pointer equality, nils, isEqual:. @param object The first object to compare. @param other The second object to compare. @result YES if the objects are equal, otherwise NO. */ + (BOOL)object:(id)object isEqualToObject:(id)other; /*! @abstract Converts a JSON string into an object @param string The JSON string to convert. @param errorRef If an error occurs, upon return contains an NSError object that describes the problem. @return An NSDictionary, NSArray, NSString or NSNumber containing the object representation, or nil if the string cannot be converted. */ + (id)objectForJSONString:(NSString *)string error:(NSError *__autoreleasing *)errorRef; /*! @abstract The version of the operating system on which the process is executing. */ + (NSOperatingSystemVersion)operatingSystemVersion; /*! @abstract Constructs a query string from a dictionary. @param dictionary The dictionary with key/value pairs for the query string. @param errorRef If an error occurs, upon return contains an NSError object that describes the problem. @param invalidObjectHandler Handles objects that are invalid, returning a replacement value or nil to ignore. @result Query string representation of the parameters. */ + (NSString *)queryStringWithDictionary:(NSDictionary *)dictionary error:(NSError *__autoreleasing *)errorRef invalidObjectHandler:(id(^)(id object, BOOL *stop))invalidObjectHandler; /*! @abstract Tests whether the orientation should be manually adjusted for views outside of the root view controller. @discussion With the legacy layout the developer must worry about device orientation when working with views outside of the window's root view controller and apply the correct rotation transform and/or swap a view's width and height values. If the application was linked with UIKit on iOS 7 or earlier or the application is running on iOS 7 or earlier then we need to use the legacy layout code. Otherwise if the application was linked with UIKit on iOS 8 or later and the application is running on iOS 8 or later, UIKit handles all of the rotation complexity and the origin is always in the top-left and no rotation transform is necessary. @return YES if if the orientation must be manually adjusted, otherwise NO. */ + (BOOL)shouldManuallyAdjustOrientation; /*! @abstract Constructs an NSURL. @param scheme The scheme for the URL. @param host The host for the URL. @param path The path for the URL. @param queryParameters The query parameters for the URL. This will be converted into a query string. @param errorRef If an error occurs, upon return contains an NSError object that describes the problem. @return The URL. */ + (NSURL *)URLWithScheme:(NSString *)scheme host:(NSString *)host path:(NSString *)path queryParameters:(NSDictionary *)queryParameters error:(NSError *__autoreleasing *)errorRef; /*! * @abstract Deletes all the cookies in the NSHTTPCookieStorage for Facebook web dialogs */ + (void)deleteFacebookCookies; /*! @abstract Extracts permissions from a response fetched from me/permissions @param responseObject the response @param grantedPermissions the set to add granted permissions to @param declinedPermissions the set to add declined permissions to. */ + (void)extractPermissionsFromResponse:(NSDictionary *)responseObject grantedPermissions:(NSMutableSet *)grantedPermissions declinedPermissions:(NSMutableSet *)declinedPermissions; /*! @abstract Registers a transient object so that it will not be deallocated until unregistered @param object The transient object */ + (void)registerTransientObject:(id)object; /*! @abstract Unregisters a transient object that was previously registered with registerTransientObject: @param object The transient object */ + (void)unregisterTransientObject:(__weak id)object; /*! @abstract validates that the app ID is non-nil, throws an NSException if nil. */ + (void)validateAppID; /** Validates that the client access token is non-nil, otherwise - throws an NSException otherwise. Returns the composed client access token. */ + (NSString *)validateRequiredClientAccessToken; /*! @abstract validates that the right URL schemes are registered, throws an NSException if not. */ + (void)validateURLSchemes; /*! @abstract validates that Facebook reserved URL schemes are not registered, throws an NSException if they are. */ + (void)validateFacebookReservedURLSchemes; /*! @abstract Attempts to find the first UIViewController in the view's responder chain. Returns nil if not found. */ + (UIViewController *)viewControllerForView:(UIView *)view; /*! @abstract returns true if the url scheme is registered in the CFBundleURLTypes */ + (BOOL)isRegisteredURLScheme:(NSString *)urlScheme; /*! @abstract returns currently displayed top view controller. */ + (UIViewController *)topMostViewController; /*! @abstract Converts NSData to a hexadecimal UTF8 String. */ + (NSString *)hexadecimalStringFromData:(NSData *)data; /* @abstract Checks if the permission is a publish permission. */ + (BOOL)isPublishPermission:(NSString *)permission; /* @abstract Checks if the set of permissions are all read permissions. */ + (BOOL)areAllPermissionsReadPermissions:(NSSet *)permissions; /* @abstract Checks if the set of permissions are all publish permissions. */ + (BOOL)areAllPermissionsPublishPermissions:(NSSet *)permissions; #pragma mark - FB Apps Installed + (BOOL)isFacebookAppInstalled; + (BOOL)isMessengerAppInstalled; + (void)checkRegisteredCanOpenURLScheme:(NSString *)urlScheme; + (BOOL)isRegisteredCanOpenURLScheme:(NSString *)urlScheme; #define FBSDKConditionalLog(condition, loggingBehavior, desc, ...) \ { \ if (!(condition)) { \ NSString *msg = [NSString stringWithFormat:(desc), ##__VA_ARGS__]; \ [FBSDKLogger singleShotLogEntry:loggingBehavior logEntry:msg]; \ } \ } #define FB_BASE_URL @"facebook.com" + (Class)resolveBoltsClassWithName:(NSString *)className; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKInternalUtility.h" #import #import #import "FBSDKCoreKit+Internal.h" #import "FBSDKError.h" #import "FBSDKMacros.h" #import "FBSDKSettings.h" #import "FBSDKUtility.h" typedef NS_ENUM(NSUInteger, FBSDKInternalUtilityVersionMask) { FBSDKInternalUtilityMajorVersionMask = 0xFFFF0000, //FBSDKInternalUtilityMinorVersionMask = 0x0000FF00, // unused //FBSDKInternalUtilityPatchVersionMask = 0x000000FF, // unused }; typedef NS_ENUM(NSUInteger, FBSDKInternalUtilityVersionShift) { FBSDKInternalUtilityMajorVersionShift = 16, //FBSDKInternalUtilityMinorVersionShift = 8, // unused //FBSDKInternalUtilityPatchVersionShift = 0, // unused }; @implementation FBSDKInternalUtility #pragma mark - Class Methods + (NSString *)appURLScheme { NSString *appID = ([FBSDKSettings appID] ?: @""); NSString *suffix = ([FBSDKSettings appURLSchemeSuffix] ?: @""); return [[NSString alloc] initWithFormat: @"fb%@%@", appID, suffix]; } + (NSURL *)appURLWithHost:(NSString *)host path:(NSString *)path queryParameters:(NSDictionary *)queryParameters error:(NSError *__autoreleasing *)errorRef { return [self URLWithScheme:[self appURLScheme] host:host path:path queryParameters:queryParameters error:errorRef]; } + (NSDictionary *)dictionaryFromFBURL:(NSURL *)url { // version 3.2.3 of the Facebook app encodes the parameters in the query but // version 3.3 and above encode the parameters in the fragment; // merge them together with fragment taking priority. NSMutableDictionary *params = [NSMutableDictionary dictionary]; [params addEntriesFromDictionary:[FBSDKUtility dictionaryWithQueryString:url.query]]; // Only get the params from the fragment if it has authorize as the host if ([url.host isEqualToString:@"authorize"]) { [params addEntriesFromDictionary:[FBSDKUtility dictionaryWithQueryString:url.fragment]]; } return params; } + (void)array:(NSMutableArray *)array addObject:(id)object { if (object) { [array addObject:object]; } } + (NSBundle *)bundleForStrings { static NSBundle *bundle; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSString *stringsBundlePath = [[NSBundle bundleForClass:[FBSDKApplicationDelegate class]] pathForResource:@"FacebookSDKStrings" ofType:@"bundle"]; bundle = [NSBundle bundleWithPath:stringsBundlePath] ?: [NSBundle mainBundle]; }); return bundle; } + (id)convertRequestValue:(id)value { if ([value isKindOfClass:[NSNumber class]]) { value = [(NSNumber *)value stringValue]; } else if ([value isKindOfClass:[NSURL class]]) { value = [(NSURL *)value absoluteString]; } return value; } + (unsigned long)currentTimeInMilliseconds { struct timeval time; gettimeofday(&time, NULL); return (time.tv_sec * 1000) + (time.tv_usec / 1000); } + (BOOL)dictionary:(NSMutableDictionary *)dictionary setJSONStringForObject:(id)object forKey:(id)key error:(NSError *__autoreleasing *)errorRef { if (!object || !key) { return YES; } NSString *JSONString = [self JSONStringForObject:object error:errorRef invalidObjectHandler:NULL]; if (!JSONString) { return NO; } [self dictionary:dictionary setObject:JSONString forKey:key]; return YES; } + (void)dictionary:(NSMutableDictionary *)dictionary setObject:(id)object forKey:(id)key { if (object && key) { [dictionary setObject:object forKey:key]; } } + (void)extractPermissionsFromResponse:(NSDictionary *)responseObject grantedPermissions:(NSMutableSet *)grantedPermissions declinedPermissions:(NSMutableSet *)declinedPermissions { NSArray *resultData = responseObject[@"data"]; if (resultData.count > 0) { for (NSDictionary *permissionsDictionary in resultData) { NSString *permissionName = permissionsDictionary[@"permission"]; NSString *status = permissionsDictionary[@"status"]; if ([status isEqualToString:@"granted"]) { [grantedPermissions addObject:permissionName]; } else if ([status isEqualToString:@"declined"]) { [declinedPermissions addObject:permissionName]; } } } } + (NSURL *)facebookURLWithHostPrefix:(NSString *)hostPrefix path:(NSString *)path queryParameters:(NSDictionary *)queryParameters error:(NSError *__autoreleasing *)errorRef { return [self facebookURLWithHostPrefix:hostPrefix path:path queryParameters:queryParameters defaultVersion:nil error:errorRef]; } + (NSURL *)facebookURLWithHostPrefix:(NSString *)hostPrefix path:(NSString *)path queryParameters:(NSDictionary *)queryParameters defaultVersion:(NSString *)defaultVersion error:(NSError *__autoreleasing *)errorRef { if ([hostPrefix length] && ![hostPrefix hasSuffix:@"."]) { hostPrefix = [hostPrefix stringByAppendingString:@"."]; } NSString *host = @"facebook.com"; NSString *domainPart = [FBSDKSettings facebookDomainPart]; if ([domainPart length]) { host = [[NSString alloc] initWithFormat:@"%@.%@", domainPart, host]; } host = [NSString stringWithFormat:@"%@%@", hostPrefix ?: @"", host ?: @""]; NSString *version = defaultVersion ?: [FBSDKSettings graphAPIVersion]; if ([version length]) { version = [@"/" stringByAppendingString:version]; } if ([path length]) { NSScanner *versionScanner = [[NSScanner alloc] initWithString:path]; if ([versionScanner scanString:@"/v" intoString:NULL] && [versionScanner scanInteger:NULL] && [versionScanner scanString:@"." intoString:NULL] && [versionScanner scanInteger:NULL]) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:[NSString stringWithFormat:@"Invalid Graph API version:%@, assuming %@ instead", version, [FBSDKSettings graphAPIVersion]]]; version = nil; } if (![path hasPrefix:@"/"]) { path = [@"/" stringByAppendingString:path]; } } path = [[NSString alloc] initWithFormat:@"%@%@", version ?: @"", path ?: @""]; return [self URLWithScheme:@"https" host:host path:path queryParameters:queryParameters error:errorRef]; } + (BOOL)isBrowserURL:(NSURL *)URL { NSString *scheme = [URL.scheme lowercaseString]; return ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]); } + (BOOL)isFacebookBundleIdentifier:(NSString *)bundleIdentifier { return ([bundleIdentifier hasPrefix:@"com.facebook."] || [bundleIdentifier hasPrefix:@".com.facebook."]); } + (BOOL)isOSRunTimeVersionAtLeast:(NSOperatingSystemVersion)version { return ([self _compareOperatingSystemVersion:[self operatingSystemVersion] toVersion:version] != NSOrderedAscending); } + (BOOL)isSafariBundleIdentifier:(NSString *)bundleIdentifier { return ([bundleIdentifier isEqualToString:@"com.apple.mobilesafari"] || [bundleIdentifier isEqualToString:@"com.apple.SafariViewService"]); } + (BOOL)isUIKitLinkTimeVersionAtLeast:(FBSDKUIKitVersion)version { static int32_t linkTimeMajorVersion; static dispatch_once_t getVersionOnce; dispatch_once(&getVersionOnce, ^{ int32_t linkTimeVersion = NSVersionOfLinkTimeLibrary("UIKit"); linkTimeMajorVersion = ((MAX(linkTimeVersion, 0) & FBSDKInternalUtilityMajorVersionMask) >> FBSDKInternalUtilityMajorVersionShift); }); return (version <= linkTimeMajorVersion); } + (BOOL)isUIKitRunTimeVersionAtLeast:(FBSDKUIKitVersion)version { static int32_t runTimeMajorVersion; static dispatch_once_t getVersionOnce; dispatch_once(&getVersionOnce, ^{ int32_t runTimeVersion = NSVersionOfRunTimeLibrary("UIKit"); runTimeMajorVersion = ((MAX(runTimeVersion, 0) & FBSDKInternalUtilityMajorVersionMask) >> FBSDKInternalUtilityMajorVersionShift); }); return (version <= runTimeMajorVersion); } + (NSString *)JSONStringForObject:(id)object error:(NSError *__autoreleasing *)errorRef invalidObjectHandler:(id(^)(id object, BOOL *stop))invalidObjectHandler { if (invalidObjectHandler || ![NSJSONSerialization isValidJSONObject:object]) { object = [self _convertObjectToJSONObject:object invalidObjectHandler:invalidObjectHandler stop:NULL]; if (![NSJSONSerialization isValidJSONObject:object]) { if (errorRef != NULL) { *errorRef = [FBSDKError invalidArgumentErrorWithName:@"object" value:object message:@"Invalid object for JSON serialization."]; } return nil; } } NSData *data = [NSJSONSerialization dataWithJSONObject:object options:0 error:errorRef]; if (!data) { return nil; } return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; } + (BOOL)object:(id)object isEqualToObject:(id)other; { if (object == other) { return YES; } if (!object || !other) { return NO; } return [object isEqual:other]; } + (id)objectForJSONString:(NSString *)string error:(NSError *__autoreleasing *)errorRef { NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; if (!data) { if (errorRef != NULL) { *errorRef = nil; } return nil; } return [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:errorRef]; } + (NSOperatingSystemVersion)operatingSystemVersion { static NSOperatingSystemVersion operatingSystemVersion = { .majorVersion = 0, .minorVersion = 0, .patchVersion = 0, }; static dispatch_once_t getVersionOnce; dispatch_once(&getVersionOnce, ^{ if ([NSProcessInfo instancesRespondToSelector:@selector(operatingSystemVersion)]) { operatingSystemVersion = [NSProcessInfo processInfo].operatingSystemVersion; } else { NSArray *components = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."]; switch (components.count) { default: case 3: operatingSystemVersion.patchVersion = [components[2] integerValue]; // fall through case 2: operatingSystemVersion.minorVersion = [components[1] integerValue]; // fall through case 1: operatingSystemVersion.majorVersion = [components[0] integerValue]; break; case 0: operatingSystemVersion.majorVersion = ([self isUIKitLinkTimeVersionAtLeast:FBSDKUIKitVersion_7_0] ? 7 : 6); break; } } }); return operatingSystemVersion; } + (NSString *)queryStringWithDictionary:(NSDictionary *)dictionary error:(NSError *__autoreleasing *)errorRef invalidObjectHandler:(id(^)(id object, BOOL *stop))invalidObjectHandler { NSMutableString *queryString = [[NSMutableString alloc] init]; __block BOOL hasParameters = NO; if (dictionary) { NSMutableArray *keys = [[dictionary allKeys] mutableCopy]; // remove non-string keys, as they are not valid [keys filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { return [evaluatedObject isKindOfClass:[NSString class]]; }]]; // sort the keys so that the query string order is deterministic [keys sortUsingSelector:@selector(compare:)]; BOOL stop = NO; for (NSString *key in keys) { id value = [self convertRequestValue:dictionary[key]]; if ([value isKindOfClass:[NSString class]]) { value = [FBSDKUtility URLEncode:value]; } if (invalidObjectHandler && ![value isKindOfClass:[NSString class]]) { value = invalidObjectHandler(value, &stop); if (stop) { break; } } if (value) { if (hasParameters) { [queryString appendString:@"&"]; } [queryString appendFormat:@"%@=%@", key, value]; hasParameters = YES; } } } if (errorRef != NULL) { *errorRef = nil; } return ([queryString length] ? [queryString copy] : nil); } + (BOOL)shouldManuallyAdjustOrientation { return (![self isUIKitLinkTimeVersionAtLeast:FBSDKUIKitVersion_8_0] || ![self isUIKitRunTimeVersionAtLeast:FBSDKUIKitVersion_8_0]); } + (NSURL *)URLWithScheme:(NSString *)scheme host:(NSString *)host path:(NSString *)path queryParameters:(NSDictionary *)queryParameters error:(NSError *__autoreleasing *)errorRef { if (![path hasPrefix:@"/"]) { path = [@"/" stringByAppendingString:path ?: @""]; } NSString *queryString = nil; if ([queryParameters count]) { NSError *queryStringError; queryString = [@"?" stringByAppendingString:[FBSDKUtility queryStringWithDictionary:queryParameters error:&queryStringError]]; if (!queryString) { if (errorRef != NULL) { *errorRef = [FBSDKError invalidArgumentErrorWithName:@"queryParameters" value:queryParameters message:nil underlyingError:queryStringError]; } return nil; } } NSURL *URL = [[NSURL alloc] initWithString:[NSString stringWithFormat: @"%@://%@%@%@", scheme ?: @"", host ?: @"", path ?: @"", queryString ?: @""]]; if (errorRef != NULL) { if (URL) { *errorRef = nil; } else { *errorRef = [FBSDKError unknownErrorWithMessage:@"Unknown error building URL."]; } } return URL; } + (void)deleteFacebookCookies { NSHTTPCookieStorage *cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage]; NSArray *facebookCookies = [cookies cookiesForURL:[self facebookURLWithHostPrefix:@"m." path:@"/dialog/" queryParameters:nil error:NULL]]; for (NSHTTPCookie *cookie in facebookCookies) { [cookies deleteCookie:cookie]; } } static NSMapTable *_transientObjects; + (void)registerTransientObject:(id)object { NSAssert([NSThread isMainThread], @"Must be called from the main thread!"); if (!_transientObjects) { _transientObjects = [[NSMapTable alloc] init]; } NSUInteger count = [(NSNumber *)[_transientObjects objectForKey:object] unsignedIntegerValue]; [_transientObjects setObject:@(count + 1) forKey:object]; } + (void)unregisterTransientObject:(__weak id)object { if (!object) { return; } NSAssert([NSThread isMainThread], @"Must be called from the main thread!"); NSUInteger count = [(NSNumber *)[_transientObjects objectForKey:object] unsignedIntegerValue]; if (count == 1) { [_transientObjects removeObjectForKey:object]; } else if (count != 0) { [_transientObjects setObject:@(count - 1) forKey:object]; } else { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors formatString:@"unregisterTransientObject:%@ count is 0. This may indicate a bug in the FBSDK. Please" " file a report to developers.facebook.com/bugs if you encounter any problems. Thanks!", [object class]]; } } + (UIViewController *)viewControllerForView:(UIView *)view { UIResponder *responder = view.nextResponder; while (responder) { if ([responder isKindOfClass:[UIViewController class]]) { return (UIViewController *)responder; } responder = responder.nextResponder; } return nil; } #pragma mark - FB Apps Installed + (BOOL)isFacebookAppInstalled { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ [FBSDKInternalUtility checkRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_FACEBOOK]; }); NSURLComponents *components = [[NSURLComponents alloc] init]; components.scheme = FBSDK_CANOPENURL_FACEBOOK; components.path = @"/"; return [[UIApplication sharedApplication] canOpenURL:components.URL]; } + (BOOL)isMessengerAppInstalled { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ [FBSDKInternalUtility checkRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_MESSENGER]; }); NSURLComponents *components = [[NSURLComponents alloc] init]; components.scheme = FBSDK_CANOPENURL_MESSENGER; components.path = @"/"; return [[UIApplication sharedApplication] canOpenURL:components.URL]; } #pragma mark - Object Lifecycle - (instancetype)init { FBSDK_NO_DESIGNATED_INITIALIZER(); return nil; } #pragma mark - Helper Methods + (NSComparisonResult)_compareOperatingSystemVersion:(NSOperatingSystemVersion)version1 toVersion:(NSOperatingSystemVersion)version2 { if (version1.majorVersion < version2.majorVersion) { return NSOrderedAscending; } else if (version1.majorVersion > version2.majorVersion) { return NSOrderedDescending; } else if (version1.minorVersion < version2.minorVersion) { return NSOrderedAscending; } else if (version1.minorVersion > version2.minorVersion) { return NSOrderedDescending; } else if (version1.patchVersion < version2.patchVersion) { return NSOrderedAscending; } else if (version1.patchVersion > version2.patchVersion) { return NSOrderedDescending; } else { return NSOrderedSame; } } + (id)_convertObjectToJSONObject:(id)object invalidObjectHandler:(id(^)(id object, BOOL *stop))invalidObjectHandler stop:(BOOL *)stopRef { __block BOOL stop = NO; if ([object isKindOfClass:[NSString class]] || [object isKindOfClass:[NSNumber class]]) { // good to go, keep the object } else if ([object isKindOfClass:[NSURL class]]) { object = [(NSURL *)object absoluteString]; } else if ([object isKindOfClass:[NSDictionary class]]) { NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; [(NSDictionary *)object enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *dictionaryStop) { [self dictionary:dictionary setObject:[self _convertObjectToJSONObject:obj invalidObjectHandler:invalidObjectHandler stop:&stop] forKey:[FBSDKTypeUtility stringValue:key]]; if (stop) { *dictionaryStop = YES; } }]; object = dictionary; } else if ([object isKindOfClass:[NSArray class]]) { NSMutableArray *array = [[NSMutableArray alloc] init]; for (id obj in (NSArray *)object) { id convertedObj = [self _convertObjectToJSONObject:obj invalidObjectHandler:invalidObjectHandler stop:&stop]; [self array:array addObject:convertedObj]; if (stop) { break; } } object = array; } else { object = invalidObjectHandler(object, stopRef); } if (stopRef != NULL) { *stopRef = stop; } return object; } + (void)validateAppID { if (![FBSDKSettings appID]) { NSString *reason = @"App ID not found. Add a string value with your app ID for the key " @"FacebookAppID to the Info.plist or call [FBSDKSettings setAppID:]."; @throw [NSException exceptionWithName:@"InvalidOperationException" reason:reason userInfo:nil]; } } + (NSString *)validateRequiredClientAccessToken { if (![FBSDKSettings clientToken]) { NSString *reason = @"ClientToken is required to be set for this operation. " @"Set the FacebookClientToken in the Info.plist or call [FBSDKSettings setClientToken:]. " @"You can find your client token in your App Settings -> Advanced."; @throw [NSException exceptionWithName:@"InvalidOperationException" reason:reason userInfo:nil]; } return [NSString stringWithFormat:@"%@|%@", [FBSDKSettings appID], [FBSDKSettings clientToken]]; } + (void)validateURLSchemes { [self validateAppID]; NSString *defaultUrlScheme = [NSString stringWithFormat:@"fb%@%@", [FBSDKSettings appID], [FBSDKSettings appURLSchemeSuffix] ?: @""]; if (![self isRegisteredURLScheme:defaultUrlScheme]) { NSString *reason = [NSString stringWithFormat:@"%@ is not registered as a URL scheme. Please add it in your Info.plist", defaultUrlScheme]; @throw [NSException exceptionWithName:@"InvalidOperationException" reason:reason userInfo:nil]; } } + (void)validateFacebookReservedURLSchemes { for (NSString * fbUrlScheme in @[FBSDK_CANOPENURL_FACEBOOK, FBSDK_CANOPENURL_MESSENGER, FBSDK_CANOPENURL_FBAPI, FBSDK_CANOPENURL_SHARE_EXTENSION]) { if ([self isRegisteredURLScheme:fbUrlScheme]) { NSString *reason = [NSString stringWithFormat:@"%@ is registered as a URL scheme. Please move the entry from CFBundleURLSchemes in your Info.plist to LSApplicationQueriesSchemes. If you are trying to resolve \"canOpenURL: failed\" warnings, those only indicate that the Facebook app is not installed on your device or simulator and can be ignored.", fbUrlScheme]; @throw [NSException exceptionWithName:@"InvalidOperationException" reason:reason userInfo:nil]; } } } + (UIViewController *)topMostViewController { UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController; while (topController.presentedViewController) { topController = topController.presentedViewController; } return topController; } + (NSString *)hexadecimalStringFromData:(NSData *)data { NSUInteger dataLength = data.length; if (dataLength == 0) { return nil; } const unsigned char *dataBuffer = data.bytes; NSMutableString *hexString = [NSMutableString stringWithCapacity:(dataLength * 2)]; for (int i = 0; i < dataLength; ++i) { [hexString appendFormat:@"%02x", dataBuffer[i]]; } return [hexString copy]; } + (BOOL)isRegisteredURLScheme:(NSString *)urlScheme { static dispatch_once_t fetchBundleOnce; static NSArray *urlTypes = nil; dispatch_once(&fetchBundleOnce, ^{ urlTypes = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"CFBundleURLTypes"]; }); for (NSDictionary *urlType in urlTypes) { NSArray *urlSchemes = [urlType valueForKey:@"CFBundleURLSchemes"]; if ([urlSchemes containsObject:urlScheme]) { return YES; } } return NO; } + (void)checkRegisteredCanOpenURLScheme:(NSString *)urlScheme { static dispatch_once_t initCheckedSchemesOnce; static NSMutableSet *checkedSchemes = nil; dispatch_once(&initCheckedSchemesOnce, ^{ checkedSchemes = [NSMutableSet set]; }); @synchronized(self) { if ([checkedSchemes containsObject:urlScheme]) { return; } else { [checkedSchemes addObject:urlScheme]; } } if (![self isRegisteredCanOpenURLScheme:urlScheme]){ NSString *reason = [NSString stringWithFormat:@"%@ is missing from your Info.plist under LSApplicationQueriesSchemes and is required for iOS 9.0", urlScheme]; #ifdef __IPHONE_9_0 @throw [NSException exceptionWithName:@"InvalidOperationException" reason:reason userInfo:nil]; #else [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:reason]; #endif } } + (BOOL)isRegisteredCanOpenURLScheme:(NSString *)urlScheme { static dispatch_once_t fetchBundleOnce; static NSArray *schemes = nil; dispatch_once(&fetchBundleOnce, ^{ schemes = [[[NSBundle mainBundle] infoDictionary] valueForKey:@"LSApplicationQueriesSchemes"]; }); return [schemes containsObject:urlScheme]; } + (BOOL)isPublishPermission:(NSString *)permission { return [permission hasPrefix:@"publish"] || [permission hasPrefix:@"manage"] || [permission isEqualToString:@"ads_management"] || [permission isEqualToString:@"create_event"] || [permission isEqualToString:@"rsvp_event"]; } + (BOOL)areAllPermissionsReadPermissions:(NSSet *)permissions { for (NSString *permission in permissions) { if ([[self class] isPublishPermission:permission]) { return NO; } } return YES; } + (BOOL)areAllPermissionsPublishPermissions:(NSSet *)permissions { for (NSString *permission in permissions) { if (![[self class] isPublishPermission:permission]) { return NO; } } return YES; } + (Class)resolveBoltsClassWithName:(NSString *)className; { Class clazz = NSClassFromString(className); if (clazz == nil) { NSString *message = [NSString stringWithFormat:@"Unable to load class %@. Did you link Bolts.framework?", className]; @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:message userInfo:nil]; } return clazz; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKLogger.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import /*! @class FBSDKLogger @abstract Simple logging utility for conditionally logging strings and then emitting them via NSLog(). @unsorted */ @interface FBSDKLogger : NSObject // Access current accumulated contents of the logger. @property (copy, nonatomic) NSString *contents; // Each FBSDKLogger gets a unique serial number to allow the client to log these numbers and, for instance, correlation of Request/Response @property (nonatomic, readonly) NSUInteger loggerSerialNumber; // The logging behavior of this logger. See the FB_LOG_BEHAVIOR* constants in FBSession.h @property (copy, nonatomic, readonly) NSString *loggingBehavior; // Is the current logger instance active, based on its loggingBehavior? @property (nonatomic, readonly) BOOL isActive; // // Instance methods // // Create with specified logging behavior - (instancetype)initWithLoggingBehavior:(NSString *)loggingBehavior; // Append string, or key/value pair - (void)appendString:(NSString *)string; - (void)appendFormat:(NSString *)formatString, ... NS_FORMAT_FUNCTION(1,2); - (void)appendKey:(NSString *)key value:(NSString *)value; // Emit log, clearing out the logger contents. - (void)emitToNSLog; // // Class methods // // // Return a globally unique serial number to be used for correlating multiple output from the same logger. // + (NSUInteger)generateSerialNumber; // Simple helper to write a single log entry, based upon whether the behavior matches a specified on. + (void)singleShotLogEntry:(NSString *)loggingBehavior logEntry:(NSString *)logEntry; + (void)singleShotLogEntry:(NSString *)loggingBehavior formatString:(NSString *)formatString, ... NS_FORMAT_FUNCTION(2,3); + (void)singleShotLogEntry:(NSString *)loggingBehavior timestampTag:(NSObject *)timestampTag formatString:(NSString *)formatString, ... NS_FORMAT_FUNCTION(3,4); // Register a timestamp label with the "current" time, to then be retrieved by singleShotLogEntry // to include a duration. + (void)registerCurrentTime:(NSString *)loggingBehavior withTag:(NSObject *)timestampTag; // When logging strings, replace all instances of 'replace' with instances of 'replaceWith'. + (void)registerStringToReplace:(NSString *)replace replaceWith:(NSString *)replaceWith; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKLogger.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLogger.h" #import "FBSDKInternalUtility.h" #import "FBSDKSettings+Internal.h" static NSUInteger g_serialNumberCounter = 1111; static NSMutableDictionary *g_stringsToReplace = nil; static NSMutableDictionary *g_startTimesWithTags = nil; @interface FBSDKLogger () @property (nonatomic, strong, readonly) NSMutableString *internalContents; @end @implementation FBSDKLogger // Lifetime - (instancetype)initWithLoggingBehavior:(NSString *)loggingBehavior { if ((self = [super init])) { _isActive = [[FBSDKSettings loggingBehavior] containsObject:loggingBehavior]; _loggingBehavior = loggingBehavior; if (_isActive) { _internalContents = [[NSMutableString alloc] init]; _loggerSerialNumber = [FBSDKLogger generateSerialNumber]; } } return self; } // Public properties - (NSString *)contents { return _internalContents; } - (void)setContents:(NSString *)contents { if (_isActive) { _internalContents = [NSMutableString stringWithString:contents]; } } // Public instance methods - (void)appendString:(NSString *)string { if (_isActive) { [_internalContents appendString:string]; } } - (void)appendFormat:(NSString *)formatString, ... { if (_isActive) { va_list vaArguments; va_start(vaArguments, formatString); NSString *logString = [[NSString alloc] initWithFormat:formatString arguments:vaArguments]; va_end(vaArguments); [self appendString:logString]; } } - (void)appendKey:(NSString *)key value:(NSString *)value { if (_isActive && [value length]) { [_internalContents appendFormat:@" %@:\t%@\n", key, value]; } } - (void)emitToNSLog { if (_isActive) { for (NSString *key in [g_stringsToReplace keyEnumerator]) { [_internalContents replaceOccurrencesOfString:key withString:[g_stringsToReplace objectForKey:key] options:NSLiteralSearch range:NSMakeRange(0, _internalContents.length)]; } // Xcode 4.4 hangs on extremely long NSLog output (http://openradar.appspot.com/11972490). Truncate if needed. const int MAX_LOG_STRING_LENGTH = 10000; NSString *logString = _internalContents; if (_internalContents.length > MAX_LOG_STRING_LENGTH) { logString = [NSString stringWithFormat:@"TRUNCATED: %@", [_internalContents substringToIndex:MAX_LOG_STRING_LENGTH]]; } NSLog(@"FBSDKLog: %@", logString); [_internalContents setString:@""]; } } // Public static methods + (NSUInteger)generateSerialNumber { return g_serialNumberCounter++; } + (void)singleShotLogEntry:(NSString *)loggingBehavior logEntry:(NSString *)logEntry { if ([[FBSDKSettings loggingBehavior] containsObject:loggingBehavior]) { FBSDKLogger *logger = [[FBSDKLogger alloc] initWithLoggingBehavior:loggingBehavior]; [logger appendString:logEntry]; [logger emitToNSLog]; } } + (void)singleShotLogEntry:(NSString *)loggingBehavior formatString:(NSString *)formatString, ... { if ([[FBSDKSettings loggingBehavior] containsObject:loggingBehavior]) { va_list vaArguments; va_start(vaArguments, formatString); NSString *logString = [[NSString alloc] initWithFormat:formatString arguments:vaArguments]; va_end(vaArguments); [self singleShotLogEntry:loggingBehavior logEntry:logString]; } } + (void)singleShotLogEntry:(NSString *)loggingBehavior timestampTag:(NSObject *)timestampTag formatString:(NSString *)formatString, ... { if ([[FBSDKSettings loggingBehavior] containsObject:loggingBehavior]) { va_list vaArguments; va_start(vaArguments, formatString); NSString *logString = [[NSString alloc] initWithFormat:formatString arguments:vaArguments]; va_end(vaArguments); // Start time of this "timestampTag" is stashed in the dictionary. // Treat the incoming object tag simply as an address, since it's only used to identify during lifetime. If // we send in as an object, the dictionary will try to copy it. NSNumber *tagAsNumber = [NSNumber numberWithUnsignedLong:(unsigned long)(__bridge void *)timestampTag]; NSNumber *startTimeNumber = [g_startTimesWithTags objectForKey:tagAsNumber]; // Only log if there's been an associated start time. if (startTimeNumber) { unsigned long elapsed = [FBSDKInternalUtility currentTimeInMilliseconds] - startTimeNumber.unsignedLongValue; [g_startTimesWithTags removeObjectForKey:tagAsNumber]; // served its purpose, remove // Log string is appended with "%d msec", with nothing intervening. This gives the most control to the caller. logString = [NSString stringWithFormat:@"%@%lu msec", logString, elapsed]; [self singleShotLogEntry:loggingBehavior logEntry:logString]; } } } + (void)registerCurrentTime:(NSString *)loggingBehavior withTag:(NSObject *)timestampTag { if ([[FBSDKSettings loggingBehavior] containsObject:loggingBehavior]) { if (!g_startTimesWithTags) { g_startTimesWithTags = [[NSMutableDictionary alloc] init]; } if (g_startTimesWithTags.count >= 1000) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry: @"Unexpectedly large number of outstanding perf logging start times, something is likely wrong."]; } unsigned long currTime = [FBSDKInternalUtility currentTimeInMilliseconds]; // Treat the incoming object tag simply as an address, since it's only used to identify during lifetime. If // we send in as an object, the dictionary will try to copy it. unsigned long tagAsNumber = (unsigned long)(__bridge void *)timestampTag; [g_startTimesWithTags setObject:[NSNumber numberWithUnsignedLong:currTime] forKey:[NSNumber numberWithUnsignedLong:tagAsNumber]]; } } + (void)registerStringToReplace:(NSString *)replace replaceWith:(NSString *)replaceWith { // Strings sent in here never get cleaned up, but that's OK, don't ever expect too many. if ([[FBSDKSettings loggingBehavior] count] > 0) { // otherwise there's no logging. if (!g_stringsToReplace) { g_stringsToReplace = [[NSMutableDictionary alloc] init]; } [g_stringsToReplace setValue:replaceWith forKey:replace]; } } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMath.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @interface FBSDKMath : NSObject + (CGPoint)ceilForPoint:(CGPoint)value; + (CGSize)ceilForSize:(CGSize)value; + (CGPoint)floorForPoint:(CGPoint)value; + (CGSize)floorForSize:(CGSize)value; + (NSUInteger)hashWithCGFloat:(CGFloat)value; + (NSUInteger)hashWithCString:(const char *)value; + (NSUInteger)hashWithDouble:(double)value; + (NSUInteger)hashWithFloat:(float)value; + (NSUInteger)hashWithInteger:(NSUInteger)value; + (NSUInteger)hashWithInteger:(NSUInteger)value1 andInteger:(NSUInteger)value2; + (NSUInteger)hashWithIntegerArray:(NSUInteger *)values count:(NSUInteger)count; + (NSUInteger)hashWithLong:(unsigned long long)value; + (NSUInteger)hashWithPointer:(const void *)value; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMath.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright 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. // // Based on Thomas Wang 32/64 bit mix hash // http://www.concentric.net/~Ttwang/tech/inthash.htm // #import "FBSDKMath.h" #import #import "FBSDKMacros.h" @implementation FBSDKMath #pragma mark - Class Methods + (CGPoint)ceilForPoint:(CGPoint)value { return CGPointMake(ceilf(value.x), ceilf(value.x)); } + (CGSize)ceilForSize:(CGSize)value { return CGSizeMake(ceilf(value.width), ceilf(value.height)); } + (CGPoint)floorForPoint:(CGPoint)value { return CGPointMake(floorf(value.x), floorf(value.y)); } + (CGSize)floorForSize:(CGSize)value { return CGSizeMake(floorf(value.width), floorf(value.height)); } + (NSUInteger)hashWithCGFloat:(CGFloat)value { #if CGFLOAT_IS_DOUBLE return [self hashWithDouble:value]; #else return [self hashWithFloat:value]; #endif } + (NSUInteger)hashWithCString:(const char *)value { // FNV-1a hash. NSUInteger hash = sizeof(NSUInteger) == 4 ? 2166136261U : 14695981039346656037U; while (*value) { hash ^= *value++; hash *= sizeof(NSUInteger) == 4 ? 16777619 : 1099511628211; } return hash; } + (NSUInteger)hashWithDouble:(double)value { assert(sizeof(double) == sizeof(uint64_t)); // Size of double must be 8 bytes union { double key; uint64_t bits; } u; u.key = value; return [self hashWithLong:u.bits]; } + (NSUInteger)hashWithFloat:(float)value { assert(sizeof(float) == sizeof(uint32_t)); // Size of float must be 4 bytes union { float key; uint32_t bits; } u; u.key = value; return [self hashWithInteger:u.bits]; } + (NSUInteger)hashWithInteger:(NSUInteger)value { return [self hashWithPointer:(void *)value]; } + (NSUInteger)hashWithInteger:(NSUInteger)value1 andInteger:(NSUInteger)value2 { return [self hashWithLong:(((unsigned long long)value1) << 32 | value2)]; } + (NSUInteger)hashWithIntegerArray:(NSUInteger *)values count:(NSUInteger)count { if (count == 0) { return 0; } NSUInteger hash = values[0]; for (NSUInteger i = 1; i < count; ++i) { hash = [self hashWithInteger:hash andInteger:values[i]]; } return hash; } + (NSUInteger)hashWithLong:(unsigned long long)value { value = (~value) + (value << 18); // key = (key << 18) - key - 1; value ^= (value >> 31); value *= 21; // key = (key + (key << 2)) + (key << 4); value ^= (value >> 11); value += (value << 6); value ^= (value >> 22); return (NSUInteger)value; } + (NSUInteger)hashWithPointer:(const void *)value { NSUInteger hash = (NSUInteger)value; #if !TARGET_RT_64_BIT hash = ~hash + (hash << 15); // key = (key << 15) - key - 1; hash ^= (hash >> 12); hash += (hash << 2); hash ^= (hash >> 4); hash *= 2057; // key = (key + (key << 3)) + (key << 11); hash ^= (hash >> 16); #else hash += ~hash + (hash << 21); // key = (key << 21) - key - 1; hash ^= (hash >> 24); hash = (hash + (hash << 3)) + (hash << 8); hash ^= (hash >> 14); hash = (hash + (hash << 2)) + (hash << 4); // key * 21 hash ^= (hash >> 28); hash += (hash << 31); #endif return hash; } #pragma mark - Object Lifecycle - (instancetype)init { FBSDK_NO_DESIGNATED_INITIALIZER(); return nil; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMonotonicTime.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright 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. #include typedef double FBSDKMonotonicTimeSeconds; typedef uint64_t FBSDKMonotonicTimeMilliseconds; typedef uint64_t FBSDKMonotonicTimeNanoseconds; typedef uint64_t FBSDKMachAbsoluteTimeUnits; /** * return current monotonic time in Milliseconds * Millisecond precision, uint64_t value. * Avoids float/double math operations, thus more efficient than FBSDKMonotonicTimeGetCurrentSeconds. * Should be preferred over FBSDKMonotonicTimeGetCurrentSeconds in case millisecond * precision is required. * IMPORTANT: this timer doesn't run while the device is sleeping. */ FBSDKMonotonicTimeMilliseconds FBSDKMonotonicTimeGetCurrentMilliseconds(void); /** * return current monotonic time in Seconds * Nanosecond precision, double value. * Should be preferred over FBSDKMonotonicTimeGetCurrentMilliseconds in case * nanosecond precision is required. * IMPORTANT: this timer doesn't run while the device is sleeping. */ FBSDKMonotonicTimeSeconds FBSDKMonotonicTimeGetCurrentSeconds(void); /** * return current monotonic time in NanoSeconds * Nanosecond precision, uint64_t value. * Useful when nanosecond precision is required but you want to avoid float/double math operations. * IMPORTANT: this timer doesn't run while the device is sleeping. */ FBSDKMonotonicTimeNanoseconds FBSDKMonotonicTimeGetCurrentNanoseconds(void); /** * return number of MachTimeUnits for given number of seconds * this is useful when you want to use the really fast mach_absolute_time() function * to calculate deltas between two points and then check it against a (precomputed) threshold. * Nanosecond precision, uint64_t value. */ FBSDKMachAbsoluteTimeUnits FBSDKMonotonicTimeConvertSecondsToMachUnits(FBSDKMonotonicTimeSeconds seconds); /** * return the number of seconds for a given amount of MachTimeUnits * this is useful when you want to use the really fast mach_absolute_time() function, take * deltas between time points, and when you're out of the timing critical section, use * this function to compute how many seconds the delta works out to be. */ FBSDKMonotonicTimeSeconds FBSDKMonotonicTimeConvertMachUnitsToSeconds(FBSDKMachAbsoluteTimeUnits machUnits); ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMonotonicTime.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright 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. #include #include #include #include #import "FBSDKMonotonicTime.h" /** * PLEASE NOTE: FBSDKSDKMonotonicTimeTests work fine, but are disabled * because they take several seconds. Please re-enable them to test * any changes you're making here! */ static uint64_t _get_time_nanoseconds(void) { static struct mach_timebase_info tb_info = {0}; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ int ret = mach_timebase_info(&tb_info); assert(0 == ret); }); return (mach_absolute_time() * tb_info.numer) / tb_info.denom; } FBSDKMonotonicTimeSeconds FBSDKMonotonicTimeGetCurrentSeconds(void) { const uint64_t nowNanoSeconds = _get_time_nanoseconds(); return (FBSDKMonotonicTimeSeconds)nowNanoSeconds / (FBSDKMonotonicTimeSeconds)1000000000.0; } FBSDKMonotonicTimeMilliseconds FBSDKMonotonicTimeGetCurrentMilliseconds(void) { const uint64_t nowNanoSeconds = _get_time_nanoseconds(); return nowNanoSeconds / 1000000; } FBSDKMonotonicTimeNanoseconds FBSDKMonotonicTimeGetCurrentNanoseconds(void) { return _get_time_nanoseconds(); } FBSDKMachAbsoluteTimeUnits FBSDKMonotonicTimeConvertSecondsToMachUnits(FBSDKMonotonicTimeSeconds seconds) { static double ratio = 0; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ struct mach_timebase_info tb_info = {0}; int ret = mach_timebase_info(&tb_info); assert(0 == ret); ratio = ((double) tb_info.denom / (double)tb_info.numer) * 1000000000.0; }); return seconds * ratio; } FBSDKMonotonicTimeSeconds FBSDKMonotonicTimeConvertMachUnitsToSeconds(FBSDKMachAbsoluteTimeUnits machUnits) { static double ratio = 0; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ struct mach_timebase_info tb_info = {0}; int ret = mach_timebase_info(&tb_info); assert(0 == ret); ratio = ((double) tb_info.numer / (double)tb_info.denom) / 1000000000.0; }); return ratio * (double)machUnits; } ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKProfile.h" @interface FBSDKProfile(Internal) + (void)cacheProfile:(FBSDKProfile *) profile; + (FBSDKProfile *)fetchCachedProfile; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSettings+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAccessTokenCache.h" #import "FBSDKSettings.h" @interface FBSDKSettings(Internal) + (FBSDKAccessTokenCache *)accessTokenCache; - (void)setAccessTokenCache; + (NSString *)graphAPIDebugParamValue; + (BOOL)isGraphErrorRecoveryDisabled; // used by Unity. + (NSString *)userAgentSuffix; + (void)setUserAgentSuffix:(NSString *)suffix; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSystemAccountStoreAdapter.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import typedef void (^FBSDKGraphRequestAccessToAccountsHandler)(NSString *oauthToken, NSError *accountStoreError); /* @class @abstract Adapter around system account store APIs. Note this is only intended for internal consumption. If publicized, consider moving declarations to an internal only header and reconsider dispatching semantics. */ @interface FBSDKSystemAccountStoreAdapter : NSObject /* @abstract Requests access to the device's Facebook account for the given parameters. @param permissions the permissions @param defaultAudience the default audience @param isReauthorize a flag describing if this is a reauth request @param appID the app id @param handler the handler that will be invoked on completion (dispatched to the main thread). the oauthToken is nil on failure. */ - (void)requestAccessToFacebookAccountStore:(NSSet *)permissions defaultAudience:(NSString *)defaultAudience isReauthorize:(BOOL)isReauthorize appID:(NSString *)appID handler:(FBSDKGraphRequestAccessToAccountsHandler)handler; /* @abstract Sends a message to the device account store to renew the Facebook account credentials @param handler the handler that is invoked on completion */ - (void)renewSystemAuthorization:(void(^)(ACAccountCredentialRenewResult result, NSError *error))handler; /* @abstracts gets the oauth token stored in the account store credential, if available. If not empty, this implies user has granted access. */ - (NSString *)accessTokenString; /* @abstract Gets the singleton instance. */ + (FBSDKSystemAccountStoreAdapter *)sharedInstance; /* @abstract Sets the singleton instance, typically only for unit tests */ + (void)setSharedInstance:(FBSDKSystemAccountStoreAdapter *)instance; /* @abstract Gets or sets the flag indicating if the next requestAccess call should block on a renew call. */ @property (nonatomic, assign) BOOL forceBlockingRenew; /* @abstract A convenience getter to the Facebook account type in the account store, if available. */ @property (strong, nonatomic, readonly) ACAccountType *accountType; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSystemAccountStoreAdapter.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKSystemAccountStoreAdapter.h" #import "FBSDKConstants.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKError.h" #import "FBSDKLogger.h" #import "FBSDKSettings+Internal.h" @interface FBSDKSystemAccountStoreAdapter () @property (retain, nonatomic, readonly) ACAccountStore *accountStore; @end static NSString *const FBForceBlockingRenewKey = @"com.facebook.sdk:ForceBlockingRenewKey"; static FBSDKSystemAccountStoreAdapter *_singletonInstance = nil; @implementation FBSDKSystemAccountStoreAdapter { ACAccountStore *_accountStore; ACAccountType *_accountType; } + (void)initialize { if (self == [FBSDKSystemAccountStoreAdapter class]) { _singletonInstance = [[self alloc] init]; } } - (instancetype)init { self = [super init]; if (self) { _forceBlockingRenew = [[NSUserDefaults standardUserDefaults] boolForKey:FBForceBlockingRenewKey]; } return self; } #pragma mark - Properties - (ACAccountStore *)accountStore { if (_accountStore == nil) { _accountStore = [[fbsdkdfl_ACAccountStoreClass() alloc] init]; } return _accountStore; } - (ACAccountType *)accountType { if (_accountType == nil) { _accountType = [self.accountStore accountTypeWithAccountTypeIdentifier:@"com.apple.facebook"]; } return _accountType; } - (void)setForceBlockingRenew:(BOOL)forceBlockingRenew { if (_forceBlockingRenew != forceBlockingRenew) { _forceBlockingRenew = forceBlockingRenew; NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setBool:forceBlockingRenew forKey:FBForceBlockingRenewKey]; [userDefaults synchronize]; } } + (FBSDKSystemAccountStoreAdapter *)sharedInstance { return _singletonInstance; } + (void)setSharedInstance:(FBSDKSystemAccountStoreAdapter *)instance { _singletonInstance = instance; } - (NSString *)accessTokenString { if (self.accountType && self.accountType.accessGranted) { NSArray *fbAccounts = [self.accountStore accountsWithAccountType:self.accountType]; if (fbAccounts.count > 0) { id account = [fbAccounts objectAtIndex:0]; id credential = [account credential]; return [credential oauthToken]; } } return nil; } #pragma mark - Public properties and methods - (void)requestAccessToFacebookAccountStore:(NSSet *)permissions defaultAudience:(NSString *)defaultAudience isReauthorize:(BOOL)isReauthorize appID:(NSString *)appID handler:(FBSDKGraphRequestAccessToAccountsHandler)handler { if (appID == nil) { @throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"appID cannot be nil" userInfo:nil]; } // no publish_* permissions are permitted with a nil audience if (!defaultAudience && isReauthorize) { for (NSString *p in permissions) { if ([p hasPrefix:@"publish"]) { [[NSException exceptionWithName:NSInvalidArgumentException reason:@"FBSDKLoginManager: One or more publish permission was requested " @"without specifying an audience; use FBSDKDefaultAudienceOnlyMe, " @"FBSDKDefaultAudienceFriends, or FBSDKDefaultAudienceEveryone" userInfo:nil] raise]; } } } // construct access options NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: appID, fbsdkdfl_ACFacebookAppIdKey(), [permissions allObjects], fbsdkdfl_ACFacebookPermissionsKey(), defaultAudience, fbsdkdfl_ACFacebookAudienceKey(), // must end on this key/value due to audience possibly being nil nil]; if (self.forceBlockingRenew && [self.accountStore accountsWithAccountType:self.accountType].count > 0) { // If the force renew flag is set and an iOS FB account is still set, // chain the requestAccessBlock to a successful renew result [self renewSystemAuthorization:^(ACAccountCredentialRenewResult result, NSError *error) { if (result == ACAccountCredentialRenewResultRenewed) { self.forceBlockingRenew = NO; [self requestAccessToFacebookAccountStore:options retrying:NO handler:handler]; } else if (handler) { // Otherwise, invoke the caller's handler back on the main thread with an // error that will trigger the password change user message. dispatch_async(dispatch_get_main_queue(), ^{ handler(nil, error); }); } }]; } else { // Otherwise go ahead and invoke normal request. [self requestAccessToFacebookAccountStore:options retrying:NO handler:handler]; } } - (void)requestAccessToFacebookAccountStore:(NSDictionary *)options retrying:(BOOL)retrying handler:(FBSDKGraphRequestAccessToAccountsHandler)handler { if (!self.accountType) { if (handler) { handler(nil, [FBSDKError errorWithCode:FBSDKUnknownErrorCode message:@"Invalid request to account store"]); } return; } // we will attempt an iOS integrated facebook login [self.accountStore requestAccessToAccountsWithType:self.accountType options:options completion:^(BOOL granted, NSError *error) { if (!granted && error.code == ACErrorPermissionDenied && [error.description rangeOfString:@"remote_app_id does not match stored id"].location != NSNotFound) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors formatString: @"System authorization failed:'%@'. This may be caused by a mismatch between" @" the bundle identifier and your app configuration on the server" @" at developers.facebook.com/apps.", error.localizedDescription]; } // requestAccessToAccountsWithType:options:completion: completes on an // arbitrary thread; let's process this back on our main thread dispatch_async(dispatch_get_main_queue(), ^{ NSError *accountStoreError = error; NSString *oauthToken = nil; id account = nil; if (granted) { NSArray *fbAccounts = [self.accountStore accountsWithAccountType:self.accountType]; if (fbAccounts.count > 0) { account = [fbAccounts objectAtIndex:0]; id credential = [account credential]; oauthToken = [credential oauthToken]; } self.forceBlockingRenew = NO; } if (!accountStoreError && !oauthToken) { if (!retrying) { // This can happen as a result of, e.g., restoring from iCloud to a different device. Try once to renew. [self renewSystemAuthorization:^(ACAccountCredentialRenewResult renewResult, NSError *renewError) { // Call block again, regardless of result -- either we'll get credentials or we'll fail with the // exception below. We want to treat failure here the same regardless of whether it was before or after the refresh attempt. [self requestAccessToFacebookAccountStore:options retrying:YES handler:handler]; }]; return; } // else call handler with nils. } handler(oauthToken, accountStoreError); }); }]; } - (void)renewSystemAuthorization:(void(^)(ACAccountCredentialRenewResult, NSError *))handler { // if the slider has been set to off, renew calls to iOS simply hang, so we must // preemptively check for that condition. if (self.accountStore && self.accountType && self.accountType.accessGranted) { NSArray *fbAccounts = [self.accountStore accountsWithAccountType:self.accountType]; id account; if (fbAccounts && [fbAccounts count] > 0 && (account = [fbAccounts objectAtIndex:0])) { FBSDKAccessToken *currentToken = [FBSDKAccessToken currentAccessToken]; if (![currentToken.tokenString isEqualToString:[self accessTokenString]]) { currentToken = nil; } [self.accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) { if (error) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorAccessTokens logEntry:[NSString stringWithFormat:@"renewCredentialsForAccount result:%ld, error: %@", (long)renewResult, error]]; } if (renewResult == ACAccountCredentialRenewResultRenewed && currentToken && [currentToken isEqual:[FBSDKAccessToken currentAccessToken]]) { // account store renewals can change the stored oauth token so we need to update the currentAccessToken // so future comparisons to -[ accessTokenString] work correctly (e.g., error recovery). FBSDKAccessToken *updatedToken = [[FBSDKAccessToken alloc] initWithTokenString:[self accessTokenString] permissions:[currentToken.permissions allObjects] declinedPermissions:[currentToken.declinedPermissions allObjects] appID:currentToken.appID userID:currentToken.userID expirationDate:[NSDate distantFuture] refreshDate:[NSDate date]]; [FBSDKAccessToken setCurrentAccessToken:updatedToken]; } if (handler) { handler(renewResult, error); } }]; return; } } if (handler) { handler(ACAccountCredentialRenewResultFailed, nil); } } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import typedef NS_ENUM(NSInteger, FBSDKTriStateBOOL) { FBSDKTriStateBOOLValueUnknown = -1, FBSDKTriStateBOOLValueNO = 0, FBSDKTriStateBOOLValueYES = 1, }; FBSDK_EXTERN FBSDKTriStateBOOL FBSDKTriStateBOOLFromBOOL(BOOL value); FBSDK_EXTERN FBSDKTriStateBOOL FBSDKTriStateBOOLFromNSNumber(NSNumber *value); FBSDK_EXTERN BOOL BOOLFromFBSDKTriStateBOOL(FBSDKTriStateBOOL value, BOOL defaultValue); ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKTriStateBOOL.h" FBSDKTriStateBOOL FBSDKTriStateBOOLFromBOOL(BOOL value) { return value ? FBSDKTriStateBOOLValueYES : FBSDKTriStateBOOLValueNO; } FBSDKTriStateBOOL FBSDKTriStateBOOLFromNSNumber(NSNumber *value) { return ([value isKindOfClass:[NSNumber class]] ? FBSDKTriStateBOOLFromBOOL([value boolValue]) : FBSDKTriStateBOOLValueUnknown); } BOOL BOOLFromFBSDKTriStateBOOL(FBSDKTriStateBOOL value, BOOL defaultValue) { switch (value) { case FBSDKTriStateBOOLValueYES: return YES; case FBSDKTriStateBOOLValueNO: return NO; case FBSDKTriStateBOOLValueUnknown: return defaultValue; } } ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTypeUtility.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @interface FBSDKTypeUtility : NSObject + (NSArray *)arrayValue:(id)object; + (BOOL)boolValue:(id)object; + (NSDictionary *)dictionaryValue:(id)object; + (NSInteger)integerValue:(id)object; + (id)objectValue:(id)object; + (NSString *)stringValue:(id)object; + (NSTimeInterval)timeIntervalValue:(id)object; + (NSUInteger)unsignedIntegerValue:(id)object; + (NSURL *)URLValue:(id)object; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTypeUtility.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKTypeUtility.h" #import "FBSDKMacros.h" @implementation FBSDKTypeUtility #pragma mark - Class Methods + (NSArray *)arrayValue:(id)object { return (NSArray *)[self _objectValue:object ofClass:[NSArray class]]; } + (BOOL)boolValue:(id)object { if ([object isKindOfClass:[NSNumber class]]) { // @0 or @NO returns NO, otherwise YES return [(NSNumber *)object boolValue]; } else if ([object isKindOfClass:[NSString class]]) { // Returns YES on encountering one of "Y", "y", "T", "t", or a digit 1-9, otherwise NO return [(NSString *)object boolValue]; } else { return ([self objectValue:object] != nil); } } + (NSDictionary *)dictionaryValue:(id)object { return (NSDictionary *)[self _objectValue:object ofClass:[NSDictionary class]]; } + (NSInteger)integerValue:(id)object { if ([object isKindOfClass:[NSNumber class]]) { return [(NSNumber *)object integerValue]; } else if ([object isKindOfClass:[NSString class]]) { return [(NSString *)object integerValue]; } else { return 0; } } + (id)objectValue:(id)object { return ([object isKindOfClass:[NSNull class]] ? nil : object); } + (NSString *)stringValue:(id)object { if ([object isKindOfClass:[NSString class]]) { return (NSString *)object; } else if ([object isKindOfClass:[NSNumber class]]) { return [(NSNumber *)object stringValue]; } else if ([object isKindOfClass:[NSURL class]]) { return [(NSURL *)object absoluteString]; } else { return nil; } } + (NSTimeInterval)timeIntervalValue:(id)object { if ([object isKindOfClass:[NSNumber class]]) { return [(NSNumber *)object doubleValue]; } else if ([object isKindOfClass:[NSString class]]) { return [(NSString *)object doubleValue]; } else { return 0; } } + (NSUInteger)unsignedIntegerValue:(id)object { if ([object isKindOfClass:[NSNumber class]]) { return [(NSNumber *)object unsignedIntegerValue]; } else { // there is no direct support for strings containing unsigned values > NSIntegerMax - not worth writing ourselves // right now, so just cap unsigned values at NSIntegerMax until we have a need for larger NSInteger integerValue = [self integerValue:object]; if (integerValue < 0) { integerValue = 0; } return (NSUInteger)integerValue; } } + (NSURL *)URLValue:(id)object { if ([object isKindOfClass:[NSURL class]]) { return (NSURL *)object; } else if ([object isKindOfClass:[NSString class]]) { return [[NSURL alloc] initWithString:(NSString *)object]; } else { return nil; } } #pragma mark - Object Lifecycle - (instancetype)init { FBSDK_NO_DESIGNATED_INITIALIZER(); return nil; } #pragma mark - Helper Methods + (id)_objectValue:(id)object ofClass:(Class)expectedClass { return ([object isKindOfClass:expectedClass] ? object : nil); } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequest+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import typedef NS_OPTIONS(NSUInteger, FBSDKGraphRequestFlags) { FBSDKGraphRequestFlagNone = 0, // indicates this request should not use a client token as its token parameter FBSDKGraphRequestFlagSkipClientToken = 1 << 1, // indicates this request should not close the session if its response is an oauth error FBSDKGraphRequestFlagDoNotInvalidateTokenOnError = 1 << 2, // indicates this request should not perform error recovery FBSDKGraphRequestFlagDisableErrorRecovery = 1 << 3, }; @interface FBSDKGraphRequest (Internal) - (instancetype)initWithGraphPath:(NSString *)graphPath parameters:(NSDictionary *)parameters flags:(FBSDKGraphRequestFlags)flags; - (instancetype)initWithGraphPath:(NSString *)graphPath parameters:(NSDictionary *)parameters tokenString:(NSString *)tokenString HTTPMethod:(NSString *)HTTPMethod flags:(FBSDKGraphRequestFlags)flags; // Generally, requests automatically issued by the SDK // should not invalidate the token and should disableErrorRecovery // so that we don't cause a sudden change in token state or trigger recovery // out of context of any user action. @property (nonatomic, assign) FBSDKGraphRequestFlags flags; - (BOOL)isGraphErrorRecoveryDisabled; - (BOOL)hasAttachments; + (BOOL)isAttachment:(id)item; + (NSString *)serializeURL:(NSString *)baseUrl params:(NSDictionary *)params httpMethod:(NSString *)httpMethod; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestBody.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @class FBSDKGraphRequestDataAttachment; @class FBSDKLogger; @interface FBSDKGraphRequestBody : NSObject @property (nonatomic, retain, readonly) NSData *data; - (void)appendWithKey:(NSString *)key formValue:(NSString *)value logger:(FBSDKLogger *)logger; - (void)appendWithKey:(NSString *)key imageValue:(UIImage *)image logger:(FBSDKLogger *)logger; - (void)appendWithKey:(NSString *)key dataValue:(NSData *)data logger:(FBSDKLogger *)logger; - (void)appendWithKey:(NSString *)key dataAttachmentValue:(FBSDKGraphRequestDataAttachment *)dataAttachment logger:(FBSDKLogger *)logger; + (NSString *)mimeContentType; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestBody.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKGraphRequestBody.h" #import "FBSDKGraphRequestDataAttachment.h" #import "FBSDKLogger.h" #import "FBSDKSettings.h" #define kStringBoundary @"3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f" #define kNewline @"\r\n" @implementation FBSDKGraphRequestBody { NSMutableData *_data; } - (instancetype)init { if ((self = [super init])) { _data = [[NSMutableData alloc] init]; } return self; } + (NSString *)mimeContentType { return [NSString stringWithFormat:@"multipart/form-data; boundary=%@", kStringBoundary]; } - (void)appendUTF8:(NSString *)utf8 { if (![_data length]) { NSString *headerUTF8 = [NSString stringWithFormat:@"--%@%@", kStringBoundary, kNewline]; NSData *headerData = [headerUTF8 dataUsingEncoding:NSUTF8StringEncoding]; [_data appendData:headerData]; } NSData *data = [utf8 dataUsingEncoding:NSUTF8StringEncoding]; [_data appendData:data]; } - (void)appendWithKey:(NSString *)key formValue:(NSString *)value logger:(FBSDKLogger *)logger { [self _appendWithKey:key filename:nil contentType:nil contentBlock:^{ [self appendUTF8:value]; }]; [logger appendFormat:@"\n %@:\t%@", key, (NSString *)value]; } - (void)appendWithKey:(NSString *)key imageValue:(UIImage *)image logger:(FBSDKLogger *)logger { NSData *data = UIImageJPEGRepresentation(image, [FBSDKSettings JPEGCompressionQuality]); [self _appendWithKey:key filename:key contentType:@"image/jpeg" contentBlock:^{ [_data appendData:data]; }]; [logger appendFormat:@"\n %@:\t", key, (unsigned long)([data length] / 1024)]; } - (void)appendWithKey:(NSString *)key dataValue:(NSData *)data logger:(FBSDKLogger *)logger { [self _appendWithKey:key filename:key contentType:@"content/unknown" contentBlock:^{ [_data appendData:data]; }]; [logger appendFormat:@"\n %@:\t", key, (unsigned long)([data length] / 1024)]; } - (void)appendWithKey:(NSString *)key dataAttachmentValue:(FBSDKGraphRequestDataAttachment *)dataAttachment logger:(FBSDKLogger *)logger { NSString *filename = dataAttachment.filename ?: key; NSString *contentType = dataAttachment.contentType ?: @"content/unknown"; NSData *data = dataAttachment.data; [self _appendWithKey:key filename:filename contentType:contentType contentBlock:^{ [_data appendData:data]; }]; [logger appendFormat:@"\n %@:\t", key, (unsigned long)([data length] / 1024)]; } - (NSData *)data { return [_data copy]; } - (void)_appendWithKey:(NSString *)key filename:(NSString *)filename contentType:(NSString *)contentType contentBlock:(void(^)(void))contentBlock { NSMutableArray *disposition = [[NSMutableArray alloc] init]; [disposition addObject:@"Content-Disposition: form-data"]; if (key) { [disposition addObject:[[NSString alloc] initWithFormat:@"name=\"%@\"", key]]; } if (filename) { [disposition addObject:[[NSString alloc] initWithFormat:@"filename=\"%@\"", filename]]; } [self appendUTF8:[[NSString alloc] initWithFormat:@"%@%@", [disposition componentsJoinedByString:@"; "], kNewline]]; if (contentType) { [self appendUTF8:[[NSString alloc] initWithFormat:@"Content-Type: %@%@", contentType, kNewline]]; } [self appendUTF8:kNewline]; if (contentBlock != NULL) { contentBlock(); } [self appendUTF8:[[NSString alloc] initWithFormat:@"%@--%@%@", kNewline, kStringBoundary, kNewline]]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestConnection+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @interface FBSDKGraphRequestConnection(Internal) @property (nonatomic, readonly) NSMutableArray *requests; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestMetadata.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import // Internal only class to facilitate FBSDKGraphRequest processing, specifically // associating FBSDKGraphRequest and FBSDKGraphRequestHandler instances and necessary // data for retry processing. @interface FBSDKGraphRequestMetadata : NSObject @property (nonatomic, retain) FBSDKGraphRequest *request; @property (nonatomic, copy) FBSDKGraphRequestHandler completionHandler; @property (nonatomic, copy) NSDictionary *batchParameters; - (instancetype)initWithRequest:(FBSDKGraphRequest *)request completionHandler:(FBSDKGraphRequestHandler)handler batchParameters:(NSDictionary *)batchParameters NS_DESIGNATED_INITIALIZER; - (void)invokeCompletionHandlerForConnection:(FBSDKGraphRequestConnection *)connection withResults:(id)results error:(NSError *)error; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestMetadata.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKGraphRequestMetadata.h" #import "FBSDKGraphRequest.h" #import "FBSDKMacros.h" @implementation FBSDKGraphRequestMetadata - (instancetype)initWithRequest:(FBSDKGraphRequest *)request completionHandler:(FBSDKGraphRequestHandler)handler batchParameters:(NSDictionary *)batchParameters { if ((self = [super init])) { _request = request; _batchParameters = [batchParameters copy]; _completionHandler = [handler copy]; } return self; } - (instancetype)init { FBSDK_NOT_DESIGNATED_INITIALIZER(initWithRequest:completionHandler:batchParameters:); return [self initWithRequest:nil completionHandler:NULL batchParameters:nil]; } - (void)invokeCompletionHandlerForConnection:(FBSDKGraphRequestConnection *)connection withResults:(id)results error:(NSError *)error { if (self.completionHandler) { self.completionHandler(connection, results, error); } } - (NSString *)description { return [NSString stringWithFormat:@"<%@: %p, batchParameters: %@, completionHandler: %@, request: %@>", NSStringFromClass([self class]), self, self.batchParameters, self.completionHandler, self.request.description]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKCoreKit+Internal.h" @interface FBSDKGraphRequestPiggybackManager : NSObject + (void)addPiggybackRequests:(FBSDKGraphRequestConnection *)connection; + (void)addRefreshPiggyback:(FBSDKGraphRequestConnection *)connection permissionHandler:(FBSDKGraphRequestHandler)permissionHandler; + (void)addRefreshPiggybackIfStale:(FBSDKGraphRequestConnection *)connection; + (void)addServerConfigurationPiggyback:(FBSDKGraphRequestConnection *)connection; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKGraphRequestPiggybackManager.h" #import "FBSDKCoreKit+Internal.h" static int const FBSDKTokenRefreshThresholdSeconds = 24 * 60 * 60; // day static int const FBSDKTokenRefreshRetrySeconds = 60 * 60; // hour @implementation FBSDKGraphRequestPiggybackManager + (void)addPiggybackRequests:(FBSDKGraphRequestConnection *)connection { if ([FBSDKSettings appID].length > 0) { BOOL safeForPiggyback = YES; for (FBSDKGraphRequestMetadata *metadata in connection.requests) { if (![metadata.request.version isEqualToString:[FBSDKSettings graphAPIVersion]] || [metadata.request hasAttachments]) { safeForPiggyback = NO; break; } } if (safeForPiggyback) { [[self class] addRefreshPiggybackIfStale:connection]; [[self class] addServerConfigurationPiggyback:connection]; } } } + (void)addRefreshPiggyback:(FBSDKGraphRequestConnection *)connection permissionHandler:(FBSDKGraphRequestHandler)permissionHandler { FBSDKAccessToken *expectedToken = [FBSDKAccessToken currentAccessToken]; __block NSMutableSet *permissions = nil; __block NSMutableSet *declinedPermissions = nil; __block NSString *tokenString = nil; __block NSNumber *expirationDateNumber = nil; __block int expectingCallbacksCount = 2; void (^expectingCallbackComplete)(void) = ^{ if (--expectingCallbacksCount == 0) { FBSDKAccessToken *currentToken = [FBSDKAccessToken currentAccessToken]; NSDate *expirationDate = currentToken.expirationDate; if (expirationDateNumber) { expirationDate = ([expirationDateNumber doubleValue] > 0 ? [NSDate dateWithTimeIntervalSince1970:[expirationDateNumber doubleValue]] : [NSDate distantFuture]); } FBSDKAccessToken *refreshedToken = [[FBSDKAccessToken alloc] initWithTokenString:tokenString ?: currentToken.tokenString permissions:[(permissions ?: currentToken.permissions) allObjects] declinedPermissions:[(declinedPermissions ?: currentToken.declinedPermissions) allObjects] appID:currentToken.appID userID:currentToken.userID expirationDate:expirationDate refreshDate:[NSDate date]]; if (expectedToken == currentToken) { [FBSDKAccessToken setCurrentAccessToken:refreshedToken]; } } }; FBSDKGraphRequest *extendRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"oauth/access_token" parameters:@{@"grant_type" : @"fb_extend_sso_token", @"fields": @"" } flags:FBSDKGraphRequestFlagDisableErrorRecovery]; [connection addRequest:extendRequest completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id result, NSError *error) { tokenString = result[@"access_token"]; expirationDateNumber = result[@"expires_at"]; expectingCallbackComplete(); }]; FBSDKGraphRequest *permissionsRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/permissions" parameters:@{@"fields": @""} flags:FBSDKGraphRequestFlagDisableErrorRecovery]; [connection addRequest:permissionsRequest completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id result, NSError *error) { if (!error) { permissions = [NSMutableSet set]; declinedPermissions = [NSMutableSet set]; [FBSDKInternalUtility extractPermissionsFromResponse:result grantedPermissions:permissions declinedPermissions:declinedPermissions]; } expectingCallbackComplete(); if (permissionHandler) { permissionHandler(innerConnection, result, error); } }]; } + (void)addRefreshPiggybackIfStale:(FBSDKGraphRequestConnection *)connection { // don't piggy back more than once an hour as a cheap way of // retrying in cases of errors and preventing duplicate refreshes. // obviously this is not foolproof but is simple and sufficient. static NSDate *lastRefreshTry; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ lastRefreshTry = [NSDate distantPast]; }); NSDate *now = [NSDate date]; NSDate *tokenRefreshDate = [FBSDKAccessToken currentAccessToken].refreshDate; if (tokenRefreshDate && [now timeIntervalSinceDate:lastRefreshTry] > FBSDKTokenRefreshRetrySeconds && [now timeIntervalSinceDate:tokenRefreshDate] > FBSDKTokenRefreshThresholdSeconds) { [self addRefreshPiggyback:connection permissionHandler:NULL]; lastRefreshTry = [NSDate date]; } } + (void)addServerConfigurationPiggyback:(FBSDKGraphRequestConnection *)connection { if (![[FBSDKServerConfigurationManager cachedServerConfiguration] isDefaults]) { return; } NSString *appID = [FBSDKSettings appID]; FBSDKGraphRequest *serverConfigurationRequest = [FBSDKServerConfigurationManager requestToLoadServerConfiguration:appID]; [connection addRequest:serverConfigurationRequest completionHandler:^(FBSDKGraphRequestConnection *conn, id result, NSError *error) { [FBSDKServerConfigurationManager processLoadRequestResponse:result error:error appID:appID]; }]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKURLConnection.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @class FBSDKURLConnection; typedef void (^FBSDKURLConnectionHandler)(FBSDKURLConnection *connection, NSError *error, NSURLResponse *response, NSData *responseData); @protocol FBSDKURLConnectionDelegate @optional - (void)facebookURLConnection:(FBSDKURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite; @end @interface FBSDKURLConnection : NSObject - (FBSDKURLConnection *)initWithRequest:(NSURLRequest *)request completionHandler:(FBSDKURLConnectionHandler)handler NS_DESIGNATED_INITIALIZER; @property (nonatomic, weak) id delegate; - (void)cancel; - (void)start; - (void)setDelegateQueue:(NSOperationQueue *)queue; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKURLConnection.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKURLConnection.h" #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKMacros.h" #import "FBSDKSettings.h" @interface FBSDKURLConnection () @property (nonatomic, retain) NSURLConnection *connection; @property (nonatomic, retain) NSMutableData *data; @property (nonatomic, copy) FBSDKURLConnectionHandler handler; @property (nonatomic, retain) NSURLResponse *response; @property (nonatomic) unsigned long requestStartTime; @property (nonatomic, readonly) NSUInteger loggerSerialNumber; @end @implementation FBSDKURLConnection #pragma mark - Lifecycle - (FBSDKURLConnection *)initWithRequest:(NSURLRequest *)request completionHandler:(FBSDKURLConnectionHandler)handler { if ((self = [super init])) { _requestStartTime = [FBSDKInternalUtility currentTimeInMilliseconds]; _loggerSerialNumber = [FBSDKLogger generateSerialNumber]; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" _connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]; #pragma clang diagnostic pop _data = [[NSMutableData alloc] init]; _handler = [handler copy]; } return self; } - (instancetype)init { FBSDK_NOT_DESIGNATED_INITIALIZER(initWithRequest:completionHandler:); return [self initWithRequest:nil completionHandler:NULL]; } - (void)logAndInvokeHandler:(FBSDKURLConnectionHandler)handler error:(NSError *)error { if (error) { NSString *logEntry = [NSString stringWithFormat:@"FBSDKURLConnection <#%lu>:\n Error: '%@'\n%@\n", (unsigned long)self.loggerSerialNumber, [error localizedDescription], [error userInfo]]; [self logMessage:logEntry]; } [self invokeHandler:handler error:error response:nil responseData:nil]; } - (void)logAndInvokeHandler:(FBSDKURLConnectionHandler)handler response:(NSURLResponse *)response responseData:(NSData *)responseData { // Basic FBSDKURLConnection logging just prints out the URL. FBSDKGraphRequest logging provides more details. NSString *mimeType = [response MIMEType]; NSMutableString *mutableLogEntry = [NSMutableString stringWithFormat:@"FBSDKURLConnection <#%lu>:\n Duration: %lu msec\nResponse Size: %lu kB\n MIME type: %@\n", (unsigned long)self.loggerSerialNumber, [FBSDKInternalUtility currentTimeInMilliseconds] - self.requestStartTime, (unsigned long)[responseData length] / 1024, mimeType]; if ([mimeType isEqualToString:@"text/javascript"]) { NSString *responseUTF8 = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; [mutableLogEntry appendFormat:@" Response:\n%@\n\n", responseUTF8]; } [self logMessage:mutableLogEntry]; [self invokeHandler:handler error:nil response:response responseData:responseData]; } - (void)invokeHandler:(FBSDKURLConnectionHandler)handler error:(NSError *)error response:(NSURLResponse *)response responseData:(NSData *)responseData { if (handler != nil) { handler(self, error, response, responseData); } } - (void)logMessage:(NSString *)message { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorNetworkRequests formatString:@"%@", message]; } - (void)cancel { [self.connection cancel]; self.handler = nil; } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { self.response = response; [self.data setLength:0]; } - (void)connection:(NSURLResponse *)connection didReceiveData:(NSData *)data { [self.data appendData:data]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { @try { if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == kCFURLErrorSecureConnectionFailed) { NSOperatingSystemVersion iOS9Version = { .majorVersion = 9, .minorVersion = 0, .patchVersion = 0 }; if ([FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS9Version]) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"WARNING: FBSDK secure network request failed. Please verify you have configured your " "app for Application Transport Security compatibility described at https://developers.facebook.com/docs/ios/ios9"]; } } [self logAndInvokeHandler:self.handler error:error]; } @finally { self.handler = nil; } } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { @try { [self logAndInvokeHandler:self.handler response:self.response responseData:self.data]; } @finally { self.handler = nil; } } - (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse { return request; } - (void) connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite { id delegate = self.delegate; if ([delegate respondsToSelector:@selector(facebookURLConnection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:)]) { [delegate facebookURLConnection:self didSendBodyData:bytesWritten totalBytesWritten:totalBytesWritten totalBytesExpectedToWrite:totalBytesExpectedToWrite]; } } - (void)start { [_connection start]; } - (void)setDelegateQueue:(NSOperationQueue*)queue { [_connection setDelegateQueue:queue]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKURLSessionTask.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import typedef void (^FBSDKURLSessionTaskHandler)(NSError *error, NSURLResponse *response, NSData *responseData); @interface FBSDKURLSessionTask : NSObject - (FBSDKURLSessionTask *)initWithRequest:(NSURLRequest *)request fromSession:(NSURLSession *)session completionHandler:(FBSDKURLSessionTaskHandler)handler NS_DESIGNATED_INITIALIZER; - (void)cancel; - (void)start; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKURLSessionTask.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKURLSessionTask.h" #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKMacros.h" #import "FBSDKSettings.h" @interface FBSDKURLSessionTask () @property (nonatomic, strong) NSURLSessionTask *task; @property (nonatomic, copy) FBSDKURLSessionTaskHandler handler; @property (nonatomic, assign) unsigned long requestStartTime; @property (nonatomic, assign, readonly) NSUInteger loggerSerialNumber; @end @implementation FBSDKURLSessionTask - (FBSDKURLSessionTask *)initWithRequest:(NSURLRequest *)request fromSession:(NSURLSession *)session completionHandler:(FBSDKURLSessionTaskHandler)handler { if ((self = [super init])) { _requestStartTime = [FBSDKInternalUtility currentTimeInMilliseconds]; _loggerSerialNumber = [FBSDKLogger generateSerialNumber]; _handler = [handler copy]; __weak FBSDKURLSessionTask *weakSelf = self; _task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (error) { [weakSelf taskDidCompleteWithError:error]; } else { [weakSelf taskDidCompleteWithResponse:response data:data]; } }]; } return self; } - (FBSDKURLSessionTask *)init { FBSDK_NOT_DESIGNATED_INITIALIZER(initWithRequest:fromSession:completionHandler:); return [self initWithRequest:nil fromSession:nil completionHandler:NULL]; } #pragma mark - Logging and Completion - (void)logAndInvokeHandler:(FBSDKURLSessionTaskHandler)handler error:(NSError *)error { if (error) { NSString *logEntry = [NSString stringWithFormat:@"FBSDKURLSessionTask <#%lu>:\n Error: '%@'\n%@\n", (unsigned long)self.loggerSerialNumber, [error localizedDescription], [error userInfo]]; [self logMessage:logEntry]; } [self invokeHandler:handler error:error response:nil responseData:nil]; } - (void)logAndInvokeHandler:(FBSDKURLSessionTaskHandler)handler response:(NSURLResponse *)response responseData:(NSData *)responseData { // Basic FBSDKURLSessionTask logging just prints out the URL. FBSDKGraphRequest logging provides more details. NSString *mimeType = [response MIMEType]; NSMutableString *mutableLogEntry = [NSMutableString stringWithFormat:@"FBSDKURLSessionTask <#%lu>:\n Duration: %lu msec\nResponse Size: %lu kB\n MIME type: %@\n", (unsigned long)self.loggerSerialNumber, [FBSDKInternalUtility currentTimeInMilliseconds] - self.requestStartTime, (unsigned long)[responseData length] / 1024, mimeType]; if ([mimeType isEqualToString:@"text/javascript"]) { NSString *responseUTF8 = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; [mutableLogEntry appendFormat:@" Response:\n%@\n\n", responseUTF8]; } [self logMessage:mutableLogEntry]; [self invokeHandler:handler error:nil response:response responseData:responseData]; } - (void)invokeHandler:(FBSDKURLSessionTaskHandler)handler error:(NSError *)error response:(NSURLResponse *)response responseData:(NSData *)responseData { if (handler != nil) { dispatch_async(dispatch_get_main_queue(), ^{ handler(error, response, responseData); }); } } - (void)logMessage:(NSString *)message { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorNetworkRequests formatString:@"%@", message]; } - (void)taskDidCompleteWithResponse:(NSURLResponse *)response data:(NSData *)data { @try { [self logAndInvokeHandler:self.handler response:response responseData:data]; } @finally { self.handler = nil; } } - (void)taskDidCompleteWithError:(NSError *)error { @try { if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == kCFURLErrorSecureConnectionFailed) { NSOperatingSystemVersion iOS9Version = { .majorVersion = 9, .minorVersion = 0, .patchVersion = 0 }; if ([FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS9Version]) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"WARNING: FBSDK secure network request failed. Please verify you have configured your " "app for Application Transport Security compatibility described at https://developers.facebook.com/docs/ios/ios9"]; } } [self logAndInvokeHandler:self.handler error:error]; } @finally { self.handler = nil; } } #pragma mark - Task State - (void)start { [self.task resume]; } - (void)cancel { [self.task cancel]; self.handler = nil; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKDialogConfiguration.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @interface FBSDKDialogConfiguration : NSObject - (instancetype)initWithName:(NSString *)name URL:(NSURL *)URL appVersions:(NSArray *)appVersions NS_DESIGNATED_INITIALIZER; @property (nonatomic, copy, readonly) NSArray *appVersions; @property (nonatomic, copy, readonly) NSString *name; @property (nonatomic, copy, readonly) NSURL *URL; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKDialogConfiguration.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKDialogConfiguration.h" #import "FBSDKMacros.h" #define FBSDK_DIALOG_CONFIGURATION_APP_VERSIONS_KEY @"appVersions" #define FBSDK_DIALOG_CONFIGURATION_NAME_KEY @"name" #define FBSDK_DIALOG_CONFIGURATION_URL_KEY @"url" @implementation FBSDKDialogConfiguration #pragma mark - Object Lifecycle - (instancetype)initWithName:(NSString *)name URL:(NSURL *)URL appVersions:(NSArray *)appVersions { if ((self = [super init])) { _name = [name copy]; _URL = [URL copy]; _appVersions = [appVersions copy]; } return self; } - (instancetype)init { FBSDK_NOT_DESIGNATED_INITIALIZER(initWithName:URL:appVersions:); return [self initWithName:nil URL:nil appVersions:nil]; } #pragma mark NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { NSString *name = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_DIALOG_CONFIGURATION_NAME_KEY]; NSURL *URL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_DIALOG_CONFIGURATION_URL_KEY]; NSSet *appVersionsClasses = [NSSet setWithObjects:[NSArray class], [NSNumber class], nil]; NSArray *appVersions = [decoder decodeObjectOfClasses:appVersionsClasses forKey:FBSDK_DIALOG_CONFIGURATION_APP_VERSIONS_KEY]; return [self initWithName:name URL:URL appVersions:appVersions]; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_appVersions forKey:FBSDK_DIALOG_CONFIGURATION_APP_VERSIONS_KEY]; [encoder encodeObject:_name forKey:FBSDK_DIALOG_CONFIGURATION_NAME_KEY]; [encoder encodeObject:_URL forKey:FBSDK_DIALOG_CONFIGURATION_URL_KEY]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { return self; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorConfiguration.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKErrorRecoveryConfiguration.h" @class FBSDKGraphRequest; // maps codes and subcodes pairs to FBSDKErrorRecoveryConfiguration instances. @interface FBSDKErrorConfiguration : NSObject // initialize from optional dictionary of existing configurations. If not supplied a fallback will be created. - (instancetype)initWithDictionary:(NSDictionary *)dictionary NS_DESIGNATED_INITIALIZER; // parses the array (supplied from app settings endpoint) - (void)parseArray:(NSArray *)array; // NSString "code" instances support "*" wildcard semantics (nil is treated as "*" also) // 'request' is optional, typically for identifying special graph request semantics (e.g., no recovery for client token) - (FBSDKErrorRecoveryConfiguration *)recoveryConfigurationForCode:(NSString *)code subcode:(NSString *)subcode request:(FBSDKGraphRequest *)request; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorConfiguration.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKErrorConfiguration.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKErrorRecoveryConfiguration.h" static NSString *const kErrorCategoryOther = @"other"; static NSString *const kErrorCategoryTransient = @"transient"; static NSString *const kErrorCategoryLogin = @"login"; #define FBSDKERRORCONFIGURATION_DICTIONARY_KEY @"configurationDictionary" @implementation FBSDKErrorConfiguration { NSMutableDictionary *_configurationDictionary; } - (instancetype)init { FBSDK_NOT_DESIGNATED_INITIALIZER(initWithDictionary:); return [self initWithDictionary:nil]; } - (instancetype)initWithDictionary:(NSDictionary *)dictionary { if ((self = [super init])) { if (dictionary) { _configurationDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionary]; } else { _configurationDictionary = [NSMutableDictionary dictionary]; NSString *localizedOK = NSLocalizedStringWithDefaultValue(@"ErrorRecovery.OK", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"OK", @"The title of the label to start attempting error recovery"); NSString *localizedCancel = NSLocalizedStringWithDefaultValue(@"ErrorRecovery.Cancel", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Cancel", @"The title of the label to decline attempting error recovery"); NSString *localizedTransientSuggestion = NSLocalizedStringWithDefaultValue(@"ErrorRecovery.Transient.Suggestion", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"The server is temporarily busy, please try again.", @"The fallback message to display to retry transient errors"); NSString *localizedLoginRecoverableSuggestion = NSLocalizedStringWithDefaultValue(@"ErrorRecovery.Login.Suggestion", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Please log into this app again to reconnect your Facebook account.", @"The fallback message to display to recover invalidated tokens"); NSArray *fallbackArray = @[ @{ @"name" : @"login", @"items" : @[ @{ @"code" : @102 }, @{ @"code" : @190 } ], @"recovery_message" : localizedLoginRecoverableSuggestion, @"recovery_options" : @[ localizedOK, localizedCancel] }, @{ @"name" : @"transient", @"items" : @[ @{ @"code" : @1 }, @{ @"code" : @2 }, @{ @"code" : @4 }, @{ @"code" : @9 }, @{ @"code" : @17 }, @{ @"code" : @341 } ], @"recovery_message" : localizedTransientSuggestion, @"recovery_options" : @[ localizedOK] }, ]; [self parseArray:fallbackArray]; } } return self; } - (FBSDKErrorRecoveryConfiguration *)recoveryConfigurationForCode:(NSString *)code subcode:(NSString *)subcode request:(FBSDKGraphRequest *)request { code = code ?: @"*"; subcode = subcode ?: @"*"; FBSDKErrorRecoveryConfiguration *configuration = (_configurationDictionary[code][subcode] ?: _configurationDictionary[code][@"*"] ?: _configurationDictionary[@"*"][subcode] ?: _configurationDictionary[@"*"][@"*"]); if (configuration.errorCategory == FBSDKGraphRequestErrorCategoryRecoverable && [FBSDKSettings clientToken] && [request.parameters[@"access_token"] hasSuffix:[FBSDKSettings clientToken]]) { // do not attempt to recovery client tokens. return nil; } return configuration; } - (void)parseArray:(NSArray *)array { for (NSDictionary *dictionary in array) { [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) { FBSDKGraphRequestErrorCategory category; NSString *action = dictionary[@"name"]; if ([action isEqualToString:kErrorCategoryOther]) { category = FBSDKGraphRequestErrorCategoryOther; } else if ([action isEqualToString:kErrorCategoryTransient]) { category = FBSDKGraphRequestErrorCategoryTransient; } else { category = FBSDKGraphRequestErrorCategoryRecoverable; } NSString *suggestion = dictionary[@"recovery_message"]; NSArray *options = dictionary[@"recovery_options"]; for (NSDictionary *codeSubcodesDictionary in dictionary[@"items"]) { NSString *code = [codeSubcodesDictionary[@"code"] stringValue]; NSMutableDictionary *currentSubcodes = _configurationDictionary[code]; if (!currentSubcodes) { currentSubcodes = [NSMutableDictionary dictionary]; _configurationDictionary[code] = currentSubcodes; } NSArray *subcodes = codeSubcodesDictionary[@"subcodes"]; if (subcodes.count > 0) { for (NSNumber *subcodeNumber in subcodes) { currentSubcodes[[subcodeNumber stringValue]] = [[FBSDKErrorRecoveryConfiguration alloc] initWithRecoveryDescription:suggestion optionDescriptions:options category:category recoveryActionName:action]; } } else { currentSubcodes[@"*"] = [[FBSDKErrorRecoveryConfiguration alloc] initWithRecoveryDescription:suggestion optionDescriptions:options category:category recoveryActionName:action]; } } }]; } } #pragma mark - NSSecureCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { NSDictionary *configurationDictionary = [decoder decodeObjectOfClass:[NSDictionary class] forKey:FBSDKERRORCONFIGURATION_DICTIONARY_KEY]; return [self initWithDictionary:configurationDictionary]; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_configurationDictionary forKey:FBSDKERRORCONFIGURATION_DICTIONARY_KEY]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { return self; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorRecoveryConfiguration.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import //immutable @interface FBSDKErrorRecoveryConfiguration : NSObject @property (nonatomic, readonly) NSString *localizedRecoveryDescription; @property (nonatomic, readonly) NSArray *localizedRecoveryOptionDescriptions; @property (nonatomic, readonly) FBSDKGraphRequestErrorCategory errorCategory; @property (nonatomic, readonly) NSString *recoveryActionName; - (instancetype)initWithRecoveryDescription:(NSString *)description optionDescriptions:(NSArray *)optionDescriptions category:(FBSDKGraphRequestErrorCategory)category recoveryActionName:(NSString *)recoveryActionName NS_DESIGNATED_INITIALIZER; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorRecoveryConfiguration.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKErrorRecoveryConfiguration.h" #define FBSDK_ERROR_RECOVERY_CONFIGURATION_DESCRIPTION_KEY @"description" #define FBSDK_ERROR_RECOVERY_CONFIGURATION_OPTIONS_KEY @"options" #define FBSDK_ERROR_RECOVERY_CONFIGURATION_CATEGORY_KEY @"category" #define FBSDK_ERROR_RECOVERY_CONFIGURATION_ACTION_KEY @"action" @implementation FBSDKErrorRecoveryConfiguration - (instancetype)init { FBSDK_NOT_DESIGNATED_INITIALIZER(initWithRecoveryDescription:optionDescriptions:category:recoveryActionName:); return [self initWithRecoveryDescription:nil optionDescriptions:nil category:0 recoveryActionName:nil]; } - (instancetype)initWithRecoveryDescription:(NSString *)description optionDescriptions:(NSArray *)optionDescriptions category:(FBSDKGraphRequestErrorCategory)category recoveryActionName:(NSString *)recoveryActionName { if ((self = [super init])) { _localizedRecoveryDescription = [description copy]; _localizedRecoveryOptionDescriptions = [optionDescriptions copy]; _errorCategory = category; _recoveryActionName = [recoveryActionName copy]; } return self; } #pragma mark - NSSecureCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { NSString *description = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_ERROR_RECOVERY_CONFIGURATION_DESCRIPTION_KEY]; NSArray *options = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_ERROR_RECOVERY_CONFIGURATION_OPTIONS_KEY]; NSNumber *category = [decoder decodeObjectOfClass:[NSNumber class] forKey:FBSDK_ERROR_RECOVERY_CONFIGURATION_CATEGORY_KEY]; NSString *action = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_ERROR_RECOVERY_CONFIGURATION_ACTION_KEY]; return [self initWithRecoveryDescription:description optionDescriptions:options category:[category unsignedIntegerValue] recoveryActionName:action]; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_localizedRecoveryDescription forKey:FBSDK_ERROR_RECOVERY_CONFIGURATION_DESCRIPTION_KEY]; [encoder encodeObject:_localizedRecoveryOptionDescriptions forKey:FBSDK_ERROR_RECOVERY_CONFIGURATION_OPTIONS_KEY]; [encoder encodeObject:@(_errorCategory) forKey:FBSDK_ERROR_RECOVERY_CONFIGURATION_CATEGORY_KEY]; [encoder encodeObject:_recoveryActionName forKey:FBSDK_ERROR_RECOVERY_CONFIGURATION_ACTION_KEY]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { //immutable return self; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import extern NSString *const FBSDKDialogConfigurationNameDefault; extern NSString *const FBSDKDialogConfigurationNameSharing; extern NSString *const FBSDKDialogConfigurationFeatureUseNativeFlow; extern NSString *const FBSDKDialogConfigurationFeatureUseSafariViewController; ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import "FBSDKDialogConfiguration.h" #import "FBSDKErrorConfiguration.h" // login kit extern NSString *const FBSDKDialogConfigurationNameLogin; // share kit extern NSString *const FBSDKDialogConfigurationNameAppInvite; extern NSString *const FBSDKDialogConfigurationNameGameRequest; extern NSString *const FBSDKDialogConfigurationNameGroup; extern NSString *const FBSDKDialogConfigurationNameLike; extern NSString *const FBSDKDialogConfigurationNameMessage; extern NSString *const FBSDKDialogConfigurationNameShare; @interface FBSDKServerConfiguration : NSObject - (instancetype)initWithAppID:(NSString *)appID appName:(NSString *)appName loginTooltipEnabled:(BOOL)loginTooltipEnabled loginTooltipText:(NSString *)loginTooltipText defaultShareMode:(NSString *)defaultShareMode advertisingIDEnabled:(BOOL)advertisingIDEnabled implicitLoggingEnabled:(BOOL)implicitLoggingEnabled implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled systemAuthenticationEnabled:(BOOL)systemAuthenticationEnabled nativeAuthFlowEnabled:(BOOL)nativeAuthFlowEnabled dialogConfigurations:(NSDictionary *)dialogConfigurations dialogFlows:(NSDictionary *)dialogFlows timestamp:(NSDate *)timestamp errorConfiguration:(FBSDKErrorConfiguration *)errorConfiguration sessionTimeoutInterval:(NSTimeInterval) sessionTimeoutInterval defaults:(BOOL)defaults loggingToken:(NSString *)loggingToken NS_DESIGNATED_INITIALIZER; @property (nonatomic, assign, readonly, getter=isAdvertisingIDEnabled) BOOL advertisingIDEnabled; @property (nonatomic, copy, readonly) NSString *appID; @property (nonatomic, copy, readonly) NSString *appName; @property (nonatomic, assign, readonly, getter=isDefaults) BOOL defaults; @property (nonatomic, copy, readonly) NSString *defaultShareMode; @property (nonatomic, strong, readonly) FBSDKErrorConfiguration *errorConfiguration; @property (nonatomic, assign, readonly, getter=isImplicitLoggingSupported) BOOL implicitLoggingEnabled; @property (nonatomic, assign, readonly, getter=isImplicitPurchaseLoggingSupported) BOOL implicitPurchaseLoggingEnabled; @property (nonatomic, assign, readonly, getter=isLoginTooltipEnabled) BOOL loginTooltipEnabled; @property (nonatomic, assign, readonly, getter=isNativeAuthFlowEnabled) BOOL nativeAuthFlowEnabled; @property (nonatomic, assign, readonly, getter=isSystemAuthenticationEnabled) BOOL systemAuthenticationEnabled; @property (nonatomic, copy, readonly) NSString *loginTooltipText; @property (nonatomic, copy, readonly) NSDate *timestamp; @property (nonatomic, assign) NSTimeInterval sessionTimoutInterval; @property (nonatomic, copy, readonly) NSString *loggingToken; - (FBSDKDialogConfiguration *)dialogConfigurationForDialogName:(NSString *)dialogName; - (BOOL)useNativeDialogForDialogName:(NSString *)dialogName; - (BOOL)useSafariViewControllerForDialogName:(NSString *)dialogName; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKServerConfiguration.h" #import "FBSDKServerConfiguration+Internal.h" #import "FBSDKInternalUtility.h" #import "FBSDKMacros.h" #define FBSDK_SERVER_CONFIGURATION_ADVERTISING_ID_ENABLED_KEY @"advertisingIDEnabled" #define FBSDK_SERVER_CONFIGURATION_APP_ID_KEY @"appID" #define FBSDK_SERVER_CONFIGURATION_APP_NAME_KEY @"appName" #define FBSDK_SERVER_CONFIGURATION_DIALOG_CONFIGS_KEY @"dialogConfigs" #define FBSDK_SERVER_CONFIGURATION_DIALOG_FLOWS_KEY @"dialogFlows" #define FBSDK_SERVER_CONFIGURATION_ERROR_CONFIGS_KEY @"errorConfigs" #define FBSDK_SERVER_CONFIGURATION_IMPLICIT_LOGGING_ENABLED_KEY @"implicitLoggingEnabled" #define FBSDK_SERVER_CONFIGURATION_DEFAULT_SHARE_MODE_KEY @"defaultShareMode" #define FBSDK_SERVER_CONFIGURATION_IMPLICIT_PURCHASE_LOGGING_ENABLED_KEY @"implicitPurchaseLoggingEnabled" #define FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_ENABLED_KEY @"loginTooltipEnabled" #define FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_TEXT_KEY @"loginTooltipText" #define FBSDK_SERVER_CONFIGURATION_SYSTEM_AUTHENTICATION_ENABLED_KEY @"systemAuthenticationEnabled" #define FBSDK_SERVER_CONFIGURATION_NATIVE_AUTH_FLOW_ENABLED_KEY @"nativeAuthFlowEnabled" #define FBSDK_SERVER_CONFIGURATION_TIMESTAMP_KEY @"timestamp" #define FBSDK_SERVER_CONFIGURATION_SESSION_TIMEOUT_INTERVAL @"sessionTimeoutInterval" #define FBSDK_SERVER_CONFIGURATION_LOGGING_TOKEN @"loggingToken" #pragma mark - Dialog Names NSString *const FBSDKDialogConfigurationNameDefault = @"default"; NSString *const FBSDKDialogConfigurationNameLogin = @"login"; NSString *const FBSDKDialogConfigurationNameSharing = @"sharing"; NSString *const FBSDKDialogConfigurationNameAppInvite = @"app_invite"; NSString *const FBSDKDialogConfigurationNameGameRequest = @"game_request"; NSString *const FBSDKDialogConfigurationNameGroup = @"group"; NSString *const FBSDKDialogConfigurationNameLike = @"like"; NSString *const FBSDKDialogConfigurationNameMessage = @"message"; NSString *const FBSDKDialogConfigurationNameShare = @"share"; NSString *const FBSDKDialogConfigurationFeatureUseNativeFlow = @"use_native_flow"; NSString *const FBSDKDialogConfigurationFeatureUseSafariViewController = @"use_safari_vc"; @implementation FBSDKServerConfiguration { NSDictionary *_dialogConfigurations; NSDictionary *_dialogFlows; } #pragma mark - Object Lifecycle - (instancetype)init NS_UNAVAILABLE { assert(0); } - (instancetype)initWithAppID:(NSString *)appID appName:(NSString *)appName loginTooltipEnabled:(BOOL)loginTooltipEnabled loginTooltipText:(NSString *)loginTooltipText defaultShareMode:(NSString*)defaultShareMode advertisingIDEnabled:(BOOL)advertisingIDEnabled implicitLoggingEnabled:(BOOL)implicitLoggingEnabled implicitPurchaseLoggingEnabled:(BOOL)implicitPurchaseLoggingEnabled systemAuthenticationEnabled:(BOOL)systemAuthenticationEnabled nativeAuthFlowEnabled:(BOOL)nativeAuthFlowEnabled dialogConfigurations:(NSDictionary *)dialogConfigurations dialogFlows:(NSDictionary *)dialogFlows timestamp:(NSDate *)timestamp errorConfiguration:(FBSDKErrorConfiguration *)errorConfiguration sessionTimeoutInterval:(NSTimeInterval) sessionTimeoutInterval defaults:(BOOL)defaults loggingToken:(NSString *)loggingToken { if ((self = [super init])) { _appID = [appID copy]; _appName = [appName copy]; _loginTooltipEnabled = loginTooltipEnabled; _loginTooltipText = [loginTooltipText copy]; _defaultShareMode = defaultShareMode; _advertisingIDEnabled = advertisingIDEnabled; _implicitLoggingEnabled = implicitLoggingEnabled; _implicitPurchaseLoggingEnabled = implicitPurchaseLoggingEnabled; _systemAuthenticationEnabled = systemAuthenticationEnabled; _nativeAuthFlowEnabled = nativeAuthFlowEnabled; _dialogConfigurations = [dialogConfigurations copy]; _dialogFlows = [dialogFlows copy]; _timestamp = [timestamp copy]; _errorConfiguration = [errorConfiguration copy]; _sessionTimoutInterval = sessionTimeoutInterval; _defaults = defaults; _loggingToken = loggingToken; } return self; } #pragma mark - Public Methods - (FBSDKDialogConfiguration *)dialogConfigurationForDialogName:(NSString *)dialogName { return _dialogConfigurations[dialogName]; } - (BOOL)useNativeDialogForDialogName:(NSString *)dialogName { return [self _useFeatureWithKey:FBSDKDialogConfigurationFeatureUseNativeFlow dialogName:dialogName]; } - (BOOL)useSafariViewControllerForDialogName:(NSString *)dialogName { return [self _useFeatureWithKey:FBSDKDialogConfigurationFeatureUseSafariViewController dialogName:dialogName]; } #pragma mark - Helper Methods - (BOOL)_useFeatureWithKey:(NSString *)key dialogName:(NSString *)dialogName { if ([dialogName isEqualToString:FBSDKDialogConfigurationNameLogin]) { return [(NSNumber *)(_dialogFlows[dialogName][key] ?: _dialogFlows[FBSDKDialogConfigurationNameDefault][key]) boolValue]; } else { return [(NSNumber *)(_dialogFlows[dialogName][key] ?: _dialogFlows[FBSDKDialogConfigurationNameSharing][key] ?: _dialogFlows[FBSDKDialogConfigurationNameDefault][key]) boolValue]; } } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { NSString *appID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SERVER_CONFIGURATION_APP_ID_KEY]; NSString *appName = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SERVER_CONFIGURATION_APP_NAME_KEY]; BOOL loginTooltipEnabled = [decoder decodeBoolForKey:FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_ENABLED_KEY]; NSString *loginTooltipText = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_TEXT_KEY]; NSString *defaultShareMode = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SERVER_CONFIGURATION_DEFAULT_SHARE_MODE_KEY]; BOOL advertisingIDEnabled = [decoder decodeBoolForKey:FBSDK_SERVER_CONFIGURATION_ADVERTISING_ID_ENABLED_KEY]; BOOL implicitLoggingEnabled = [decoder decodeBoolForKey:FBSDK_SERVER_CONFIGURATION_IMPLICIT_LOGGING_ENABLED_KEY]; BOOL implicitPurchaseLoggingEnabled = [decoder decodeBoolForKey:FBSDK_SERVER_CONFIGURATION_IMPLICIT_PURCHASE_LOGGING_ENABLED_KEY]; BOOL systemAuthenticationEnabled = [decoder decodeBoolForKey:FBSDK_SERVER_CONFIGURATION_SYSTEM_AUTHENTICATION_ENABLED_KEY]; BOOL nativeAuthFlowEnabled = [decoder decodeBoolForKey:FBSDK_SERVER_CONFIGURATION_NATIVE_AUTH_FLOW_ENABLED_KEY]; NSDate *timestamp = [decoder decodeObjectOfClass:[NSDate class] forKey:FBSDK_SERVER_CONFIGURATION_TIMESTAMP_KEY]; NSSet *dialogConfigurationsClasses = [[NSSet alloc] initWithObjects: [NSDictionary class], [FBSDKDialogConfiguration class], nil]; NSDictionary *dialogConfigurations = [decoder decodeObjectOfClasses:dialogConfigurationsClasses forKey:FBSDK_SERVER_CONFIGURATION_DIALOG_CONFIGS_KEY]; NSSet *dialogFlowsClasses = [[NSSet alloc] initWithObjects: [NSDictionary class], [NSString class], [NSNumber class], nil]; NSDictionary *dialogFlows = [decoder decodeObjectOfClasses:dialogFlowsClasses forKey:FBSDK_SERVER_CONFIGURATION_DIALOG_FLOWS_KEY]; FBSDKErrorConfiguration *errorConfiguration = [decoder decodeObjectOfClass:[FBSDKErrorConfiguration class] forKey:FBSDK_SERVER_CONFIGURATION_ERROR_CONFIGS_KEY]; NSTimeInterval sessionTimeoutInterval = [decoder decodeDoubleForKey:FBSDK_SERVER_CONFIGURATION_SESSION_TIMEOUT_INTERVAL]; NSString *loggingToken = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SERVER_CONFIGURATION_LOGGING_TOKEN]; return [self initWithAppID:appID appName:appName loginTooltipEnabled:loginTooltipEnabled loginTooltipText:loginTooltipText defaultShareMode:defaultShareMode advertisingIDEnabled:advertisingIDEnabled implicitLoggingEnabled:implicitLoggingEnabled implicitPurchaseLoggingEnabled:implicitPurchaseLoggingEnabled systemAuthenticationEnabled:systemAuthenticationEnabled nativeAuthFlowEnabled:nativeAuthFlowEnabled dialogConfigurations:dialogConfigurations dialogFlows:dialogFlows timestamp:timestamp errorConfiguration:errorConfiguration sessionTimeoutInterval:sessionTimeoutInterval defaults:NO loggingToken:loggingToken]; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeBool:_advertisingIDEnabled forKey:FBSDK_SERVER_CONFIGURATION_ADVERTISING_ID_ENABLED_KEY]; [encoder encodeObject:_appID forKey:FBSDK_SERVER_CONFIGURATION_APP_ID_KEY]; [encoder encodeObject:_appName forKey:FBSDK_SERVER_CONFIGURATION_APP_NAME_KEY]; [encoder encodeObject:_defaultShareMode forKey:FBSDK_SERVER_CONFIGURATION_DEFAULT_SHARE_MODE_KEY]; [encoder encodeObject:_dialogConfigurations forKey:FBSDK_SERVER_CONFIGURATION_DIALOG_CONFIGS_KEY]; [encoder encodeObject:_dialogFlows forKey:FBSDK_SERVER_CONFIGURATION_DIALOG_FLOWS_KEY]; [encoder encodeObject:_errorConfiguration forKey:FBSDK_SERVER_CONFIGURATION_ERROR_CONFIGS_KEY]; [encoder encodeBool:_implicitLoggingEnabled forKey:FBSDK_SERVER_CONFIGURATION_IMPLICIT_LOGGING_ENABLED_KEY]; [encoder encodeBool:_implicitPurchaseLoggingEnabled forKey:FBSDK_SERVER_CONFIGURATION_IMPLICIT_PURCHASE_LOGGING_ENABLED_KEY]; [encoder encodeBool:_loginTooltipEnabled forKey:FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_ENABLED_KEY]; [encoder encodeObject:_loginTooltipText forKey:FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_TEXT_KEY]; [encoder encodeBool:_nativeAuthFlowEnabled forKey:FBSDK_SERVER_CONFIGURATION_NATIVE_AUTH_FLOW_ENABLED_KEY]; [encoder encodeBool:_systemAuthenticationEnabled forKey:FBSDK_SERVER_CONFIGURATION_SYSTEM_AUTHENTICATION_ENABLED_KEY]; [encoder encodeObject:_timestamp forKey:FBSDK_SERVER_CONFIGURATION_TIMESTAMP_KEY]; [encoder encodeDouble:_sessionTimoutInterval forKey:FBSDK_SERVER_CONFIGURATION_SESSION_TIMEOUT_INTERVAL]; [encoder encodeObject:_loggingToken forKey:FBSDK_SERVER_CONFIGURATION_LOGGING_TOKEN]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { return self; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfigurationManager+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKServerConfigurationManager.h" @class FBSDKGraphRequest; @interface FBSDKServerConfigurationManager () + (void)processLoadRequestResponse:(id)result error:(NSError *)error appID:(NSString *)appID; + (FBSDKGraphRequest *)requestToLoadServerConfiguration:(NSString *)appID; + (void)clearCache; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfigurationManager.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKServerConfiguration.h" typedef void(^FBSDKServerConfigurationManagerLoadBlock)(FBSDKServerConfiguration *serverConfiguration, NSError *error); @interface FBSDKServerConfigurationManager : NSObject /** @abstract Returns the locally cached configuration. @discussion The result will be valid for the appID from FBSDKSettings, but may be expired. A network request will be initiated to update the configuration if a valid and unexpired configuration is not available. */ + (FBSDKServerConfiguration *)cachedServerConfiguration; /** @abstract Executes the completionBlock with a valid and current configuration when it is available. @discussion This method will use a cached configuration if it is valid and not expired. */ + (void)loadServerConfigurationWithCompletionBlock:(FBSDKServerConfigurationManagerLoadBlock)completionBlock; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfigurationManager.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKServerConfigurationManager+Internal.h" #import "FBSDKGraphRequest+Internal.h" #import "FBSDKGraphRequest.h" #import "FBSDKInternalUtility.h" #import "FBSDKLogger.h" #import "FBSDKServerConfiguration+Internal.h" #import "FBSDKServerConfiguration.h" #import "FBSDKSettings.h" #import "FBSDKTypeUtility.h" // one hour #define DEFAULT_SESSION_TIMEOUT_INTERVAL 60 #define FBSDK_SERVER_CONFIGURATION_MANAGER_CACHE_TIMEOUT (60 * 60) #define FBSDK_SERVER_CONFIGURATION_USER_DEFAULTS_KEY @"com.facebook.sdk:serverConfiguration%@" #define FBSDK_SERVER_CONFIGURATION_APP_EVENTS_FEATURES_FIELD @"app_events_feature_bitmask" #define FBSDK_SERVER_CONFIGURATION_APP_NAME_FIELD @"name" #define FBSDK_SERVER_CONFIGURATION_DEFAULT_SHARE_MODE_FIELD @"default_share_mode" #define FBSDK_SERVER_CONFIGURATION_DIALOG_CONFIGS_FIELD @"ios_dialog_configs" #define FBSDK_SERVER_CONFIGURATION_DIALOG_FLOWS_FIELD @"ios_sdk_dialog_flows" #define FBSDK_SERVER_CONFIGURATION_ERROR_CONFIGURATION_FIELD @"ios_sdk_error_categories" #define FBSDK_SERVER_CONFIGURATION_IMPLICIT_LOGGING_ENABLED_FIELD @"supports_implicit_sdk_logging" #define FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_ENABLED_FIELD @"gdpv4_nux_enabled" #define FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_TEXT_FIELD @"gdpv4_nux_content" #define FBSDK_SERVER_CONFIGURATION_NATIVE_PROXY_AUTH_FLOW_ENABLED_FIELD @"ios_supports_native_proxy_auth_flow" #define FBSDK_SERVER_CONFIGURATION_SYSTEM_AUTHENTICATION_ENABLED_FIELD @"ios_supports_system_auth" #define FBSDK_SERVER_CONFIGURATION_SESSION_TIMEOUT_FIELD @"app_events_session_timeout" #define FBSDK_SERVER_CONFIGURATION_LOGGIN_TOKEN_FIELD @"logging_token" @implementation FBSDKServerConfigurationManager static NSMutableArray *_completionBlocks; static BOOL _loadingServerConfiguration; static FBSDKServerConfiguration *_serverConfiguration; static NSError *_serverConfigurationError; static NSDate *_serverConfigurationErrorTimestamp; static const NSTimeInterval kTimeout = 4.0; typedef NS_OPTIONS(NSUInteger, FBSDKServerConfigurationManagerAppEventsFeatures) { FBSDKServerConfigurationManagerAppEventsFeaturesNone = 0, FBSDKServerConfigurationManagerAppEventsFeaturesAdvertisingIDEnabled = 1 << 0, FBSDKServerConfigurationManagerAppEventsFeaturesImplicitPurchaseLoggingEnabled = 1 << 1, }; #pragma mark - Public Class Methods + (void)initialize { if (self == [FBSDKServerConfigurationManager class]) { _completionBlocks = [[NSMutableArray alloc] init]; } } + (void)clearCache { _serverConfiguration = nil; _serverConfigurationError = nil; _serverConfigurationErrorTimestamp = nil; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *defaultsKey = [NSString stringWithFormat:FBSDK_SERVER_CONFIGURATION_USER_DEFAULTS_KEY, [FBSDKSettings appID]]; [defaults removeObjectForKey:defaultsKey]; [defaults synchronize]; } + (FBSDKServerConfiguration *)cachedServerConfiguration { NSString *appID = [FBSDKSettings appID]; @synchronized(self) { // load the server configuration if we don't have it already [self loadServerConfigurationWithCompletionBlock:NULL]; // use whatever configuration we have or the default return _serverConfiguration ?: [self _defaultServerConfigurationForAppID:appID]; } } + (void)loadServerConfigurationWithCompletionBlock:(FBSDKServerConfigurationManagerLoadBlock)completionBlock { void (^loadBlock)(void) = NULL; NSString *appID = [FBSDKSettings appID]; @synchronized(self) { // validate the cached configuration has the correct appID if (_serverConfiguration && ![_serverConfiguration.appID isEqualToString:appID]) { _serverConfiguration = nil; _serverConfigurationError = nil; _serverConfigurationErrorTimestamp = nil; } // load the configuration from NSUserDefaults if (!_serverConfiguration) { // load the defaults NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *defaultsKey = [NSString stringWithFormat:FBSDK_SERVER_CONFIGURATION_USER_DEFAULTS_KEY, appID]; NSData *data = [defaults objectForKey:defaultsKey]; if ([data isKindOfClass:[NSData class]]) { // decode the configuration FBSDKServerConfiguration *serverConfiguration = [NSKeyedUnarchiver unarchiveObjectWithData:data]; if ([serverConfiguration isKindOfClass:[FBSDKServerConfiguration class]]) { // ensure that the configuration points to the current appID if ([serverConfiguration.appID isEqualToString:appID]) { _serverConfiguration = serverConfiguration; } } } } if ((_serverConfiguration && [self _serverConfigurationTimestampIsValid:_serverConfiguration.timestamp]) || (_serverConfigurationErrorTimestamp && [self _serverConfigurationTimestampIsValid:_serverConfigurationErrorTimestamp])) { // we have a valid server configuration, use that loadBlock = [self _wrapperBlockForLoadBlock:completionBlock]; } else { // hold onto the completion block [FBSDKInternalUtility array:_completionBlocks addObject:[completionBlock copy]]; // check if we are already loading if (!_loadingServerConfiguration) { // load the configuration from the network _loadingServerConfiguration = YES; FBSDKGraphRequest *request = [[self class] requestToLoadServerConfiguration:appID]; // start request with specified timeout instead of the default 180s FBSDKGraphRequestConnection *requestConnection = [[FBSDKGraphRequestConnection alloc] init]; requestConnection.timeout = kTimeout; [requestConnection addRequest:request completionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { [self processLoadRequestResponse:result error:error appID:appID]; }]; [requestConnection start]; } } } if (loadBlock != NULL) { loadBlock(); } } #pragma mark - Internal Class Methods + (void)processLoadRequestResponse:(id)result error:(NSError *)error appID:(NSString *)appID { if (error) { [self _didProcessConfigurationFromNetwork:nil appID:appID error:error]; return; } NSDictionary *resultDictionary = [FBSDKTypeUtility dictionaryValue:result]; NSUInteger appEventsFeatures = [FBSDKTypeUtility unsignedIntegerValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_APP_EVENTS_FEATURES_FIELD]]; BOOL advertisingIDEnabled = (appEventsFeatures & FBSDKServerConfigurationManagerAppEventsFeaturesAdvertisingIDEnabled); BOOL implicitPurchaseLoggingEnabled = (appEventsFeatures & FBSDKServerConfigurationManagerAppEventsFeaturesImplicitPurchaseLoggingEnabled); NSString *appName = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_APP_NAME_FIELD]]; BOOL loginTooltipEnabled = [FBSDKTypeUtility boolValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_ENABLED_FIELD]]; NSString *loginTooltipText = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_TEXT_FIELD]]; NSString *defaultShareMode = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_DEFAULT_SHARE_MODE_FIELD]]; BOOL implicitLoggingEnabled = [FBSDKTypeUtility boolValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_IMPLICIT_LOGGING_ENABLED_FIELD]]; BOOL systemAuthenticationEnabled = [FBSDKTypeUtility boolValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_SYSTEM_AUTHENTICATION_ENABLED_FIELD]]; BOOL nativeAuthFlowEnabled = [FBSDKTypeUtility boolValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_NATIVE_PROXY_AUTH_FLOW_ENABLED_FIELD]]; NSDictionary *dialogConfigurations = [FBSDKTypeUtility dictionaryValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_DIALOG_CONFIGS_FIELD]]; dialogConfigurations = [self _parseDialogConfigurations:dialogConfigurations]; NSDictionary *dialogFlows = [FBSDKTypeUtility dictionaryValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_DIALOG_FLOWS_FIELD]]; FBSDKErrorConfiguration *errorConfiguration = [[FBSDKErrorConfiguration alloc] initWithDictionary:nil]; [errorConfiguration parseArray:resultDictionary[FBSDK_SERVER_CONFIGURATION_ERROR_CONFIGURATION_FIELD]]; NSTimeInterval sessionTimeoutInterval = [FBSDKTypeUtility timeIntervalValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_SESSION_TIMEOUT_FIELD]] ?: DEFAULT_SESSION_TIMEOUT_INTERVAL; NSString *loggingToken = [FBSDKTypeUtility stringValue:resultDictionary[FBSDK_SERVER_CONFIGURATION_LOGGIN_TOKEN_FIELD]]; FBSDKServerConfiguration *serverConfiguration = [[FBSDKServerConfiguration alloc] initWithAppID:appID appName:appName loginTooltipEnabled:loginTooltipEnabled loginTooltipText:loginTooltipText defaultShareMode:defaultShareMode advertisingIDEnabled:advertisingIDEnabled implicitLoggingEnabled:implicitLoggingEnabled implicitPurchaseLoggingEnabled:implicitPurchaseLoggingEnabled systemAuthenticationEnabled:systemAuthenticationEnabled nativeAuthFlowEnabled:nativeAuthFlowEnabled dialogConfigurations:dialogConfigurations dialogFlows:dialogFlows timestamp:[NSDate date] errorConfiguration:errorConfiguration sessionTimeoutInterval:sessionTimeoutInterval defaults:NO loggingToken:loggingToken]; [self _didProcessConfigurationFromNetwork:serverConfiguration appID:appID error:nil]; } + (FBSDKGraphRequest *)requestToLoadServerConfiguration:(NSString *)appID { NSOperatingSystemVersion operatingSystemVersion = [FBSDKInternalUtility operatingSystemVersion]; NSString *dialogFlowsField = [NSString stringWithFormat:@"%@.os_version(%ti.%ti.%ti)", FBSDK_SERVER_CONFIGURATION_DIALOG_FLOWS_FIELD, operatingSystemVersion.majorVersion, operatingSystemVersion.minorVersion, operatingSystemVersion.patchVersion]; NSArray *fields = @[FBSDK_SERVER_CONFIGURATION_APP_EVENTS_FEATURES_FIELD, FBSDK_SERVER_CONFIGURATION_APP_NAME_FIELD, FBSDK_SERVER_CONFIGURATION_DEFAULT_SHARE_MODE_FIELD, FBSDK_SERVER_CONFIGURATION_DIALOG_CONFIGS_FIELD, dialogFlowsField, FBSDK_SERVER_CONFIGURATION_ERROR_CONFIGURATION_FIELD, FBSDK_SERVER_CONFIGURATION_IMPLICIT_LOGGING_ENABLED_FIELD, FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_ENABLED_FIELD, FBSDK_SERVER_CONFIGURATION_LOGIN_TOOLTIP_TEXT_FIELD, FBSDK_SERVER_CONFIGURATION_NATIVE_PROXY_AUTH_FLOW_ENABLED_FIELD, FBSDK_SERVER_CONFIGURATION_SYSTEM_AUTHENTICATION_ENABLED_FIELD, FBSDK_SERVER_CONFIGURATION_SESSION_TIMEOUT_FIELD, FBSDK_SERVER_CONFIGURATION_LOGGIN_TOKEN_FIELD, ]; NSDictionary *parameters = @{ @"fields": [fields componentsJoinedByString:@","] }; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:appID parameters:parameters tokenString:nil HTTPMethod:nil flags:FBSDKGraphRequestFlagSkipClientToken | FBSDKGraphRequestFlagDisableErrorRecovery]; return request; } #pragma mark - Helper Class Methods + (FBSDKServerConfiguration *)_defaultServerConfigurationForAppID:(NSString *)appID { // Use a default configuration while we do not have a configuration back from the server. This allows us to set // the default values for any of the dialog sets or anything else in a centralized location while we are waiting for // the server to respond. static FBSDKServerConfiguration *_defaultServerConfiguration = nil; if (![_defaultServerConfiguration.appID isEqualToString:appID]) { // Bypass the native dialog flow for iOS 9+, as it produces a series of additional confirmation dialogs that lead to // extra friction that is not desirable. NSOperatingSystemVersion iOS9Version = { .majorVersion = 9, .minorVersion = 0, .patchVersion = 0 }; BOOL useNativeFlow = ![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS9Version]; // Also enable SFSafariViewController by default. NSDictionary *dialogFlows = @{ FBSDKDialogConfigurationNameDefault: @{ FBSDKDialogConfigurationFeatureUseNativeFlow: @(useNativeFlow), FBSDKDialogConfigurationFeatureUseSafariViewController: @YES, }, FBSDKDialogConfigurationNameMessage: @{ FBSDKDialogConfigurationFeatureUseNativeFlow: @YES, }, }; _defaultServerConfiguration = [[FBSDKServerConfiguration alloc] initWithAppID:appID appName:nil loginTooltipEnabled:NO loginTooltipText:nil defaultShareMode:nil advertisingIDEnabled:NO implicitLoggingEnabled:NO implicitPurchaseLoggingEnabled:NO systemAuthenticationEnabled:NO nativeAuthFlowEnabled:NO dialogConfigurations:nil dialogFlows:dialogFlows timestamp:nil errorConfiguration:nil sessionTimeoutInterval:DEFAULT_SESSION_TIMEOUT_INTERVAL defaults:YES loggingToken:nil]; } return _defaultServerConfiguration; } + (void)_didProcessConfigurationFromNetwork:(FBSDKServerConfiguration *)serverConfiguration appID:(NSString *)appID error:(NSError *)error { NSMutableArray *completionBlocks = [[NSMutableArray alloc] init]; @synchronized(self) { if (error) { // Only set the error if we don't have previously fetched app settings. // (i.e., if we have app settings and a new call gets an error, we'll // ignore the error and surface the last successfully fetched settings). if (_serverConfiguration && [_serverConfiguration.appID isEqualToString:appID]) { // We have older app settings but the refresh received an error. // Log and ignore the error. [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorInformational formatString:@"loadServerConfigurationWithCompletionBlock failed with %@", error]; } else { _serverConfiguration = nil; } _serverConfigurationError = error; _serverConfigurationErrorTimestamp = [NSDate date]; } else { _serverConfiguration = serverConfiguration; _serverConfigurationError = nil; _serverConfigurationErrorTimestamp = nil; } // update the cached copy in NSUserDefaults NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *defaultsKey = [NSString stringWithFormat:FBSDK_SERVER_CONFIGURATION_USER_DEFAULTS_KEY, appID]; if (serverConfiguration) { NSData *data = [NSKeyedArchiver archivedDataWithRootObject:serverConfiguration]; [defaults setObject:data forKey:defaultsKey]; } // wrap the completion blocks for (FBSDKServerConfigurationManagerLoadBlock completionBlock in _completionBlocks) { [completionBlocks addObject:[self _wrapperBlockForLoadBlock:completionBlock]]; } [_completionBlocks removeAllObjects]; _loadingServerConfiguration = NO; } // release the lock before calling out of this class for (void (^completionBlock)(void) in completionBlocks) { completionBlock(); } } + (NSDictionary *)_parseDialogConfigurations:(NSDictionary *)dictionary { NSMutableDictionary *dialogConfigurations = [[NSMutableDictionary alloc] init]; NSArray *dialogConfigurationsArray = [FBSDKTypeUtility arrayValue:dictionary[@"data"]]; for (id dialogConfiguration in dialogConfigurationsArray) { NSDictionary *dialogConfigurationDictionary = [FBSDKTypeUtility dictionaryValue:dialogConfiguration]; if (dialogConfigurationDictionary) { NSString *name = [FBSDKTypeUtility stringValue:dialogConfigurationDictionary[@"name"]]; if ([name length]) { NSURL *URL = [FBSDKTypeUtility URLValue:dialogConfigurationDictionary[@"url"]]; NSArray *appVersions = [FBSDKTypeUtility arrayValue:dialogConfigurationDictionary[@"versions"]]; dialogConfigurations[name] = [[FBSDKDialogConfiguration alloc] initWithName:name URL:URL appVersions:appVersions]; } } } return dialogConfigurations; } + (BOOL)_serverConfigurationTimestampIsValid:(NSDate *)timestamp { return ([[NSDate date] timeIntervalSinceDate:timestamp] < FBSDK_SERVER_CONFIGURATION_MANAGER_CACHE_TIMEOUT); } + (void(^)(void))_wrapperBlockForLoadBlock:(FBSDKServerConfigurationManagerLoadBlock)loadBlock { if (loadBlock == NULL) { return NULL; } // create local vars to capture the current values from the ivars to allow this wrapper to be called outside of a lock FBSDKServerConfiguration *serverConfiguration; NSError *serverConfigurationError; @synchronized(self) { serverConfiguration = _serverConfiguration; serverConfigurationError = _serverConfigurationError; } return ^{ loadBlock(serverConfiguration, serverConfigurationError); }; } #pragma mark - Object Lifecycle - (instancetype)init { return nil; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCache.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import "FBSDKAccessTokenCaching.h" @interface FBSDKAccessTokenCache : NSObject @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCache.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAccessTokenCache.h" #import "FBSDKAccessTokenCacheV3.h" #import "FBSDKAccessTokenCacheV3_17.h" #import "FBSDKAccessTokenCacheV3_21.h" #import "FBSDKAccessTokenCacheV4.h" static BOOL g_tryDeprecatedCaches = YES; @implementation FBSDKAccessTokenCache - (FBSDKAccessToken*)fetchAccessToken { FBSDKAccessToken *token = [[[FBSDKAccessTokenCacheV4 alloc] init] fetchAccessToken]; if (token || !g_tryDeprecatedCaches) { return token; } g_tryDeprecatedCaches = NO; NSArray *oldCacheClasses = [[self class] deprecatedCacheClasses]; __block FBSDKAccessToken *oldToken = nil; [oldCacheClasses enumerateObjectsUsingBlock:^(Class obj, NSUInteger idx, BOOL *stop) { id cache = [[obj alloc] init]; oldToken = [cache fetchAccessToken]; if (oldToken) { *stop = YES; [cache clearCache]; } }]; if (oldToken) { [self cacheAccessToken:oldToken]; } return oldToken; } - (void)cacheAccessToken:(FBSDKAccessToken *)token { [[[FBSDKAccessTokenCacheV4 alloc] init] cacheAccessToken:token]; if (g_tryDeprecatedCaches) { g_tryDeprecatedCaches = NO; NSArray *oldCacheClasses = [[self class] deprecatedCacheClasses]; [oldCacheClasses enumerateObjectsUsingBlock:^(Class obj, NSUInteger idx, BOOL *stop) { id cache = [[obj alloc] init]; [cache clearCache]; }]; } } - (void)clearCache { [[[FBSDKAccessTokenCacheV4 alloc] init] clearCache]; } // used by FBSDKAccessTokenCacheIntegrationTests + (void)resetV3CacheChecks { g_tryDeprecatedCaches = YES; } + (NSArray *)deprecatedCacheClasses { return @[ [FBSDKAccessTokenCacheV3_21 class], [FBSDKAccessTokenCacheV3_17 class], [FBSDKAccessTokenCacheV3 class]]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV3.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKAccessTokenCaching.h" #import "FBSDKMacros.h" FBSDK_EXTERN NSString *const FBSDKTokenInformationUUIDKey; @interface FBSDKAccessTokenCacheV3 : NSObject + (FBSDKAccessToken *)accessTokenForV3Dictionary:(NSDictionary *)dictionary; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV3.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAccessTokenCacheV3.h" #import "FBSDKAccessToken.h" #import "FBSDKSettings.h" #import "FBSDKTypeUtility.h" NSString *const FBSDKTokenInformationUUIDKey = @"com.facebook.sdk:TokenInformationUUIDKey"; #define FBSDK_TOKEN_INFORMATION_TOKEN_KEY @"com.facebook.sdk:TokenInformationTokenKey" #define FBSDK_TOKEN_INFORMATION_EXPIRATION_DATE_KEY @"com.facebook.sdk:TokenInformationExpirationDateKey" #define FBSDK_TOKEN_INFORMATION_USER_FBID_KEY @"com.facebook.sdk:TokenInformationUserFBIDKey" #define FBSDK_TOKEN_INFORMATION_PERMISSIONS_KEY @"com.facebook.sdk:TokenInformationPermissionsKey" #define FBSDK_TOKEN_INFORMATION_DECLINED_PERMISSIONS_KEY @"com.facebook.sdk:TokenInformationDeclinedPermissionsKey" #define FBSDK_TOKEN_INFORMATION_APP_ID_KEY @"com.facebook.sdk:TokenInformationAppIDKey" #define FBSDK_TOKEN_INFORMATION_REFRESH_DATE_KEY @"com.facebook.sdk:TokenInformationRefreshDateKey" @implementation FBSDKAccessTokenCacheV3 - (FBSDKAccessToken *)fetchAccessToken { // Check NSUserDefaults ( <= v3.16 ) NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSDictionary *tokenDictionary = [defaults objectForKey:[FBSDKSettings legacyUserDefaultTokenInformationKeyName]]; return [[self class] accessTokenForV3Dictionary:tokenDictionary]; } - (void)clearCache { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults removeObjectForKey:[FBSDKSettings legacyUserDefaultTokenInformationKeyName]]; [defaults synchronize]; } - (void)cacheAccessToken:(FBSDKAccessToken *)token { //no-op. NSAssert(NO, @"deprecated cache FBSDKAccessTokenCacheV3 should not be used to cache a token"); } + (FBSDKAccessToken *)accessTokenForV3Dictionary:(NSDictionary *)dictionary { NSString *tokenString = [FBSDKTypeUtility stringValue:dictionary[FBSDK_TOKEN_INFORMATION_TOKEN_KEY]]; if (tokenString.length > 0) { NSDate *expirationDate = dictionary[FBSDK_TOKEN_INFORMATION_EXPIRATION_DATE_KEY]; // Note we default to valid in cases where expiration date is missing. BOOL isExpired = ([expirationDate compare:[NSDate date]] == NSOrderedAscending); if (isExpired) { return nil; } return [[FBSDKAccessToken alloc] initWithTokenString:tokenString permissions:dictionary[FBSDK_TOKEN_INFORMATION_PERMISSIONS_KEY] declinedPermissions:dictionary[FBSDK_TOKEN_INFORMATION_DECLINED_PERMISSIONS_KEY] appID:dictionary[FBSDK_TOKEN_INFORMATION_APP_ID_KEY] userID:dictionary[FBSDK_TOKEN_INFORMATION_USER_FBID_KEY] expirationDate:expirationDate refreshDate:dictionary[FBSDK_TOKEN_INFORMATION_REFRESH_DATE_KEY]]; } return nil; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV3_17.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKAccessTokenCaching.h" @interface FBSDKAccessTokenCacheV3_17 : NSObject @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV3_17.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAccessTokenCacheV3_17.h" #import "FBSDKAccessToken.h" #import "FBSDKAccessTokenCacheV3.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKKeychainStoreViaBundleID.h" #import "FBSDKSettings.h" @implementation FBSDKAccessTokenCacheV3_17 { FBSDKKeychainStoreViaBundleID *_keychainStore; } - (instancetype)init { if ((self = [super init])) { _keychainStore = [[FBSDKKeychainStoreViaBundleID alloc] init]; } return self; } - (FBSDKAccessToken *)fetchAccessToken { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *uuidKey = [[FBSDKSettings legacyUserDefaultTokenInformationKeyName] stringByAppendingString:@"UUID"]; NSString *uuid = [defaults objectForKey:uuidKey]; NSDictionary *tokenDictionary = [_keychainStore dictionaryForKey:[FBSDKSettings legacyUserDefaultTokenInformationKeyName]]; if (![tokenDictionary[FBSDKTokenInformationUUIDKey] isEqualToString:uuid]) { [self clearCache]; } return [FBSDKAccessTokenCacheV3 accessTokenForV3Dictionary:tokenDictionary]; } - (void)clearCache { [_keychainStore setDictionary:nil forKey:[FBSDKSettings legacyUserDefaultTokenInformationKeyName] accessibility:nil]; } - (void)cacheAccessToken:(FBSDKAccessToken *)token { //no-op. NSAssert(NO, @"deprecated cache FBSDKAccessTokenCacheV3_17 should not be used to cache a token"); } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV3_21.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKAccessTokenCaching.h" @interface FBSDKAccessTokenCacheV3_21 : NSObject @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV3_21.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAccessTokenCacheV3_21.h" #import "FBSDKAccessToken.h" #import "FBSDKAccessTokenCacheV3.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKKeychainStore.h" #import "FBSDKSettings.h" @implementation FBSDKAccessTokenCacheV3_21 { FBSDKKeychainStore *_keychainStore; } - (instancetype)init { if ((self = [super init])) { NSString *keyChainServiceIdentifier = [NSString stringWithFormat:@"com.facebook.sdk.tokencache.%@", [[NSBundle mainBundle] bundleIdentifier]]; _keychainStore = [[FBSDKKeychainStore alloc] initWithService:keyChainServiceIdentifier accessGroup:nil]; } return self; } - (FBSDKAccessToken *)fetchAccessToken { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *uuidKey = [[FBSDKSettings legacyUserDefaultTokenInformationKeyName] stringByAppendingString:@"UUID"]; NSString *uuid = [defaults objectForKey:uuidKey]; NSDictionary *tokenDictionary = [_keychainStore dictionaryForKey:[FBSDKSettings legacyUserDefaultTokenInformationKeyName]]; if (![tokenDictionary[FBSDKTokenInformationUUIDKey] isEqualToString:uuid]) { [self clearCache]; } return [FBSDKAccessTokenCacheV3 accessTokenForV3Dictionary:tokenDictionary]; } - (void)clearCache { [_keychainStore setDictionary:nil forKey:[FBSDKSettings legacyUserDefaultTokenInformationKeyName] accessibility:nil]; } - (void)cacheAccessToken:(FBSDKAccessToken *)token { //no-op. NSAssert(NO, @"deprecated cache FBSDKAccessTokenCacheV3_21 should not be used to cache a token"); } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV4.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKAccessToken.h" #import "FBSDKAccessTokenCaching.h" @interface FBSDKAccessTokenCacheV4 : NSObject @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV4.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAccessTokenCacheV4.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKInternalUtility.h" #import "FBSDKKeychainStore.h" static NSString *const kFBSDKAccessTokenUserDefaultsKey = @"com.facebook.sdk.v4.FBSDKAccessTokenInformationKey"; static NSString *const kFBSDKAccessTokenUUIDKey = @"tokenUUID"; static NSString *const kFBSDKAccessTokenEncodedKey = @"tokenEncoded"; @implementation FBSDKAccessTokenCacheV4 { FBSDKKeychainStore *_keychainStore; } - (instancetype)init { if ((self = [super init])) { NSString *keyChainServiceIdentifier = [NSString stringWithFormat:@"com.facebook.sdk.tokencache.%@", [[NSBundle mainBundle] bundleIdentifier]]; _keychainStore = [[FBSDKKeychainStore alloc] initWithService:keyChainServiceIdentifier accessGroup:nil]; } return self; } - (FBSDKAccessToken *)fetchAccessToken { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *uuid = [defaults objectForKey:kFBSDKAccessTokenUserDefaultsKey]; NSDictionary *dict = [_keychainStore dictionaryForKey:kFBSDKAccessTokenUserDefaultsKey]; if (![dict[kFBSDKAccessTokenUUIDKey] isEqualToString:uuid]) { // if the uuid doesn't match (including if there is no uuid in defaults which means uninstalled case) // clear the keychain and return nil. [self clearCache]; return nil; } id tokenData = dict[kFBSDKAccessTokenEncodedKey]; if ([tokenData isKindOfClass:[NSData class]]) { return [NSKeyedUnarchiver unarchiveObjectWithData:tokenData]; } else { return nil; } } - (void)cacheAccessToken:(FBSDKAccessToken *)token { if (!token) { [self clearCache]; return; } NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSString *uuid = [defaults objectForKey:kFBSDKAccessTokenUserDefaultsKey]; if (!uuid) { uuid = [[NSUUID UUID] UUIDString]; [defaults setObject:uuid forKey:kFBSDKAccessTokenUserDefaultsKey]; [defaults synchronize]; } NSData *tokenData = [NSKeyedArchiver archivedDataWithRootObject:token]; NSDictionary *dict = @{ kFBSDKAccessTokenUUIDKey : uuid, kFBSDKAccessTokenEncodedKey : tokenData }; [_keychainStore setDictionary:dict forKey:kFBSDKAccessTokenUserDefaultsKey accessibility:[FBSDKDynamicFrameworkLoader loadkSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]]; } - (void)clearCache { [_keychainStore setDictionary:nil forKey:kFBSDKAccessTokenUserDefaultsKey accessibility:NULL]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults removeObjectForKey:kFBSDKAccessTokenUserDefaultsKey]; [defaults synchronize]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCaching.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @class FBSDKAccessToken; @protocol FBSDKAccessTokenCaching - (FBSDKAccessToken *)fetchAccessToken; - (void)cacheAccessToken:(FBSDKAccessToken *)token; - (void)clearCache; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStore.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @interface FBSDKKeychainStore : NSObject @property (nonatomic, readonly, copy) NSString *service; @property (nonatomic, readonly, copy) NSString *accessGroup; - (instancetype)initWithService:(NSString *)service accessGroup:(NSString *)accessGroup NS_DESIGNATED_INITIALIZER; - (BOOL)setDictionary:(NSDictionary *)value forKey:(NSString *)key accessibility:(CFTypeRef)accessibility; - (NSDictionary *)dictionaryForKey:(NSString *)key; - (BOOL)setString:(NSString *)value forKey:(NSString *)key accessibility:(CFTypeRef)accessibility; - (NSString *)stringForKey:(NSString *)key; - (BOOL)setData:(NSData *)value forKey:(NSString *)key accessibility:(CFTypeRef)accessibility; - (NSData *)dataForKey:(NSString *)key; // hook for subclasses to override keychain query construction. - (NSMutableDictionary *)queryForKey:(NSString *)key; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStore.m ================================================ /** * Contains code from UICKeyChainStore * * Copyright (c) 2011 kishikawa katsumi * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #import "FBSDKKeychainStore.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKMacros.h" @implementation FBSDKKeychainStore - (instancetype)initWithService:(NSString *)service accessGroup:(NSString *)accessGroup { if ((self = [super init])) { _service = service ? [service copy] : [[NSBundle mainBundle] bundleIdentifier]; _accessGroup = [accessGroup copy]; NSAssert(_service, @"Keychain must be initialized with service"); } return self; } - (instancetype)init { FBSDK_NOT_DESIGNATED_INITIALIZER(initWithService:accessGroup:); return [self initWithService:nil accessGroup:nil]; } - (BOOL)setDictionary:(NSDictionary *)value forKey:(NSString *)key accessibility:(CFTypeRef)accessibility { NSData *data = value == nil ? nil : [NSKeyedArchiver archivedDataWithRootObject:value]; return [self setData:data forKey:key accessibility:accessibility]; } - (NSDictionary *)dictionaryForKey:(NSString *)key { NSData *data = [self dataForKey:key]; if (!data) { return nil; } NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithData:data]; if (![dict isKindOfClass:[NSDictionary class]]) { return nil; } return dict; } - (BOOL)setString:(NSString *)value forKey:(NSString *)key accessibility:(CFTypeRef)accessibility { NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding]; return [self setData:data forKey:key accessibility:accessibility]; } - (NSString *)stringForKey:(NSString *)key { NSData *data = [self dataForKey:key]; if (!data) { return nil; } return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; } - (BOOL)setData:(NSData *)value forKey:(NSString *)key accessibility:(CFTypeRef)accessibility { if (!key) { return NO; } NSMutableDictionary *query = [self queryForKey:key]; OSStatus status; if (value) { NSMutableDictionary *attributesToUpdate = [NSMutableDictionary dictionary]; [attributesToUpdate setObject:value forKey:[FBSDKDynamicFrameworkLoader loadkSecValueData]]; status = fbsdkdfl_SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributesToUpdate); if (status == errSecItemNotFound) { #if TARGET_OS_IPHONE || (defined(MAC_OS_X_VERSION_10_9) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9) if (accessibility) { [query setObject:(__bridge id)(accessibility) forKey:[FBSDKDynamicFrameworkLoader loadkSecAttrAccessible]]; } #endif [query setObject:value forKey:[FBSDKDynamicFrameworkLoader loadkSecValueData]]; status = fbsdkdfl_SecItemAdd((__bridge CFDictionaryRef)query, NULL); } } else { status = fbsdkdfl_SecItemDelete((__bridge CFDictionaryRef)query); if (status == errSecItemNotFound) { status = errSecSuccess; } } return (status == errSecSuccess); } - (NSData *)dataForKey:(NSString *)key { if (!key) { return nil; } NSMutableDictionary *query = [self queryForKey:key]; [query setObject:(id)kCFBooleanTrue forKey:[FBSDKDynamicFrameworkLoader loadkSecReturnData]]; [query setObject:[FBSDKDynamicFrameworkLoader loadkSecMatchLimitOne] forKey:[FBSDKDynamicFrameworkLoader loadkSecMatchLimit]]; CFTypeRef data = nil; OSStatus status = fbsdkdfl_SecItemCopyMatching((__bridge CFDictionaryRef)query, &data); if (status != errSecSuccess) { return nil; } if (!data || CFGetTypeID(data) != CFDataGetTypeID()) { return nil; } NSData *ret = [NSData dataWithData:(__bridge NSData *)(data)]; CFRelease(data); return ret; } - (NSMutableDictionary *)queryForKey:(NSString *)key { NSMutableDictionary *query = [NSMutableDictionary dictionary]; [query setObject:[FBSDKDynamicFrameworkLoader loadkSecClassGenericPassword] forKey:[FBSDKDynamicFrameworkLoader loadkSecClass]]; [query setObject:_service forKey:[FBSDKDynamicFrameworkLoader loadkSecAttrService]]; [query setObject:key forKey:[FBSDKDynamicFrameworkLoader loadkSecAttrAccount]]; #if !TARGET_IPHONE_SIMULATOR if (_accessGroup) { [query setObject:_accessGroup forKey:[FBSDKDynamicFrameworkLoader loadkSecAttrAccessGroup]]; } #endif return query; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStoreViaBundleID.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKKeychainStore.h" // This is the keychainstore defined in 3.17 that incorrectly used the bundle id as the service id // and should NOT be used outside of this cache. @interface FBSDKKeychainStoreViaBundleID : FBSDKKeychainStore // since this subclass represents the old keychainstore behavior, // the designated initializer is just the `init`. - (instancetype)init NS_DESIGNATED_INITIALIZER; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStoreViaBundleID.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKKeychainStoreViaBundleID.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKInternalUtility.h" @implementation FBSDKKeychainStoreViaBundleID - (instancetype)init { return [super initWithService:[[NSBundle mainBundle] bundleIdentifier] accessGroup:nil]; } - (instancetype)initWithService:(NSString *)service accessGroup:(NSString *)accessGroup { return [self init]; } - (NSMutableDictionary*)queryForKey:(NSString *)key { NSMutableDictionary *query = [NSMutableDictionary dictionary]; query[(__bridge id)[FBSDKDynamicFrameworkLoader loadkSecClass]] = (__bridge id)([FBSDKDynamicFrameworkLoader loadkSecClassGenericPassword]); query[(__bridge id)[FBSDKDynamicFrameworkLoader loadkSecAttrService]] = self.service; query[(__bridge id)[FBSDKDynamicFrameworkLoader loadkSecAttrGeneric]] = key; #if !TARGET_IPHONE_SIMULATOR [FBSDKInternalUtility dictionary:query setObject:self.accessGroup forKey:[FBSDKDynamicFrameworkLoader loadkSecAttrAccessGroup]]; #endif return query; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKButton+Subclass.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import "FBSDKIcon.h" @protocol FBSDKButtonImpressionTracking - (NSDictionary *)analyticsParameters; - (NSString *)impressionTrackingEventName; - (NSString *)impressionTrackingIdentifier; @end @interface FBSDKButton () - (void)logTapEventWithEventName:(NSString *)eventName parameters:(NSDictionary *)parameters; - (void)checkImplicitlyDisabled; - (void)configureButton; - (void)configureWithIcon:(FBSDKIcon *)icon title:(NSString *)title backgroundColor:(UIColor *)backgroundColor highlightedColor:(UIColor *)highlightedColor; - (void)configureWithIcon:(FBSDKIcon *)icon title:(NSString *)title backgroundColor:(UIColor *)backgroundColor highlightedColor:(UIColor *)highlightedColor selectedTitle:(NSString *)selectedTitle selectedIcon:(FBSDKIcon *)selectedIcon selectedColor:(UIColor *)selectedColor selectedHighlightedColor:(UIColor *)selectedHighlightedColor; - (UIColor *)defaultBackgroundColor; - (UIColor *)defaultDisabledColor; - (UIFont *)defaultFont; - (UIColor *)defaultHighlightedColor; - (FBSDKIcon *)defaultIcon; - (UIColor *)defaultSelectedColor; - (BOOL)isImplicitlyDisabled; - (CGSize)sizeThatFits:(CGSize)size title:(NSString *)title; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKCloseIcon.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @interface FBSDKCloseIcon : NSObject - (UIImage *)imageWithSize:(CGSize)size; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKCloseIcon.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKCloseIcon.h" #import "FBSDKMacros.h" @implementation FBSDKCloseIcon #pragma mark - Public API - (UIImage *)imageWithSize:(CGSize)size { CGFloat scale = [UIScreen mainScreen].scale; UIGraphicsBeginImageContextWithOptions(size, NO, scale); CGContextRef context = UIGraphicsGetCurrentContext(); CGFloat iconSize = MIN(size.width, size.height); CGRect rect = CGRectMake((size.width - iconSize) / 2, (size.height - iconSize) / 2, iconSize, iconSize); CGFloat step = iconSize / 12; // shadow rect = CGRectIntegral(CGRectInset(rect, step, step)); NSArray *colors = @[ (__bridge id)[UIColor colorWithWhite:0.0 alpha:0.7].CGColor, (__bridge id)[UIColor colorWithWhite:0.0 alpha:0.3].CGColor, (__bridge id)[UIColor colorWithWhite:0.0 alpha:0.1].CGColor, (__bridge id)[UIColor colorWithWhite:0.0 alpha:0.0].CGColor, ]; CGFloat locations[4] = { 0.70, 0.80, 0.90, 1.0, }; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations); CGColorSpaceRelease(colorSpace); CGPoint center = CGPointMake(CGRectGetMidX(rect) - step / 6, CGRectGetMidY(rect) + step / 4); CGContextDrawRadialGradient(context, gradient, center, 0.0, center, (CGRectGetWidth(rect) - step / 2) / 2, 0); CGGradientRelease(gradient); // outer circle rect = CGRectIntegral(CGRectInset(rect, step, step)); [[UIColor whiteColor] setFill]; CGContextFillEllipseInRect(context, rect); // inner circle rect = CGRectIntegral(CGRectInset(rect, step, step)); [[UIColor blackColor] setFill]; CGContextFillEllipseInRect(context, rect); // cross rect = CGRectIntegral(CGRectInset(rect, step, step)); CGFloat lineWidth = step * 5 / 4; rect.origin.y = CGRectGetMidY(rect) - lineWidth / 2; rect.size.height = lineWidth; [[UIColor whiteColor] setFill]; CGContextTranslateCTM(context, size.width / 2, size.height / 2); CGContextRotateCTM(context, M_PI_4); CGContextTranslateCTM(context, -size.width / 2, -size.height / 2); CGContextFillRect(context, rect); CGContextTranslateCTM(context, size.width / 2, size.height / 2); CGContextRotateCTM(context, M_PI_2); CGContextTranslateCTM(context, -size.width / 2, -size.height / 2); CGContextFillRect(context, rect); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKColor.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import UIColor *FBSDKUIColorWithRGBA(uint8_t r, uint8_t g, uint8_t b, CGFloat a); UIColor *FBSDKUIColorWithRGB(uint8_t r, uint8_t g, uint8_t b); ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKColor.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKColor.h" static const CGFloat kFBRGBMax = 255.0; UIColor *FBSDKUIColorWithRGBA(uint8_t r, uint8_t g, uint8_t b, CGFloat a) { return [UIColor colorWithRed:(r / kFBRGBMax) green:(g / kFBRGBMax) blue:(b / kFBRGBMax) alpha:a]; } UIColor *FBSDKUIColorWithRGB(uint8_t r, uint8_t g, uint8_t b) { return FBSDKUIColorWithRGBA(r, g, b, 1.0); } ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKIcon.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @interface FBSDKIcon : NSObject - (instancetype)initWithColor:(UIColor *)color NS_DESIGNATED_INITIALIZER; @property (nonatomic, strong, readonly) UIColor *color; - (UIImage *)imageWithSize:(CGSize)size; - (CGPathRef)pathWithSize:(CGSize)size; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKIcon.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKIcon.h" #import "FBSDKMacros.h" @implementation FBSDKIcon #pragma mark - Object Lifecycle - (instancetype)initWithColor:(UIColor *)color { if ((self = [super init])) { _color = [color copy]; } return self; } - (instancetype)init { return [self initWithColor:[UIColor whiteColor]]; } #pragma mark - Public API - (UIImage *)imageWithSize:(CGSize)size { if ((size.width == 0) || (size.height == 0)) { return nil; } CGFloat scale = [UIScreen mainScreen].scale; UIGraphicsBeginImageContextWithOptions(size, NO, scale); CGContextRef context = UIGraphicsGetCurrentContext(); CGPathRef path = [self pathWithSize:size]; CGContextAddPath(context, path); CGContextSetFillColorWithColor(context, self.color.CGColor); CGContextFillPath(context); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; } - (CGPathRef)pathWithSize:(CGSize)size { return NULL; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKLogo.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKIcon.h" @interface FBSDKLogo : FBSDKIcon @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKLogo.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLogo.h" @implementation FBSDKLogo - (CGPathRef)pathWithSize:(CGSize)size { CGAffineTransform transformValue = CGAffineTransformMakeScale(size.width / 136.0, size.height / 136.0); const CGAffineTransform *transform = &transformValue; CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, transform, 127.856, 0.676); CGPathAddLineToPoint(path, transform, 7.469, 0.676); CGPathAddCurveToPoint(path, transform, 3.344, 0.676, 0.0, 4.02, 0.0, 8.145); CGPathAddLineToPoint(path, transform, 0.0, 128.531); CGPathAddCurveToPoint(path, transform, 0.0, 132.656, 3.344, 136.0, 7.469, 136.0); CGPathAddLineToPoint(path, transform, 72.282, 136.0); CGPathAddLineToPoint(path, transform, 72.282, 83.596); CGPathAddLineToPoint(path, transform, 54.646, 83.596); CGPathAddLineToPoint(path, transform, 54.646, 63.173); CGPathAddLineToPoint(path, transform, 72.282, 63.173); CGPathAddLineToPoint(path, transform, 72.282, 48.112); CGPathAddCurveToPoint(path, transform, 72.282, 30.633, 82.957, 21.116, 98.549, 21.116); CGPathAddCurveToPoint(path, transform, 106.018, 21.116, 112.438, 21.671, 114.309, 21.92); CGPathAddLineToPoint(path, transform, 114.309, 40.187); CGPathAddLineToPoint(path, transform, 103.495, 40.191); CGPathAddCurveToPoint(path, transform, 95.014, 40.191, 93.372, 44.221, 93.372, 50.133); CGPathAddLineToPoint(path, transform, 93.372, 63.173); CGPathAddLineToPoint(path, transform, 113.596, 63.173); CGPathAddLineToPoint(path, transform, 110.963, 83.596); CGPathAddLineToPoint(path, transform, 93.372, 83.596); CGPathAddLineToPoint(path, transform, 93.372, 136.0); CGPathAddLineToPoint(path, transform, 127.856, 136.0); CGPathAddCurveToPoint(path, transform, 131.981, 136.0, 135.325, 132.656, 135.325, 128.531); CGPathAddLineToPoint(path, transform, 135.325, 8.145); CGPathAddCurveToPoint(path, transform, 135.325, 4.02, 131.981, 0.676, 127.856, 0.676); CGPathCloseSubpath(path); CGPathRef result = CGPathCreateCopy(path); CGPathRelease(path); return CFAutorelease(result); } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKMaleSilhouetteIcon.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKIcon.h" @interface FBSDKMaleSilhouetteIcon : FBSDKIcon @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKMaleSilhouetteIcon.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKMaleSilhouetteIcon.h" @implementation FBSDKMaleSilhouetteIcon - (CGPathRef)pathWithSize:(CGSize)size { CGAffineTransform transformValue = CGAffineTransformMakeScale(size.width / 158.783, size.height / 158.783); CGAffineTransform *transform = &transformValue; CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, transform, 158.783, 158.783); CGPathAddCurveToPoint(path, transform, 156.39, 131.441, 144.912, 136.964, 105.607, 117.32); CGPathAddCurveToPoint(path, transform, 103.811, 113.941, 103.348, 108.8965, 103.013, 107.4781); CGPathAddLineToPoint(path, transform, 100.434, 106.7803); CGPathAddCurveToPoint(path, transform, 97.2363, 82.7701, 100.67, 101.5845, 106.006, 75.2188); CGPathAddCurveToPoint(path, transform, 107.949, 76.2959, 108.268, 70.7417, 108.971, 66.5743); CGPathAddCurveToPoint(path, transform, 109.673, 62.4068, 110.864, 58.9082, 107.139, 58.9082); CGPathAddCurveToPoint(path, transform, 107.94, 42.7652, 110.299, 31.3848, 101.335, 23.3072); CGPathAddCurveToPoint(path, transform, 92.3808, 15.23781, 87.874, 15.52349, 95.0483, 9.6036128); CGPathAddCurveToPoint(path, transform, 91.2319, 8.892613, 70.2036, 12.01861, 57.4487, 23.3072); CGPathAddCurveToPoint(path, transform, 48.4121, 31.3042, 50.8437, 42.7652, 51.6445, 58.9082); CGPathAddCurveToPoint(path, transform, 47.9194, 58.9082, 49.1108, 62.4068, 49.813, 66.5743); CGPathAddCurveToPoint(path, transform, 50.5156, 70.7417, 50.8349, 76.2959, 52.7778, 75.2188); CGPathAddCurveToPoint(path, transform, 58.1138, 110.1135, 61.5478, 82.7701, 58.3501, 106.7803); CGPathAddLineToPoint(path, transform, 55.7705, 107.4781); CGPathAddCurveToPoint(path, transform, 55.4355, 108.8965, 54.9722, 113.941, 53.1767, 117.32); CGPathAddCurveToPoint(path, transform, 13.8711, 136.964, 2.3945, 131.441, 0.0, 158.783); CGPathAddLineToPoint(path, transform, 158.783, 158.783); CGPathRef result = CGPathCreateCopy(path); CGPathRelease(path); return CFAutorelease(result); } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKUIUtility.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import "../FBSDKMath.h" /*! @abstract Insets a CGSize with the insets in a UIEdgeInsets. */ FBSDK_STATIC_INLINE CGSize FBSDKEdgeInsetsInsetSize(CGSize size, UIEdgeInsets insets) { CGRect rect = CGRectZero; rect.size = size; return UIEdgeInsetsInsetRect(rect, insets).size; } /*! @abstract Outsets a CGSize with the insets in a UIEdgeInsets. */ FBSDK_STATIC_INLINE CGSize FBSDKEdgeInsetsOutsetSize(CGSize size, UIEdgeInsets insets) { return CGSizeMake(insets.left + size.width + insets.right, insets.top + size.height + insets.bottom); } /*! @abstract Limits a CGFloat value, using the scale to limit to pixels (instead of points). @discussion The limitFunction is frequention floorf, ceilf or roundf. If the scale is 2.0, you may get back values of *.5 to correspond to pixels. */ typedef float (*FBSDKLimitFunctionType)(float); FBSDK_STATIC_INLINE CGFloat FBSDKPointsForScreenPixels(FBSDKLimitFunctionType limitFunction, CGFloat screenScale, CGFloat pointValue) { return limitFunction(pointValue * screenScale) / screenScale; } FBSDK_STATIC_INLINE CGSize FBSDKTextSize(NSString *text, UIFont *font, CGSize constrainedSize, NSLineBreakMode lineBreakMode) { if (!text) { return CGSizeZero; } NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineBreakMode = lineBreakMode; NSDictionary *attributes = @{ NSFontAttributeName: font, NSParagraphStyleAttributeName: paragraphStyle, }; NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:text attributes:attributes]; CGSize size = [FBSDKMath ceilForSize:[attributedString boundingRectWithSize:constrainedSize options:(NSStringDrawingUsesDeviceMetrics | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) context:NULL].size]; return [FBSDKMath ceilForSize:size]; } ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKViewImpressionTracker.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @interface FBSDKViewImpressionTracker : NSObject + (instancetype)impressionTrackerWithEventName:(NSString *)eventName; @property (nonatomic, copy, readonly) NSString *eventName; - (void)logImpressionWithIdentifier:(NSString *)identifier parameters:(NSDictionary *)parameters; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKViewImpressionTracker.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKViewImpressionTracker.h" #import "FBSDKAccessToken.h" #import "FBSDKAppEvents+Internal.h" @implementation FBSDKViewImpressionTracker { NSMutableSet *_trackedImpressions; } #pragma mark - Class Methods + (instancetype)impressionTrackerWithEventName:(NSString *)eventName { static NSMutableDictionary *_impressionTrackers = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _impressionTrackers = [[NSMutableDictionary alloc] init]; }); // Maintains a single instance of an impression tracker for each event name FBSDKViewImpressionTracker *impressionTracker = _impressionTrackers[eventName]; if (!impressionTracker) { impressionTracker = [[self alloc] initWithEventName:eventName]; _impressionTrackers[eventName] = impressionTracker; } return impressionTracker; } #pragma mark - Object Lifecycle - (instancetype)initWithEventName:(NSString *)eventName { if ((self = [super init])) { _eventName = [eventName copy]; _trackedImpressions = [[NSMutableSet alloc] init]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationDidEnterBackgroundNotification:) name:UIApplicationDidEnterBackgroundNotification object:[UIApplication sharedApplication]]; } return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } #pragma mark - Public API - (void)logImpressionWithIdentifier:(NSString *)identifier parameters:(NSDictionary *)parameters { NSMutableDictionary *keys = [NSMutableDictionary dictionary]; keys[@"__view_impression_identifier__"] = identifier; [keys addEntriesFromDictionary:parameters]; NSDictionary *impressionKey = [keys copy]; // Ensure that each impression is only tracked once if ([_trackedImpressions containsObject:impressionKey]) { return; } [_trackedImpressions addObject:impressionKey]; [FBSDKAppEvents logImplicitEvent:self.eventName valueToSum:nil parameters:parameters accessToken:[FBSDKAccessToken currentAccessToken]]; } #pragma mark - Helper Methods - (void)_applicationDidEnterBackgroundNotification:(NSNotification *)notification { // reset all tracked impressions when the app backgrounds so we will start tracking them again the next time they // are triggered. [_trackedImpressions removeAllObjects]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialog.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @protocol FBSDKWebDialogDelegate; @interface FBSDKWebDialog : NSObject + (instancetype)showWithName:(NSString *)name parameters:(NSDictionary *)parameters delegate:(id)delegate; @property (nonatomic, assign) BOOL deferVisibility; @property (nonatomic, weak) id delegate; @property (nonatomic, copy) NSString *name; @property (nonatomic, copy) NSDictionary *parameters; - (BOOL)show; @end @protocol FBSDKWebDialogDelegate - (void)webDialog:(FBSDKWebDialog *)webDialog didCompleteWithResults:(NSDictionary *)results; - (void)webDialog:(FBSDKWebDialog *)webDialog didFailWithError:(NSError *)error; - (void)webDialogDidCancel:(FBSDKWebDialog *)webDialog; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialog.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKWebDialog.h" #import "FBSDKAccessToken.h" #import "FBSDKDynamicFrameworkLoader.h" #import "FBSDKInternalUtility.h" #import "FBSDKSettings.h" #import "FBSDKTypeUtility.h" #import "FBSDKWebDialogView.h" #define FBSDK_WEB_DIALOG_SHOW_ANIMATION_DURATION 0.2 #define FBSDK_WEB_DIALOG_DISMISS_ANIMATION_DURATION 0.3 static FBSDKWebDialog *g_currentDialog = nil; @interface FBSDKWebDialog () @end @implementation FBSDKWebDialog { UIView *_backgroundView; FBSDKWebDialogView *_dialogView; } #pragma mark - Class Methods + (instancetype)showWithName:(NSString *)name parameters:(NSDictionary *)parameters delegate:(id)delegate { FBSDKWebDialog *dialog = [[self alloc] init]; dialog.name = name; dialog.parameters = parameters; dialog.delegate = delegate; [dialog show]; return dialog; } #pragma mark - Object Lifecycle - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; _dialogView.delegate = nil; [_dialogView removeFromSuperview]; [_backgroundView removeFromSuperview]; } #pragma mark - Public Methods - (BOOL)show { if (g_currentDialog == self) { return NO; } [g_currentDialog _dismissAnimated:YES]; NSError *error; NSURL *URL = [self _generateURL:&error]; if (!URL) { [self _failWithError:error]; return NO; } g_currentDialog = self; UIWindow *window = [self _findWindow]; if (!window) { [self _failWithError:nil]; return NO; } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" _dialogView = [[FBSDKWebDialogView alloc] initWithFrame:window.screen.applicationFrame]; #pragma clang diagnostic pop _dialogView.delegate = self; [_dialogView loadURL:URL]; if (!_deferVisibility) { [self _showWebView]; } return YES; } #pragma mark - FBSDKWebDialogViewDelegate - (void)webDialogView:(FBSDKWebDialogView *)webDialogView didCompleteWithResults:(NSDictionary *)results { [self _completeWithResults:results]; } - (void)webDialogView:(FBSDKWebDialogView *)webDialogView didFailWithError:(NSError *)error { [self _failWithError:error]; } - (void)webDialogViewDidCancel:(FBSDKWebDialogView *)webDialogView { [self _cancel]; } - (void)webDialogViewDidFinishLoad:(FBSDKWebDialogView *)webDialogView { if (_deferVisibility) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ if (_dialogView) { [self _showWebView]; } }); } } #pragma mark - Notifications - (void)_addObservers { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(_deviceOrientationDidChangeNotification:) name:UIDeviceOrientationDidChangeNotification object:nil]; } - (void)_deviceOrientationDidChangeNotification:(NSNotification *)notification { BOOL animated = [FBSDKTypeUtility boolValue:notification.userInfo[@"UIDeviceOrientationRotateAnimatedUserInfoKey"]]; Class CATransactionClass = fbsdkdfl_CATransactionClass(); CFTimeInterval animationDuration = (animated ? [CATransactionClass animationDuration] : 0.0); [self _updateViewsWithScale:1.0 alpha:1.0 animationDuration:animationDuration completion:^(BOOL finished) { if (finished) { [_dialogView setNeedsDisplay]; } }]; } - (void)_removeObservers { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; } #pragma mark - Helper Methods - (void)_cancel { FBSDKWebDialog *dialog = self; [self _dismissAnimated:YES]; // may cause the receiver to be released [_delegate webDialogDidCancel:dialog]; } - (void)_completeWithResults:(NSDictionary *)results { FBSDKWebDialog *dialog = self; [self _dismissAnimated:YES]; // may cause the receiver to be released [_delegate webDialog:dialog didCompleteWithResults:results]; } - (void)_dismissAnimated:(BOOL)animated { [self _removeObservers]; UIView *backgroundView = _backgroundView; _backgroundView = nil; FBSDKWebDialogView *dialogView = _dialogView; _dialogView.delegate = nil; _dialogView = nil; void(^didDismiss)(BOOL) = ^(BOOL finished){ [backgroundView removeFromSuperview]; [dialogView removeFromSuperview]; }; if (animated) { [UIView animateWithDuration:FBSDK_WEB_DIALOG_DISMISS_ANIMATION_DURATION animations:^{ dialogView.alpha = 0.0; backgroundView.alpha = 0.0; } completion:didDismiss]; } else { didDismiss(YES); } if (g_currentDialog == self) { g_currentDialog = nil; } } - (void)_failWithError:(NSError *)error { // defer so that the consumer is guaranteed to have an opportunity to set the delegate before we fail dispatch_async(dispatch_get_main_queue(), ^{ [self _dismissAnimated:YES]; [_delegate webDialog:self didFailWithError:error]; }); } - (UIWindow *)_findWindow { UIWindow *window = [UIApplication sharedApplication].keyWindow; if (window == nil || window.windowLevel != UIWindowLevelNormal) { for (window in [UIApplication sharedApplication].windows) { if (window.windowLevel == UIWindowLevelNormal) { break; } } } return window; } - (NSURL *)_generateURL:(NSError **)errorRef { NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; parameters[@"display"] = @"touch"; parameters[@"sdk"] = [NSString stringWithFormat:@"ios-%@", [FBSDKSettings sdkVersion]]; parameters[@"redirect_uri"] = @"fbconnect://success"; [FBSDKInternalUtility dictionary:parameters setObject:[FBSDKSettings appID] forKey:@"app_id"]; [FBSDKInternalUtility dictionary:parameters setObject:[FBSDKAccessToken currentAccessToken].tokenString forKey:@"access_token"]; [parameters addEntriesFromDictionary:self.parameters]; return [FBSDKInternalUtility facebookURLWithHostPrefix:@"m" path:[@"/dialog/" stringByAppendingString:self.name] queryParameters:parameters error:errorRef]; } - (BOOL)_showWebView { UIWindow *window = [self _findWindow]; if (!window) { [self _failWithError:nil]; return NO; } [self _addObservers]; _backgroundView = [[UIView alloc] initWithFrame:window.bounds]; _backgroundView.alpha = 0.0; _backgroundView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); _backgroundView.backgroundColor = [UIColor colorWithWhite:0.3 alpha:0.8]; [window addSubview:_backgroundView]; [window addSubview:_dialogView]; [_dialogView becomeFirstResponder]; // dismisses the keyboard if it there was another first responder with it [self _updateViewsWithScale:0.001 alpha:0.0 animationDuration:0.0 completion:NULL]; [self _updateViewsWithScale:1.1 alpha:1.0 animationDuration:FBSDK_WEB_DIALOG_SHOW_ANIMATION_DURATION completion:^(BOOL finished1) { [self _updateViewsWithScale:0.9 alpha:1.0 animationDuration:FBSDK_WEB_DIALOG_SHOW_ANIMATION_DURATION completion:^(BOOL finished2) { [self _updateViewsWithScale:1.0 alpha:1.0 animationDuration:FBSDK_WEB_DIALOG_SHOW_ANIMATION_DURATION completion:NULL]; }]; }]; return YES; } - (CGAffineTransform)_transformForOrientation { // iOS 8 simply adjusts the application frame to adapt to the current orientation and deprecated the concept of // interface orientations if ([FBSDKInternalUtility shouldManuallyAdjustOrientation]) { switch ([UIApplication sharedApplication].statusBarOrientation) { case UIInterfaceOrientationLandscapeLeft: return CGAffineTransformMakeRotation(M_PI * 1.5); case UIInterfaceOrientationLandscapeRight: return CGAffineTransformMakeRotation(M_PI/2); case UIInterfaceOrientationPortraitUpsideDown: return CGAffineTransformMakeRotation(-M_PI); case UIInterfaceOrientationPortrait: case UIInterfaceOrientationUnknown: // don't adjust the orientation break; } } return CGAffineTransformIdentity; } - (CGRect)_applicationFrameForOrientation { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" CGRect applicationFrame = _dialogView.window.screen.applicationFrame; #pragma clang diagnostic pop if ([FBSDKInternalUtility shouldManuallyAdjustOrientation]) { switch ([UIApplication sharedApplication].statusBarOrientation) { case UIInterfaceOrientationLandscapeLeft: case UIInterfaceOrientationLandscapeRight: return CGRectMake(0, 0, CGRectGetHeight(applicationFrame), CGRectGetWidth(applicationFrame)); case UIInterfaceOrientationPortraitUpsideDown: case UIInterfaceOrientationPortrait: case UIInterfaceOrientationUnknown: return applicationFrame; } } else { return applicationFrame; } } - (void)_updateViewsWithScale:(CGFloat)scale alpha:(CGFloat)alpha animationDuration:(CFTimeInterval)animationDuration completion:(void(^)(BOOL finished))completion { CGAffineTransform transform; CGRect applicationFrame = [self _applicationFrameForOrientation]; if (scale == 1.0) { transform = _dialogView.transform; _dialogView.transform = CGAffineTransformIdentity; _dialogView.frame = applicationFrame; _dialogView.transform = transform; } transform = CGAffineTransformScale([self _transformForOrientation], scale, scale); void(^updateBlock)(void) = ^{ _dialogView.transform = transform; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" CGRect mainFrame = _dialogView.window.screen.applicationFrame; #pragma clang diagnostic pop _dialogView.center = CGPointMake(CGRectGetMidX(mainFrame), CGRectGetMidY(mainFrame)); _backgroundView.alpha = alpha; }; if (animationDuration == 0.0) { updateBlock(); } else { [UIView animateWithDuration:animationDuration animations:updateBlock completion:completion]; } } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialogView.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @protocol FBSDKWebDialogViewDelegate; @interface FBSDKWebDialogView : UIView @property (nonatomic, weak) id delegate; - (void)loadURL:(NSURL *)URL; - (void)stopLoading; @end @protocol FBSDKWebDialogViewDelegate - (void)webDialogView:(FBSDKWebDialogView *)webDialogView didCompleteWithResults:(NSDictionary *)results; - (void)webDialogView:(FBSDKWebDialogView *)webDialogView didFailWithError:(NSError *)error; - (void)webDialogViewDidCancel:(FBSDKWebDialogView *)webDialogView; - (void)webDialogViewDidFinishLoad:(FBSDKWebDialogView *)webDialogView; @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialogView.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKWebDialogView.h" #import "FBSDKCloseIcon.h" #import "FBSDKError.h" #import "FBSDKTypeUtility.h" #import "FBSDKUtility.h" #define FBSDK_WEB_DIALOG_VIEW_BORDER_WIDTH 10.0 @interface FBSDKWebDialogView () @end @implementation FBSDKWebDialogView { UIButton *_closeButton; UIActivityIndicatorView *_loadingView; UIWebView *_webView; } #pragma mark - Object Lifecycle - (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { self.backgroundColor = [UIColor clearColor]; self.opaque = NO; _webView = [[UIWebView alloc] initWithFrame:CGRectZero]; _webView.delegate = self; [self addSubview:_webView]; _closeButton = [UIButton buttonWithType:UIButtonTypeCustom]; UIImage *closeImage = [[[FBSDKCloseIcon alloc] init] imageWithSize:CGSizeMake(29.0, 29.0)]; [_closeButton setImage:closeImage forState:UIControlStateNormal]; [_closeButton setTitleColor:[UIColor colorWithRed:167.0/255.0 green:184.0/255.0 blue:216.0/255.0 alpha:1.0] forState:UIControlStateNormal]; [_closeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; _closeButton.showsTouchWhenHighlighted = YES; [_closeButton sizeToFit]; [self addSubview:_closeButton]; [_closeButton addTarget:self action:@selector(_close:) forControlEvents:UIControlEventTouchUpInside]; _loadingView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; _loadingView.color = [UIColor grayColor]; [_webView addSubview:_loadingView]; } return self; } - (void)dealloc { _webView.delegate = nil; } #pragma mark - Public Methods - (void)loadURL:(NSURL *)URL { [_loadingView startAnimating]; [_webView loadRequest:[NSURLRequest requestWithURL:URL]]; } - (void)stopLoading { [_webView stopLoading]; } #pragma mark - Layout - (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSaveGState(context); [self.backgroundColor setFill]; CGContextFillRect(context, self.bounds); [[UIColor blackColor] setStroke]; CGContextSetLineWidth(context, 1.0 / self.layer.contentsScale); CGContextStrokeRect(context, _webView.frame); CGContextRestoreGState(context); [super drawRect:rect]; } - (void)layoutSubviews { [super layoutSubviews]; CGRect bounds = self.bounds; if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { CGFloat horizontalInset = CGRectGetWidth(bounds) * 0.2; CGFloat verticalInset = CGRectGetHeight(bounds) * 0.2; UIEdgeInsets iPadInsets = UIEdgeInsetsMake(verticalInset, horizontalInset, verticalInset, horizontalInset); bounds = UIEdgeInsetsInsetRect(bounds, iPadInsets); } UIEdgeInsets webViewInsets = UIEdgeInsetsMake(FBSDK_WEB_DIALOG_VIEW_BORDER_WIDTH, FBSDK_WEB_DIALOG_VIEW_BORDER_WIDTH, FBSDK_WEB_DIALOG_VIEW_BORDER_WIDTH, FBSDK_WEB_DIALOG_VIEW_BORDER_WIDTH); _webView.frame = CGRectIntegral(UIEdgeInsetsInsetRect(bounds, webViewInsets)); CGRect webViewBounds = _webView.bounds; _loadingView.center = CGPointMake(CGRectGetMidX(webViewBounds), CGRectGetMidY(webViewBounds)); CGRect closeButtonFrame = _closeButton.bounds; closeButtonFrame.origin = bounds.origin; _closeButton.frame = CGRectIntegral(closeButtonFrame); } #pragma mark - Actions - (void)_close:(id)sender { [_delegate webDialogViewDidCancel:self]; } #pragma mark - UIWebViewDelegate - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { [_loadingView stopAnimating]; // 102 == WebKitErrorFrameLoadInterruptedByPolicyChange // NSURLErrorCancelled == "Operation could not be completed", note NSURLErrorCancelled occurs when the user clicks // away before the page has completely loaded, if we find cases where we want this to result in dialog failure // (usually this just means quick-user), then we should add something more robust here to account for differences in // application needs if (!(([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorCancelled) || ([error.domain isEqualToString:@"WebKitErrorDomain"] && error.code == 102))) { [_delegate webDialogView:self didFailWithError:error]; } } - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSURL *URL = request.URL; if ([URL.scheme isEqualToString:@"fbconnect"]) { NSMutableDictionary *parameters = [[FBSDKUtility dictionaryWithQueryString:URL.query] mutableCopy]; [parameters addEntriesFromDictionary:[FBSDKUtility dictionaryWithQueryString:URL.fragment]]; if ([URL.resourceSpecifier hasPrefix:@"//cancel"]) { NSInteger errorCode = [FBSDKTypeUtility integerValue:parameters[@"error_code"]]; if (errorCode) { NSString *errorMessage = [FBSDKTypeUtility stringValue:parameters[@"error_msg"]]; NSError *error = [FBSDKError errorWithCode:errorCode message:errorMessage]; [_delegate webDialogView:self didFailWithError:error]; } else { [_delegate webDialogViewDidCancel:self]; } } else { [_delegate webDialogView:self didCompleteWithResults:parameters]; } return NO; } else if (navigationType == UIWebViewNavigationTypeLinkClicked) { [[UIApplication sharedApplication] openURL:request.URL]; return NO; } else { return YES; } } - (void)webViewDidFinishLoad:(UIWebView *)webView { [_loadingView stopAnimating]; [_delegate webDialogViewDidFinishLoad:self]; } @end ================================================ FILE: Pods/FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit/Internal_NoARC/FBSDKDynamicFrameworkLoader.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKDynamicFrameworkLoader.h" #import #import #import #import "FBSDKLogger.h" #import "FBSDKSettings.h" static NSString *const g_frameworkPathTemplate = @"/System/Library/Frameworks/%@.framework/%@"; #pragma mark - Library and Symbol Loading struct FBSDKDFLLoadSymbolContext { void *(*library)(void); // function to retrieve the library handle (it's a function instead of void * so it can be staticlly bound) const char *name; // name of the symbol to retrieve void **address; // [out] address of the symbol in the process address space }; // Retrieves the handle for a library for framework. The paths for each are constructed // differently so the loading function passed to dispatch_once() calls this. static void *fbsdkdfl_load_library_once(const char *path) { void *handle = dlopen(path, RTLD_LAZY); if (handle) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorInformational formatString:@"Dynamically loaded library at %s", path]; } else { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorInformational formatString:@"Failed to load library at %s", path]; } return handle; } // Constructs the path for a system framework with the given name and returns the handle for dlsym static void *fbsdkdfl_load_framework_once(NSString *framework) { NSString *path = [NSString stringWithFormat:g_frameworkPathTemplate, framework, framework]; return fbsdkdfl_load_library_once([path fileSystemRepresentation]); } // Implements the callback for dispatch_once() that loads the handle for specified framework name #define _fbsdkdfl_load_framework_once_impl_(FRAMEWORK) \ static void fbsdkdfl_load_##FRAMEWORK##_once(void *context) { \ *(void **)context = fbsdkdfl_load_framework_once(@#FRAMEWORK); \ } // Implements the framework/library retrieval function for the given name. // It calls the loading function once and caches the handle in a local static variable #define _fbsdkdfl_handle_get_impl_(LIBRARY) \ static void *fbsdkdfl_handle_get_##LIBRARY(void) { \ static void *LIBRARY##_handle; \ static dispatch_once_t LIBRARY##_once; \ dispatch_once_f(&LIBRARY##_once, &LIBRARY##_handle, &fbsdkdfl_load_##LIBRARY##_once); \ return LIBRARY##_handle;\ } // Callback from dispatch_once() to load a specific symbol static void fbsdkdfl_load_symbol_once(void *context) { struct FBSDKDFLLoadSymbolContext *ctx = context; *ctx->address = dlsym(ctx->library(), ctx->name); } // The boilerplate code for loading a symbol from a given library once and caching it in a static local #define _fbsdkdfl_symbol_get(LIBRARY, PREFIX, SYMBOL, TYPE, VARIABLE_NAME) \ static TYPE VARIABLE_NAME; \ static dispatch_once_t SYMBOL##_once; \ static struct FBSDKDFLLoadSymbolContext ctx = { .library = &fbsdkdfl_handle_get_##LIBRARY, .name = PREFIX #SYMBOL, .address = (void **)&VARIABLE_NAME }; \ dispatch_once_f(&SYMBOL##_once, &ctx, &fbsdkdfl_load_symbol_once) #define _fbsdkdfl_symbol_get_c(LIBRARY, SYMBOL) _fbsdkdfl_symbol_get(LIBRARY, "OBJC_CLASS_$_", SYMBOL, Class, c) // convenience symbol retrieval macro for getting an Objective-C class symbol and storing it in the local static c #define _fbsdkdfl_symbol_get_f(LIBRARY, SYMBOL) _fbsdkdfl_symbol_get(LIBRARY, "", SYMBOL, SYMBOL##_type, f) // convenience symbol retrieval macro for getting a function pointer and storing it in the local static f #define _fbsdkdfl_symbol_get_k(LIBRARY, SYMBOL, TYPE) _fbsdkdfl_symbol_get(LIBRARY, "", SYMBOL, TYPE, k) // convenience symbol retrieval macro for getting a pointer to a named variable and storing it in the local static k // convenience macro for verifying a pointer to a named variable was successfully loaded and returns the value #define _fbsdkdfl_return_k(FRAMEWORK, SYMBOL) \ NSCAssert(k != NULL, @"Failed to load constant %@ in the %@ framework", @#SYMBOL, @#FRAMEWORK); \ return *k // convenience macro for getting a pointer to a named NSString, verifying it loaded correctly, and returning it #define _fbsdkdfl_get_and_return_NSString(LIBRARY, SYMBOL) \ _fbsdkdfl_symbol_get_k(LIBRARY, SYMBOL, NSString **); \ NSCAssert([*k isKindOfClass:[NSString class]], @"Loaded symbol %@ is not of type NSString *", @#SYMBOL); \ _fbsdkdfl_return_k(LIBRARY, SYMBOL) #pragma mark - Security Framework _fbsdkdfl_load_framework_once_impl_(Security) _fbsdkdfl_handle_get_impl_(Security) #pragma mark - Security Constants @implementation FBSDKDynamicFrameworkLoader #define _fbsdkdfl_Security_get_k(SYMBOL) _fbsdkdfl_symbol_get_k(Security, SYMBOL, CFTypeRef *) #define _fbsdkdfl_Security_get_and_return_k(SYMBOL) \ _fbsdkdfl_Security_get_k(SYMBOL); \ _fbsdkdfl_return_k(Security, SYMBOL) + (SecRandomRef)loadkSecRandomDefault { _fbsdkdfl_symbol_get_k(Security, kSecRandomDefault, SecRandomRef *); _fbsdkdfl_return_k(Security, kSecRandomDefault); } + (CFTypeRef)loadkSecAttrAccessible { _fbsdkdfl_Security_get_and_return_k(kSecAttrAccessible); } + (CFTypeRef)loadkSecAttrAccessibleAfterFirstUnlockThisDeviceOnly { _fbsdkdfl_Security_get_and_return_k(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly); } + (CFTypeRef)loadkSecAttrAccount { _fbsdkdfl_Security_get_and_return_k(kSecAttrAccount); } + (CFTypeRef)loadkSecAttrService { _fbsdkdfl_Security_get_and_return_k(kSecAttrService); } + (CFTypeRef)loadkSecAttrGeneric { _fbsdkdfl_Security_get_and_return_k(kSecAttrGeneric); } + (CFTypeRef)loadkSecValueData { _fbsdkdfl_Security_get_and_return_k(kSecValueData); } + (CFTypeRef)loadkSecClassGenericPassword { _fbsdkdfl_Security_get_and_return_k(kSecClassGenericPassword); } + (CFTypeRef)loadkSecAttrAccessGroup { _fbsdkdfl_Security_get_and_return_k(kSecAttrAccessGroup); } + (CFTypeRef)loadkSecMatchLimitOne { _fbsdkdfl_Security_get_and_return_k(kSecMatchLimitOne); } + (CFTypeRef)loadkSecMatchLimit { _fbsdkdfl_Security_get_and_return_k(kSecMatchLimit); } + (CFTypeRef)loadkSecReturnData { _fbsdkdfl_Security_get_and_return_k(kSecReturnData); } + (CFTypeRef)loadkSecClass { _fbsdkdfl_Security_get_and_return_k(kSecClass); } #pragma mark - Object Lifecycle - (instancetype)init { FBSDK_NO_DESIGNATED_INITIALIZER(); return nil; } @end #pragma mark - Security APIs #define _fbsdkdfl_Security_get_f(SYMBOL) _fbsdkdfl_symbol_get_f(Security, SYMBOL) typedef int (*SecRandomCopyBytes_type)(SecRandomRef, size_t, uint8_t *); typedef OSStatus (*SecItemUpdate_type)(CFDictionaryRef, CFDictionaryRef); typedef OSStatus (*SecItemAdd_type)(CFDictionaryRef, CFTypeRef); typedef OSStatus (*SecItemCopyMatching_type)(CFDictionaryRef, CFTypeRef); typedef OSStatus (*SecItemDelete_type)(CFDictionaryRef); int fbsdkdfl_SecRandomCopyBytes(SecRandomRef rnd, size_t count, uint8_t *bytes) { _fbsdkdfl_Security_get_f(SecRandomCopyBytes); return f(rnd, count, bytes); } OSStatus fbsdkdfl_SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate) { _fbsdkdfl_Security_get_f(SecItemUpdate); return f(query, attributesToUpdate); } OSStatus fbsdkdfl_SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result) { _fbsdkdfl_Security_get_f(SecItemAdd); return f(attributes, result); } OSStatus fbsdkdfl_SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result) { _fbsdkdfl_Security_get_f(SecItemCopyMatching); return f(query, result); } OSStatus fbsdkdfl_SecItemDelete(CFDictionaryRef query) { _fbsdkdfl_Security_get_f(SecItemDelete); return f(query); } #pragma mark - Social Constants _fbsdkdfl_load_framework_once_impl_(Social) _fbsdkdfl_handle_get_impl_(Social) #define _fbsdkdfl_Social_get_and_return_constant(SYMBOL) _fbsdkdfl_get_and_return_NSString(Social, SYMBOL) NSString *fbsdkdfl_SLServiceTypeFacebook(void) { _fbsdkdfl_Social_get_and_return_constant(SLServiceTypeFacebook); } #pragma mark - Social Classes #define _fbsdkdfl_Social_get_c(SYMBOL) _fbsdkdfl_symbol_get_c(Social, SYMBOL) Class fbsdkdfl_SLComposeViewControllerClass(void) { _fbsdkdfl_Social_get_c(SLComposeViewController); return c; } #pragma mark - QuartzCore Classes _fbsdkdfl_load_framework_once_impl_(QuartzCore) _fbsdkdfl_handle_get_impl_(QuartzCore) #define _fbsdkdfl_QuartzCore_get_c(SYMBOL) _fbsdkdfl_symbol_get_c(QuartzCore, SYMBOL); Class fbsdkdfl_CATransactionClass(void) { _fbsdkdfl_QuartzCore_get_c(CATransaction); return c; } #pragma mark - QuartzCore APIs #define _fbsdkdfl_QuartzCore_get_f(SYMBOL) _fbsdkdfl_symbol_get_f(QuartzCore, SYMBOL) typedef CATransform3D (*CATransform3DMakeScale_type)(CGFloat, CGFloat, CGFloat); typedef CATransform3D (*CATransform3DMakeTranslation_type)(CGFloat, CGFloat, CGFloat); typedef CATransform3D (*CATransform3DConcat_type)(CATransform3D, CATransform3D); const CATransform3D fbsdkdfl_CATransform3DIdentity = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; CATransform3D fbsdkdfl_CATransform3DMakeScale(CGFloat sx, CGFloat sy, CGFloat sz) { _fbsdkdfl_QuartzCore_get_f(CATransform3DMakeScale); return f(sx, sy, sz); } CATransform3D fbsdkdfl_CATransform3DMakeTranslation(CGFloat tx, CGFloat ty, CGFloat tz) { _fbsdkdfl_QuartzCore_get_f(CATransform3DMakeTranslation); return f(tx, ty, tz); } CATransform3D fbsdkdfl_CATransform3DConcat(CATransform3D a, CATransform3D b) { _fbsdkdfl_QuartzCore_get_f(CATransform3DConcat); return f(a, b); } #pragma mark - AudioToolbox APIs _fbsdkdfl_load_framework_once_impl_(AudioToolbox) _fbsdkdfl_handle_get_impl_(AudioToolbox) #define _fbsdkdfl_AudioToolbox_get_f(SYMBOL) _fbsdkdfl_symbol_get_f(AudioToolbox, SYMBOL) typedef OSStatus (*AudioServicesCreateSystemSoundID_type)(CFURLRef, SystemSoundID *); typedef OSStatus (*AudioServicesDisposeSystemSoundID_type)(SystemSoundID); typedef void (*AudioServicesPlaySystemSound_type)(SystemSoundID); OSStatus fbsdkdfl_AudioServicesCreateSystemSoundID(CFURLRef inFileURL, SystemSoundID *outSystemSoundID) { _fbsdkdfl_AudioToolbox_get_f(AudioServicesCreateSystemSoundID); return f(inFileURL, outSystemSoundID); } OSStatus fbsdkdfl_AudioServicesDisposeSystemSoundID(SystemSoundID inSystemSoundID) { _fbsdkdfl_AudioToolbox_get_f(AudioServicesDisposeSystemSoundID); return f(inSystemSoundID); } void fbsdkdfl_AudioServicesPlaySystemSound(SystemSoundID inSystemSoundID) { _fbsdkdfl_AudioToolbox_get_f(AudioServicesPlaySystemSound); return f(inSystemSoundID); } #pragma mark - Ad Support Classes _fbsdkdfl_load_framework_once_impl_(AdSupport) _fbsdkdfl_handle_get_impl_(AdSupport) #define _fbsdkdfl_AdSupport_get_c(SYMBOL) _fbsdkdfl_symbol_get_c(AdSupport, SYMBOL); Class fbsdkdfl_ASIdentifierManagerClass(void) { _fbsdkdfl_AdSupport_get_c(ASIdentifierManager); return c; } #pragma mark - Safari Services _fbsdkdfl_load_framework_once_impl_(SafariServices) _fbsdkdfl_handle_get_impl_(SafariServices) #define _fbsdkdfl_SafariServices_get_c(SYMBOL) _fbsdkdfl_symbol_get_c(SafariServices, SYMBOL); Class fbsdkdfl_SFSafariViewControllerClass(void) { _fbsdkdfl_SafariServices_get_c(SFSafariViewController); return c; } #pragma mark - Accounts Constants _fbsdkdfl_load_framework_once_impl_(Accounts) _fbsdkdfl_handle_get_impl_(Accounts) #define _fbsdkdfl_Accounts_get_and_return_NSString(SYMBOL) _fbsdkdfl_get_and_return_NSString(Accounts, SYMBOL) NSString *fbsdkdfl_ACFacebookAppIdKey(void) { _fbsdkdfl_Accounts_get_and_return_NSString(ACFacebookAppIdKey); } NSString *fbsdkdfl_ACFacebookAudienceEveryone(void) { _fbsdkdfl_Accounts_get_and_return_NSString(ACFacebookAudienceEveryone); } NSString *fbsdkdfl_ACFacebookAudienceFriends(void) { _fbsdkdfl_Accounts_get_and_return_NSString(ACFacebookAudienceFriends); } NSString *fbsdkdfl_ACFacebookAudienceKey(void) { _fbsdkdfl_Accounts_get_and_return_NSString(ACFacebookAudienceKey); } NSString *fbsdkdfl_ACFacebookAudienceOnlyMe(void) { _fbsdkdfl_Accounts_get_and_return_NSString(ACFacebookAudienceOnlyMe); } NSString *fbsdkdfl_ACFacebookPermissionsKey(void) { _fbsdkdfl_Accounts_get_and_return_NSString(ACFacebookPermissionsKey); } #pragma mark - Accounts Classes #define _fbsdkdfl_Accounts_get_c(SYMBOL) _fbsdkdfl_symbol_get_c(Accounts, SYMBOL); Class fbsdkdfl_ACAccountStoreClass(void) { _fbsdkdfl_Accounts_get_c(ACAccountStore); return c; } #pragma mark - StoreKit Classes _fbsdkdfl_load_framework_once_impl_(StoreKit) _fbsdkdfl_handle_get_impl_(StoreKit) #define _fbsdkdfl_StoreKit_get_c(SYMBOL) _fbsdkdfl_symbol_get_c(StoreKit, SYMBOL); Class fbsdkdfl_SKPaymentQueueClass(void) { _fbsdkdfl_StoreKit_get_c(SKPaymentQueue); return c; } Class fbsdkdfl_SKProductsRequestClass(void) { _fbsdkdfl_StoreKit_get_c(SKProductsRequest); return c; } #pragma mark - AssetsLibrary Classes _fbsdkdfl_load_framework_once_impl_(AssetsLibrary) _fbsdkdfl_handle_get_impl_(AssetsLibrary) #define _fbsdkdfl_AssetsLibrary_get_c(SYMBOL) _fbsdkdfl_symbol_get_c(AssetsLibrary, SYMBOL); Class fbsdkdfl_ALAssetsLibraryClass(void) { _fbsdkdfl_AssetsLibrary_get_c(ALAssetsLibrary); return c; } #pragma mark - CoreTelephony Classes _fbsdkdfl_load_framework_once_impl_(CoreTelephony) _fbsdkdfl_handle_get_impl_(CoreTelephony) #define _fbsdkdfl_CoreTelephonyLibrary_get_c(SYMBOL) _fbsdkdfl_symbol_get_c(CoreTelephony, SYMBOL); Class fbsdkdfl_CTTelephonyNetworkInfoClass(void) { _fbsdkdfl_CoreTelephonyLibrary_get_c(CTTelephonyNetworkInfo); return c; } ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/af.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Besoek %@ op jou slimfoon of rekenaar en voer hierdie kode in:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "Goed"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Kanselleer"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Meld asseblief weer by hierdie toepassing aan om jou Facebook-rekening te herkoppel. "; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "Goed"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Die bediener is tydelik besig, probeer asseblief weer."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Hou van"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Hou van"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Kanselleer"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Meld af"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Met Facebook aangemeld"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "As %@ aangemeld"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Meld aan"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Meld met Facebook aan"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Meld af"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Toegang is nie na die Facebook-rekening verleen nie. Verifieer toestelinstellings."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Kan nie aan Facebook koppel nie. Gaan jou netwerkverbinding na en probeer weer."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Jou Facebook-wagwoord het verander. Om jou wagwoord te bevestig, maak Instellings > Facebook oop en tik jou naam."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Die Facebook-rekening is nie op die toestel opgestel nie."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Jou rekening is nie bevestig nie. Meld asseblief by www.facebook.com aan en volg die gegewe instruksies."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Jy kan nie op die oomblik by toepassings aanmeld nie. Meld asseblief by www.facebook.com aan en volg die gegewe instruksies."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Nuut! Jy is in beheer - kies waater inligting jy met toepassings wil deel."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Meld aan"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Stuur"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Deel"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/ar.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "زر %@ على هاتفك الذكي أو الكمبيوتر ثم أدخل هذا الرمز:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "موافق"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "إلغاء"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "يرجى تسجيل الدخول إلى هذا التطبيق مرة أخرى لإعادة الاتصال بحساب فيسبوك."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "موافق"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "الخادم مشغول مؤقتًا، يرجى إعادة المحاولة."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "إعجاب"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "أعجبني"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "إلغاء"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "تسجيل الخروج"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "تم تسجيل الدخول بحساب فيسبوك"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "تم تسجيل الدخول باسم %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "تسجيل الدخول"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "تسجيل الدخول بحساب فيسبوك"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "تسجيل الخروج"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "لم يتم منح إذن الوصول لحساب فيسبوك. تحقق من إعدادات الجهاز."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "تعذر الاتصال بفيسبوك. يُرجى التحقق من الاتصال بالإنترنت وإعادة المحاولة."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "تم تغيير كلمة سر فيسبوك الخاصة بك. لتأكيد كلمة السر، افتح الإعدادات > فيسبوك ثم اضغط على اسمك."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "لم تتم تهيئة حساب فيسبوك على الجهاز."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "لم يتم تأكيد حسابك. يُرجى تسجيل الدخول إلى www.facebook.com واتباع التعليمات الموضحة."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "لا يمكنك تسجيل الدخول إلى التطبيقات حاليًا. يُرجى تسجيل الدخول إلى www.facebook.com واتباع التعليمات الموضحة."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "جديد! أنت المتحكم - اختر المعلومات التي تريد مشاركتها مع التطبيقات."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "تسجيل الدخول"; /* The label for FBSDKSendButton */ "SendButton.Send" = "إرسال"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "مشاركة"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/bn.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "আপনার কম্পিউটার বা স্মার্টফোন থেকে %@ এ যান এবং এই কোডটিকে প্রবেশ করান:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "ঠিক আছে"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "বাতিল করুন"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "আপনার Facebook অ্যাকাউন্টটিতে পুনরায় সংযোগ করার জন্য অনুগ্রহ করে এই অ্যাপটিতে লগ ইন করুন৷"; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "ঠিক আছে"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "এই সার্ভারটি সাময়িকভাবে ব্যস্ত আছে, অনুগ্রহ করে পুনরায় চেষ্টা করুন৷"; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "পছন্দ করুন"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "পছন্দ করা হয়েছে"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "বাতিল করুন"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "লগ আউট করুন"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Facebook ব্যবহার করে লগ ইন করা হয়েছে"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "%@ হিসাবে লগ ইন করা হয়েছে"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "লগ ইন করুন"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Facebook -এর সাথে লগ ইন করুন"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "লগ আউট করুন"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Facebook অ্যাকাউন্টটিতে অ্যাক্সেস করার অনুমতি নেই৷ ডিভাইস সেটিংস যাচাই করুন৷"; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Facebook-এ সংযোগ করা যাচ্ছে না৷ আপনার নেটওয়ার্ক সংযোগটি পরীক্ষা করুন এবং পুনরায় চেষ্টা করুন৷"; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "আপনার Facebook পাসওয়ার্ডটি পরিবর্তিত হয়েছে৷ আপনার পাসওয়ার্ডটি নিশ্চিত করতে, সেটিংস > Facebook খুলুন এবং আপনার নামটি ট্যাপ করুন৷"; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Facebook অ্যাকাউন্টটি এই ডিভাইসে কনফিগার করা যাযনি৷"; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "আপনার অ্যাকাউন্টটি নিশ্চিত করা যায়নি৷ অনুগ্রহ করে www.facebook.com-এ লগ ইন করুন এবং উল্লিখিত নির্দেশাবলী অনুসরণ করুন৷"; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "এই সময়ে আপনি অ্যাপসে লগ ইন করতে পারবেন না৷ অনুগ্রহ করে www.facebook.com-এ লগ ইন করুন এবং উল্লিখিত নির্দেশাবলী অনুসরণ করুন৷"; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "নতুন! আপনি নিয়ন্ত্রণে আছেন-অ্যাপসের সাথে আপনি কোন তথ্য ভাগ করতে চাইছেন তা চয়ন করুন৷"; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "লগ ইন করুন"; /* The label for FBSDKSendButton */ "SendButton.Send" = "পাঠান"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "ভাগ করুন"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/cs.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Přejděte ze smartphonu nebo počítače na %@ a zadejte tento kód:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Zrušit"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Pokud se chcete ke svému Facebook účtu znovu připojit, přihlaste se k této aplikaci ještě jednou."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Server je dočasně zaneprázdněný, zkuste to znovu."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "To se mi líbí"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Už se mi to líbí"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Zrušit"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Odhlásit"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Přihlášen(a) přes Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Přihlášen(a) jako %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Přihlásit"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Přihlásit se přes Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Odhlásit"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Facebook účtu nebylo oprávnění uděleno. Ověřte nastavení zařízení."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "K Facebooku se nedá připojit. Zkontrolujte připojení k síti a zkuste to znovu."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Vaše heslo na Facebook je změněné. Pokud chcete heslo potvrdit, přejděte do Nastavení > Facebook a klepněte na své jméno."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "V tomto zařízení není Facebook účet konfigurovaný."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Váš účet není potvrzený. Přihlaste se na www. facebook.com a postupujte podle uvedených pokynů."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Do aplikací se v této chvíli přihlásit nemůžete. Přihlaste se na www. facebook.com a postupujte podle uvedených pokynů."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Novinka! Je jen na vás, které informace chcete s aplikacemi sdílet."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Přihlásit"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Odeslat"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Sdílet"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/da.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Gå til %@ på din smartphone eller computer, og indtast denne kode:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Annuller"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Log på denne app igen for at genoprette forbindelsen til din Facebook-konto."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Serveren er optaget i øjeblikket. Prøv igen."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Synes godt om"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Synes godt om"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Annuller"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Log af"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Logget på med Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Logget på som %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Log på"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Log på med Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Log af"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Der er ikke blevet givet adgang til Facebook-kontoen. Kontrollér enhedsindstillingerne."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Kunne ikke oprette forbindelse til Facebook. Kontrollér din netværksforbindelse, og prøv igen."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Din Facebook-adgangskode er ændret. For at bekræfte din adgangskode skal du åbne Indstillinger > Facebook og trykke på dit navn."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Facebook-kontoen er ikke blevet konfigureret på enheden."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Din konto er ikke bekræftet. Log på www.facebook.com, og følg instruktionerne."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Du kan ikke logge på apps på nuværende tidspunkt. Log på www.facebook.com, og følg instruktionerne."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Nyhed! Du har styringen – vælg de oplysninger, som du vil dele med apps."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Log på"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Send"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Del"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/de.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Gehe über dein Smartphone oder deinen Computer zu %@ und gib diesen Code ein:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Abbrechen"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Melde dich bitte erneut bei dieser App an, um die Verbindung mit deinem Facebook-Konto wiederherzustellen."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Der Server ist vorübergehend beschäftigt. Bitte versuche es erneut."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Gefällt mir"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Gefällt dir"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Abbrechen"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Abmelden"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Über Facebook angemeldet"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Als %@ angemeldet"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Anmelden"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Über Facebook anmelden"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Abmelden"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Auf das Facebook-Konto wurde kein Zugriff erteilt. Überprüfe bitte die Geräteeinstellungen."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Verbindung zu Facebook kann nicht hergestellt werden. Bitte überprüfe deine Netzwerkverbindung und versuche es erneut."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Dein Facebook-Passwort hat sich geändert. Öffne „Einstellungen“ > „Facebook“ und tippe auf deinen Namen, um dein Passwort zu bestätigen."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Das Facebook-Konto wurde für dieses Gerät nicht konfiguriert."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Dein Konto wurde nicht bestätigt. Bitte melde dich unter www.facebook.com an und folge den Anweisungen."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Du kannst dich zurzeit nicht bei Apps anmelden. Bitte melde dich unter www.facebook.com an und folge den Anweisungen."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Neu! Es liegt ganz an dir – du kannst dir aussuchen, was du mit Apps teilen möchtest."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Anmelden"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Senden"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Teilen"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/el.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Επισκεφτείτε τον ιστότοπο %@ από το smartphone ή τον υπολογιστή σας και πληκτρολογήστε αυτόν τον κωδικό:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Άκυρο"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Συνδεθείτε ξανά σε αυτή την εφαρμογή για να συνδέσετε και πάλι το λογαριασμό σας στο Facebook."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Ο διακομιστής είναι προσωρινά απασχολημένος, προσπαθήστε ξανά."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Μου αρέσει!"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Σας αρέσει"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Άκυρο"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Αποσύνδεση"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Έχει γίνει σύνδεση μέσω Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Έχει γίνει σύνδεση ως %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Σύνδεση"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Σύνδεση μέσω Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Αποσύνδεση"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Δεν έχει παραχωρηθεί πρόσβαση στο λογαριασμό Facebook. Επαληθεύστε τις ρυθμίσεις της συσκευής σας."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Δεν είναι δυνατή η σύνδεση στο Facebook. Ελέγξτε τη σύνδεση στο δίκτυο και προσπαθήστε ξανά."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Ο κωδικός πρόσβασής σας στο Facebook άλλαξε. Για να επιβεβαιώσετε τον κωδικό σας, πηγαίνετε στις Ρυθμίσεις > Facebook και πατήστε το όνομά σας."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Ο λογαριασμός Facebook δεν έχει διαμορφωθεί στη συσκευή."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Ο λογαριασμός σας δεν επιβεβαιώθηκε. Συνδεθείτε στο www.facebook.com και ακολουθήστε τις οδηγίες που εμφανίζονται."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Προς το παρόν δεν μπορείτε να συνδεθείτε σε εφαρμογές. Συνδεθείτε στο www.facebook.com και ακολουθήστε τις οδηγίες που εμφανίζονται."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Νέο! Έχετε τον έλεγχο - επιλέξτε ποιες πληροφορίες θέλετε να κοινοποιούνται στις εφαρμογές."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Σύνδεση"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Αποστολή"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Κοινοποίηση"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/en_GB.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Visit %@ on your smartphone or computer and enter this code:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Cancel"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Please log in to this app again to reconnect your Facebook account."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "The server is temporarily busy, please try again."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Like"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Liked"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Cancel"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Log out"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Logged in using Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Logged in as %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Log in"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Log in with Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Log out"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Access has not been granted to the Facebook account. Verify device settings."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Unable to connect to Facebook. Please check your network connection and try again."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Your Facebook password has changed. To confirm your password, open Settings > Facebook and tap your name."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "The Facebook account has not been configured on the device."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Your account is not confirmed. Please log in to www.facebook.com and follow the instructions given."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "You cannot log in to apps at this time. Please log in to www.facebook.com and follow the instructions given."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "New! You're in control – choose what info you want to share with apps."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Log In"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Send"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Share"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/es.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Visita %@ en tu smartphone o computadora e ingresa este código:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "Aceptar"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Cancelar"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Inicia sesión de nuevo en esta aplicación para volver a conectarte a tu cuenta de Facebook."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "Aceptar"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "El servidor está temporalmente ocupado. Vuelve a intentarlo."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Me gusta"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Te gusta"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Cancelar"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Cerrar sesión"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Sesión iniciada con Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Sesión iniciada como %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Inicio de sesión"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Iniciar sesión con Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Salir"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "No se concedió acceso a la cuenta de Facebook. Verifica la configuración del dispositivo."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "No es posible conectarse a Facebook. Comprueba tu conexión a internet y vuelve a intentarlo."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Cambió tu contraseña de Facebook. Para confirmar tu contraseña, abre Configuración > Facebook y toca tu nombre."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "No se configuró la cuenta de Facebook en el dispositivo."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Tu cuenta no está confirmada. Inicia sesión en www.facebook.com y sigue las instrucciones."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "No puedes iniciar sesión en las aplicaciones en este momento. Inicia sesión en www.facebook.com y sigue las instrucciones."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "¡Nuevo! Tú tienes el control: elige qué información quieres compartir con las aplicaciones."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Inicio de sesión"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Enviar"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Compartir"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/es_ES.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Visita %@ en tu smartphone u ordenador e introduce este código:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "Aceptar"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Cancelar"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Vuelve a iniciar sesión en esta aplicación para volver a conectar tu cuenta de Facebook."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "Aceptar"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "El servidor está ocupado temporalmente. Vuelve a intentarlo más tarde."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Me gusta"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Te gusta"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Cancelar"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Salir"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Sesión iniciada con Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Sesión iniciada como %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Inicio de sesión"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Iniciar sesión con Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Salir"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "No se ha otorgado acceso a la cuenta de Facebook. Verifica la configuración del dispositivo."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "No es posible conectarse a Facebook. Comprueba tu conexión de red y vuelve a intentarlo."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Tu contraseña de Facebook ha cambiado. Para confirmar tu contraseña, abre Configuración > Facebook y toca tu nombre."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "La cuenta de Facebook no se ha configurado en el dispositivo."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Tu cuenta no se ha confirmado. Inicia sesión en www.facebook.com y sigue las instrucciones."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "No puedes iniciar sesión en las aplicaciones en este momento. Inicia sesión en www.facebook.com y sigue las instrucciones."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Novedad: Tú eres quien controla y elige la información que quieres compartir con las aplicaciones."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Inicio de sesión"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Enviar"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Compartir"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/fi.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Siirry osoitteeseen %@ älypuhelimella tai tietokoneella ja anna seuraava koodi:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Peruuta"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Kirjaudu tähän sovellukseen uudelleen, jotta voit yhdistää Facebook-tilisi uudelleen."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Palvelin on tilapäisesti varattu, yritä uudelleen."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Tykkää"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Tykätty"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Peruuta"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Kirjaudu ulos"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Sisäänkirjautunut Facebookin avulla"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Sisäänkirjautunut nimellä %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Kirjaudu sisään"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Kirjaudu sisään Facebookin avulla"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Kirjaudu ulos"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Pääsyä Facebook-tiliin ei ole myönnetty. Tarkista laiteasetukset."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Yhteyttä Facebookiin ei voi muodostaa. Tarkista verkkoyhteys ja yritä sitten uudelleen."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Facebook-salasanasi on vaihdettu. Vahvista salasanasi avaamalla Asetukset > Facebook ja napauttamalla nimeäsi."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Facebook-tiliä ei ole määritetty laitteessa."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Tiliäsi ei ole vahvistettu. Kirjaudu sisään osoitteeseen www.facebook.com ja noudata annettuja ohjeita."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Et pysty kirjautumaan sovelluksiin tällä hetkellä. Kirjaudu sisään osoitteeseen www.facebook.com ja noudata annettuja ohjeita."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Uutta! Sinä päätät – valitse, mitä haluat jakaa sovellusten kanssa."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Kirjaudu sisään"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Lähetä"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Jaa"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/fil.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Puntahan ang %@ sa iyong smartphone o computer at ilagay ang code na ito:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Kanselahin"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Mangyaring mag-log in muli sa app na ito para ikonekta muli ang iyong Facebook account."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Pansamantalang abala ang server, pakisubukan muli."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Gustuhin"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Nagustuhan"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Kanselahin"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Mag-log Out"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Naka-log in gamit ang Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Naka-log in bilang si %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Mag-log in"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Mag-log in sa pamamagitan ng Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Mag-log out"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Hindi binigyan ng access ang Facebook account. Beripikahin ang mga setting ng device."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Hindi nakakonekta sa Facebook. Tingnan ang iyong koneksyon sa network at subukan muli."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Nagbago ang iyong password sa Facebook. Para makumpirma ang iyong password, buksan ang Mga Setting > Facebook at i-tap ang iyong pangalan."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Hindi na-configure sa device ang Facebook account."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Hindi nakumpirma ang iyong account. Mangyaring mag-log in sa www.facebook.com at sundin ang mga ibinigay na tagubilin."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Hindi ka makakapag-log in sa mga app sa oras na ito. Mangyaring mag-log in sa www.facebook.com at sundin ang mga ibinigay na tagubilin."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Bago! Ikaw ang may kontrol - piliin kung anong impormasyon ang gusto mong ibahagi sa mga app."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Mag-log In"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Ipadala"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Ibahagi"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/fr.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Rendez-vous sur %@ sur votre smartphone ou votre ordinateur et entrez ce code :"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Annuler"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Veuillez vous connecter à nouveau à cette application pour reconnecter votre compte Facebook."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Le serveur est temporairement occupé. Veuillez réessayer plus tard."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "J’aime"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "J’aime déjà"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Annuler"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Déconnexion"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Connecté(e) à l’aide de Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Connecté(e) en tant que %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Connexion"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Connexion avec Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Déconnexion"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "L’accès au compte Facebook n’a pas été autorisé. Vérifiez les paramètres de l’appareil."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Connexion à Facebook impossible. Vérifiez votre connexion avant de réessayer."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Votre mot de passe Facebook a changé. Pour confirmer votre mot de passe, ouvrez Paramètres > Facebook et saisissez votre nom."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Le compte Facebook n’a pas été configuré sur l’appareil."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Votre compte n’est pas confirmé. Veuillez vous connecter à www.facebook.com et suivre les instructions indiquées."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Vous ne pouvez pas vous connecter à des applications pour le moment. Veuillez vous connecter à www.facebook.com et suivre les instructions indiquées."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Nouveau ! Choisissez les informations que vous souhaitez partager avec les applications."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Connexion"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Envoyer"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Partager"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/gu.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "તમારા સ્માર્ટફોન અથવા કમ્પ્યુટર પર %@ ની મુલાકાત લો અને આ કોડ દાખલ કરો:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "ઠીક"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "રદ કરો"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "તમારા ફેસબુક ખાતાને ફરીથી કનેક્ટ કરવા માટે કૃપા કરીને આ એપ્લિકેશનમાં ફરી લૉગ ઇન કરો."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "ઠીક"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "સર્વર અસ્થાયીરૂપે વ્યસ્ત છે, કૃપા કરીને ફરી પ્રયાસ કરો."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "પસંદ કરો"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "પસંદ કર્યું"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "રદ કરો"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "લૉગ આઉટ કરો"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "ફેસબુકનો ઉપયોગ કરીને લૉગ ઇન કરો"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "%@ તરીકે લૉગ ઇન થયાં"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "લૉગ ઇન કરો"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "ફેસબુક સાથે લૉગ ઇન કરો"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "લૉગ આઉટ કરો"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "ફેસબુક ખાતા પર ઍક્સેસ આપવામાં આવી નથી. ઉપકરણ સેટિંગ્સ ચકાસો"; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "ફેસબુકથી કનેક્ટ કરવામાં અસમર્થ. તમારું નેટવર્ક કનેક્શન તપાસો અને ફરી પ્રયાસ કરો."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "તમારો ફેસબુક પાસવર્ડ બદલાઈ ગયો છે. તમારા પાસવર્ડની પુષ્ટિ કરવા માટે, સેટિંગ્સ > ફેસબુક ખોલો અને તમારા નામ પર ટૅપ કરો."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "ઉપકરણ પર ફેસબુક ખાતું કન્ફિગર કરવામાં આવ્યું નથી."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "તમારા ખાતાની પુષ્ટિ કરવામાં આવી નથી. કૃપા કરીને www.facebook.com પર લૉગ ઇન કરો અને આપેલા સૂચનોને અનુસરો."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "તમે આ સમયે એપ્લિકેશન્સમાં લૉગ ઇન કરી શકતાં નથી. કૃપા કરીને www.facebook.com પર લૉગ ઇન કરો અને આપેલા સૂચનોને અનુસરો."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "નવું! તમે નિયંત્રણ કરો છો - તમે એપ્લિકેશન્સ સાથે કઈ માહિતી શેર કરવા માંગો છો તે પસંદ કરો."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "લૉગ ઇન કરો"; /* The label for FBSDKSendButton */ "SendButton.Send" = "મોકલો"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "શેર કરો"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/he.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "בקר ב-%@ בטלפון החכם או במחשב והזן קוד זה:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "אישור"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "ביטול"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "התחבר לאפליקציה זו שוב כדי לחבר מחדש את חשבון הפייסבוק שלך."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "אישור"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "השרת עמוס באופן זמני, נסה שוב."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "אהבתי"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "אהבתי"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "ביטול"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "התנתק"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "מחובר באמצעות פייסבוק"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "מחובר בתור %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "התחבר"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "התחבר באמצעות פייסבוק"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "התנתק"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "לא הוענקה גישה לחשבון הפייסבוק. אמת את הגדרות המכשיר."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "לא ניתן להתחבר לפייסבוק. בדוק את החיבור שלך לרשת ונסה שוב."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "סיסמת הפייסבוק שלך השתנתה. כדי לאשר את הסיסמה, פתח את 'הגדרות' > 'פייסבוק' והקש על שמך."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "חשבון הפייסבוק לא הוגדר במכשיר."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "החשבון שלך לא אושר. התחבר ל-www.facebook.com ופעל בהתאם להוראות שיוצגו."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "לא ניתן להתחבר לאפליקציות כעת. התחבר ל-www.facebook.com ופעל בהתאם להוראות שיוצגו."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "חדש! אתה מחליט - בחר איזה מידע אתה רוצה לשתף עם האפליקציות."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "התחבר"; /* The label for FBSDKSendButton */ "SendButton.Send" = "שלח"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "שתף"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/hi.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "अपने स्मार्टफ़ोन या कंप्यूटर पर %@ पर जाएँ और यह कोड डालें:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "ठीक"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "रद्द करें"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "अपने Facebook खाते से फिर से कनेक्ट होने के लिए कृपया इस एप्लिकेशन में फिर से लॉग इन करें."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "ठीक"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "सर्वर अस्थायी रूप से व्यस्त है, कृपया फिर से कोशिश करें."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "पसंद करें"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "पसंद किया"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "रद्द करें"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "लॉग आउट करें"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Facebook का उपयोग करके लॉग इन किया हुआ है"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "%@ के रूप में लॉग इन किया हुआ है"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "लॉग इन करें"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Facebook से लॉग इन करें"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "लॉग आउट"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Facebook खाते को एक्सेस नहीं दी गई है. डिवाइस सेटिंग सत्यापित करें."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Facebook से कनेक्ट होने में असमर्थ. कृपया अपने नेटवर्क कनेक्शन की जाँच करें फिर से प्रयास करें."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "आपका Facebook पासवर्ड बदल गया है. अपना पासवर्ड कन्फ़र्म करने के लिए, सेटिंग > Facebook खोलें और अपना नाम टैप करें."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "डिवाइस पर Facebook खाता कॉन्फ़िगर नहीं किया गया है."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "आपका खाता कन्फ़र्म नहीं किया गया है. कृपया www.facebook.com में लॉग इन करें और दिए गए निर्देशों का पालन करें."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "आप इस समय एप्लिकेशन में लॉग इन नहीं कर सकते. कृपया www.facebook.com में लॉग इन करें और दिए गए निर्देशों का पालन करें."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "नया! आप नियंत्रण में हैं - चुनें कि आप एप्लिकेशन से कौन-सी जानकारी साझा करना चाहते हैं."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "लॉग इन करें"; /* The label for FBSDKSendButton */ "SendButton.Send" = "भेजें"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "साझा करें"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/hr.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Posjetite %@ na pametnom telefonu ili računalu i unesite ovaj kôd:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "U redu"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Odustani"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Ponovo se prijavite u ovu aplikaciju kako biste se ponovo povezali s Facebook računom."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "U redu"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Poslužitelj je privremeno zauzet, pokušajte ponovo."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Sviđa mi se"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Označeno sa "sviđa mi se""; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Odustani"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Odjavi se"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Prijavljen putem Facebooka"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Prijavljen kao %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Prijavi se"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Prijava putem Facebooka"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Odjavi se"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Pristup Facebook računu nije odobren. Provjerite postavke uređaja."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Povezivanje s Facebookom nije uspjelo. Provjerite mrežnu vezu i pokušajte ponovo."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Promijenili ste lozinku za Facebook. Za potvrdu lozinke otvorite Postavke > Facebook i dodirnite svoje ime."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Na uređaju nije konfiguriran račun za Facebook."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Vaš račun nije potvrđen. Prijavite se na www.facebook.com i slijedite upute."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "U ovome trenutku prijava u aplikacije nije moguća. Prijavite se na www.facebook.com i slijedite upute."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Novo! Vi odlučujete – odaberite koje informacije želite podijeliti u aplikacijama."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Prijava"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Pošalji"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Dijeli"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/hu.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Keresd fel a(z) %@ oldalt a telefonodról vagy számítógépről, és írd be a következő kódot:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Mégsem"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Kérjük, jelentkezz be újra ebbe az alkalmazásba, ha szeretnéd ismét összekapcsolni a Facebook-fiókoddal."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "A kiszolgáló átmenetileg foglalt, próbáld meg újra."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Tetszik"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Kedveled"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Mégsem"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Kijelentkezés"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Bejelentkezve a Facebook használatával"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Bejelentkezve %@ néven"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Bejelentkezés"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Bejelentkezés a Facebook használatával"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Kijelentkezés"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "A Facebook-fiókhoz nincs megadva a hozzáférés. Ellenőrizd az eszköz beállításait."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Nem sikerült kapcsolódni a Facebookhoz. Ellenőrizd a hálózati kapcsolatot, majd próbáld meg újra."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Facebook-jelszavad megváltozott. A jelszó megerősítéséhez nyisd meg a Settings (Beállítások) > Facebook pontot, és koppints a nevedre."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "A készüléken nincs beállítva a Facebook-fiók."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "A fiókod nincs megerősítve. Jelentkezz be a www.facebook.com címre, és kövesd az utasításokat."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Jelenleg nem tudsz alkalmazásokba bejelentkezni. Jelentkezz be a www.facebook.com címre, és kövesd az utasításokat."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Újdonság! A döntés a kezedben van: kiválaszthatod, hogy milyen adatokat osztasz meg az alkalmazásokkal."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Bejelentkezés"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Küldés"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Megosztás"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/id.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Buka %@ dari smartphone Anda atau komputer dan masukkan kode ini:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Batal"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Harap masuk ke aplikasi ini lagi untuk menghubungkan kembali akun Facebook Anda."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Server untuk sementara sedang sibuk, harap coba lagi."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Suka"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Disukai"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Batal"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Keluar"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Masuk menggunakan Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Masuk sebagai %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Masuk"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Masuk menggunakan Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Keluar"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Akses belum diberikan ke akun Facebook. Verifikasi pengaturan perangkat."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Tidak dapat terhubung ke Facebook. Periksa koneksi jaringan dan coba lagi."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Kata sandi Facebook Anda telah diubah. Untuk mengonfirmasi kata sandi Anda, buka Pengaturan > Facebook, lalu ketuk nama Anda."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Akun Facebook belum dikonfigurasikan di perangkat."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Akun Anda tidak dikonfirmasi. Masuk ke www.facebook.com dan ikuti petunjuknya."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Saat ini Anda tidak dapat masuk ke aplikasi. Masuk ke www.facebook.com dan ikuti petunjuknya."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Baru! Anda memegang kendali - pilih info yang ingin Anda bagikan dengan aplikasi."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Masuk"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Kirim"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Berbagi"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/it.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Accedi a %@ nel tuo smartphone o computer e inserisci questo codice:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Annulla"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Effettua di nuovo l'accesso a questa applicazione per riconnettere il tuo account Facebook."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Il server è temporaneamente occupato, riprova."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Mi piace"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Ti piace"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Annulla"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Esci"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Accesso effettuato tramite Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Accesso effettuato come %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Accedi"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Accedi con Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Esci"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "All'account Facebook non è stato concesso l'accesso. Verifica le impostazioni del dispositivo."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Impossibile connettersi a Facebook. Controlla la tua connessione e riprova."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "La tua password di Facebook è stata modificata. Per confermare la password, apri Impostazioni > Facebook e tocca il tuo nome."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "L'account Facebook non è stato configurato nel dispositivo."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Il tuo account non è stato verificato. Accedi a www.facebook.com e segui le istruzioni fornite."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Impossibile accedere alle applicazioni al momento. Accedi a www.facebook.com e segui le istruzioni fornite."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Novità! Il controllo è nelle tue mani: scegli quali informazioni condividere con le applicazioni."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Accedi"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Invia"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Condividi"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/ja.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "スマートフォンまたはコンピュータから%@にアクセスし、次のコードを入力してください。"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "キャンセル"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "このアプリにもう一度ログインして、Facebookアカウントを再接続してください。"; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "サーバーが一時的にビジーです。もう一度お試しください。"; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "いいね!"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "いいね!済み"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "キャンセル"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "ログアウト"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Facebookを使用してログイン中"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "%@としてログイン中"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "ログイン"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Facebookでログイン"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "ログアウト"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Facebookアカウントにアクセス権が与えられていません。デバイス設定を確認してください。"; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Facebookに接続できませんでした。ネットワーク接続を確認してもう一度お試しください。"; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Facebookパスワードが変更されています。パスワードを確認するには、[設定] > [Facebook]の順に開き、名前をタップしてください。"; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "デバイスにFacebookアカウントが構成されていません。"; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "アカウントが確認されません。www.facebook.comにログインし、表示される説明に従ってください。"; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "今はアプリにログインできません。www.facebook.comにログインし、表示される説明に従ってください。"; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "新機能!アプリと共有する情報をコントロールできます。"; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "ログイン"; /* The label for FBSDKSendButton */ "SendButton.Send" = "送信"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "シェア"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/kn.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "ನಿಮ್ಮ ಸ್ಮಾರ್ಟ್‌ ಫೋನ್‌ ಅಥವಾ ಕಂಪ್ಯೂಟರ್‌ನಲ್ಲಿ %@ ಗೆ ಭೇಟಿ ನೀಡಿ ಮತ್ತು ಈ ಕೋಡ್‌ ಅನ್ನು ನಮೂದಿಸಿ:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "ಸರಿ"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "ರದ್ದುಮಾಡು"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "ನಿಮ್ಮ Facebook ಖಾತೆಯನ್ನು ಮರುಸಂಪರ್ಕಗೊಳಿಸಲು ಈ ಅಪ್ಲಿಕೇಶನ್‌ನಲ್ಲಿ ಮತ್ತೊಮ್ಮೆ ಲಾಗಿನ್‌ ಮಾಡಿ."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "ಸರಿ"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "ಸರ್ವರ್ ತಾತ್ಕಾಲಿಕವಾಗಿ ಕಾರ್ಯನಿರತವಾಗಿದೆ, ದಯವಿಟ್ಟು ನಂತರ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "ಇಷ್ಟವಾಗಿದೆ"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "ಇಷ್ಟಪಟ್ಟಿದ್ದಾರೆ"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "ರದ್ದುಮಾಡು"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "ಲಾಗ್‌ ಔಟ್‌"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Facebook ಬಳಸಿಕೊಂಡು ಲಾಗಿನ್‌ ಮಾಡಲಾಗಿದೆ"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "%@ ರಂತೆ ಲಾಗಿನ್‌ ಮಾಡಲಾಗಿದೆ"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "ಲಾಗ್‌ ಇನ್‌"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Facebook ಮೂಲಕ ಲಾಗ್‌ ಇನ್‌ ಮಾಡಿ"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "ಲಾಗ್‌ ಔಟ್‌"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Facebook ಖಾತೆಗೆ ಪ್ರವೇಶವನ್ನು ಅನುಮತಿಸಲಾಗಿಲ್ಲ. ಸಾಧನದ ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ಪರಿಶೀಲಿಸಿ."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Facebook ಗೆ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ನಿಮ್ಮ ನೆಟ್‌ವರ್ಕ್‌ ಸಂಪರ್ಕವನ್ನು ಪರಿಶೀಲಿಸಿ ಹಾಗೂ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "ನಿಮ್ಮ Facebook ಪಾಸ್‌ವರ್ಡ್‌ ಬದಲಿಸಲಾಗಿದೆ. ನಿಮ್ಮ ಪಾಸ್‌ವರ್ಡ್‌ ಖಚಿತಪಡಿಸಲು, ಸೆಟ್ಟಿಂಗ್‌ಗಳು > Facebook ತೆರೆಯಿರಿ ಮತ್ತು ನಿಮ್ಮ ಹೆಸರನ್ನು ಟ್ಯಾಪ್‌ ಮಾಡಿ."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Facebook ಖಾತೆಯನ್ನು ಸಾಧನದಲ್ಲಿ ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾಗಿಲ್ಲ."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "ನಿಮ್ಮ ಖಾತೆಯನ್ನು ದೃಢೀಕರಿಸಿಲ್ಲ. ದಯವಿಟ್ಟು www.facebook.com ಗೆ ಲಾಗಿನ್‌ ಮಾಡಿ ಮತ್ತು ಕೆಳಗೆ ನೀಡಿದ ಸೂಚನೆಗಳನ್ನು ಅನುಸರಿಸಿ."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "ನೀವು ಈ ಸಮಯದಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ ಲಾಗಿನ್‌ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ. ದಯವಿಟ್ಟು www.facebook.com ಗೆ ಲಾಗಿನ್‌ ಮಾಡಿ ಮತ್ತು ಕೆಳಗೆ ನೀಡಿದ ಸೂಚನೆಗಳನ್ನು ಅನುಸರಿಸಿ."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "ಹೊಸ! ನೀವು ನಿಯಂತ್ರಣದಲ್ಲಿರುವಿರಿ - ನೀವು ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಹಂಚಿಕೊಳ್ಳಲು ಬಯಸುವ ವಿಷಯವನ್ನು ಆರಿಸಿ."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "ಲಾಗ್‌ ಇನ್‌"; /* The label for FBSDKSendButton */ "SendButton.Send" = "ಕಳುಹಿಸಿ"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "ಹಂಚಿಕೊಳ್ಳಿ"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/ko.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "스마트폰이나 컴퓨터에서 %@ 주소를 방문하여 다음 코드를 입력하세요."; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "확인"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "취소"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Facebook 계정을 다시 연결하려면 이 앱에 다시 로그인하세요."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "확인"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "일시적으로 서버 사용량이 많아졌습니다. 다시 시도하세요."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "좋아요"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "좋아요"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "취소"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "로그아웃"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Facebook 계정으로 로그인함"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "%@(으)로 로그인함"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "로그인"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Facebook으로 로그인"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "로그아웃"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Facebook 계정에 대한 액세스가 승인되지 않았습니다. 기기 설정을 확인하세요."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Facebook에 연결할 수 없습니다. 네트워크 연결을 확인하고 다시 시도하세요."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Facebook 비밀번호가 변경되었습니다. 비밀번호를 확인하려면 설정 > Facebook으로 이동하여 이름을 누르세요."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Facebook 계정이 기기에 구성되어 있지 않습니다."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "계정이 확인되지 않았습니다. www.facebook.com에 로그인한 뒤 안내를 따라주세요."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "현재 앱에 로그인할 수 없습니다. www.facebook.com에 로그인한 뒤 안내를 따라주세요."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "새로운 기능! 이제 앱과 어떤 정보를 공유할지 자유롭게 선택할 수 있습니다."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "로그인"; /* The label for FBSDKSendButton */ "SendButton.Send" = "보내기"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "공유하기"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/ml.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "നിങ്ങളുടെ സ്‌മാർട്ട്ഫോണിലെ അല്ലെങ്കിൽ കമ്പ്യൂട്ടറിലെ %@ സന്ദർശിച്ച് ഇനിപ്പറയുന്ന കോഡ് നൽകുക:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "ശരി"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "റദ്ദാക്കുക"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "നിങ്ങളുടെ Facebook അക്കൗണ്ടുമായി വീണ്ടും കണക്‌റ്റുചെയ്യുന്നതിന് ഈ ആപ്ലിക്കേഷനിൽ വീണ്ടും ലോഗിൻ ചെയ്യുക."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "ശരി"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "സെർവർ താൽക്കാലികമായി തിരക്കിലാണ്, വീണ്ടും ശ്രമിക്കുക."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "ലൈക്കുചെയ്യുക"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "ലൈക്കുചെയ്‌‌തു"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "റദ്ദാക്കുക"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "ലോഗ്ഔട്ട് ചെയ്യുക"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Facebook ഉപയോഗിച്ച് ലോഗിൻ ചെയ്‌തു"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "%@ എന്നതായി ലോഗിൻ ചെയ്‌തു"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "ലോഗിൻ ചെയ്യുക"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Facebook ഉപയോഗിച്ച് ലോഗിൻ ചെയ്യുക"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "ലോഗ്ഔട്ട് ചെയ്യുക"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Facebook അക്കൗണ്ടിലേക്ക് ആക്‌സസ് നൽകിയിട്ടില്ല. ഉപകരണ ക്രമീകരണങ്ങൾ പരിശോധിച്ചുറപ്പിക്കുക."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Facebook-ലേക്ക് കണക്‌റ്റുചെയ്യാനായില്ല. നിങ്ങളുടെ നെറ്റ്‌വർക്ക് കണക്ഷൻ പരിശോധിച്ച് വീണ്ടും ശ്രമിക്കുക."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "നിങ്ങളുടെ Facebook പാസ്‌വേഡ് മാറി. പാ‌സ്‌വേഡ് സ്ഥിരീകരിക്കുന്നതിന് ക്രമീകരണങ്ങൾ > Facebook എന്നത് തുറന്ന് പേര് ടാപ്പുചെയ്യുക."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "ഉപകരണത്തിൽ Facebook അക്കൗണ്ട് കോൺഫിഗർ ചെയ്‌തിട്ടില്ല."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "അക്കൗണ്ട് സ്ഥിരീകരിച്ചു. www.facebook.com എന്നതിലേക്ക് ലോഗിൻ ചെയ്‌ത് തന്നിരിക്കുന്ന നിർദ്ദേശങ്ങൾ പാലിക്കുക."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "നിങ്ങൾക്ക് ഈ സമയം ആപ്ലിക്കേഷനുകളിലേക്ക് ലോഗിൻ ചെയ്യാനാവില്ല. www.facebook.com എന്നതിലേക്ക് ലോഗിൻ ചെയ്‌ത് തന്നിരിക്കുന്ന നിർദ്ദേശങ്ങൾ പാലിക്കുക."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "പുതിയത്! നിങ്ങൾ നിയന്ത്രണത്തിലാണ് - നിങ്ങൾക്ക് ആപ്ലിക്കേഷനുകളുമായി പങ്കിടേണ്ടതുണ്ടെങ്കിൽ തിരഞ്ഞെടുക്കുക."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "ലോഗിൻ ചെയ്യുക"; /* The label for FBSDKSendButton */ "SendButton.Send" = "അയയ്‌ക്കുക"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "പങ്കിടൂ"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/mr.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "आपला स्‍मार्ट फोन किंवा संगणकावर %@ ला भेट द्या आणि हा कोड प्रविष्‍ट करा:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "ठीक"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "रद्द करा"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "कृपया आपले फेसबुक खाते रीकनेक्ट करण्यासाठी या अनुप्रयोगावर पुन्हा लॉग इन करा."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "ठीक"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "सर्व्हर तात्पुरता व्यस्त आहे, कृपया पुन्हा प्रयत्न करा."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "आवडले"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "आवडलेले"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "रद्द करा"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "लॉग आउट करा"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "फेसबुक वापरून लॉग इन केले"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "%@ म्हणून लॉग इन केले"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "लॉग इन करा"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "फेसबुकसह लॉग इन करा"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "लॉग आउट करा"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "फेसबुक खात्यावर प्रवेशास मंजूरी दिली गेली नाही. डिव्हाइस सेटिंग्ज सत्यापित करा."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "फेसबुकशी कनेक्ट करण्यात अक्षम. आपले नेटवर्क कनेक्शन तपासा आणि पुन्हा प्रयत्न करा."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "आपला फेसबुक पासवर्ड बदलला आहे. आपल्या पासवर्डची पुष्टी करण्यासाठी, सेटिंग्ज > फेसबुक उघडा आणि आपले नाव टॅप करा."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "डिव्हाइसवर फेसबुक खाते कॉन्फिगर केले गेले नाही."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "आपल्या खात्याची पुष्टी झाली नाही. कृपया www.facebook.com वर लॉग इन करा आणि दिलेल्या सूचनांचे अनुसरण करा."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "आपण यावेळी अनुप्रयोगांवर लॉग इन करू शकत नाही. कृपया www.facebook.com वर लॉग इन करा आणि दिलेल्या सूचनांचे अनुसरण करा."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "नवीन! आपण नियंत्रणात आहात - आपण कोणती माहिती अनुप्रयोगांसह शेअर करू इच्छिता ते निवडा."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "लॉग इन करा"; /* The label for FBSDKSendButton */ "SendButton.Send" = "पाठवा"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "सामायिक करा"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/ms.lproj/FacebookSDK.strings ================================================ /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Batal"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Sila log masuk ke aplikasi ini sekali lagi untuk menyambung semula akaun Facebook anda."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Pelayan ini sibuk buat sementara waktu, sila cuba lagi."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Suka"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Disukai"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Batal"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Log Keluar"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Dilog masuk menggunakan Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Dilog masuk sebagai %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Log masuk"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Log masuk dengan Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Log keluar"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Akses ke akaun Facebook tidak diberikan. Sahkan tetapan peranti."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Tidak dapat menyambung ke Facebook. Semak sambungan rangkaian anda dan cuba lagi."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Kata laluan Facebook anda telah ditukar. Untuk mengesahkan kata laluan anda, buka Tetapan > Facebook dan ketik nama anda."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Akaun Facebook masih belum dikonfigurasikan pada peranti."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Akaun anda tidak disahkan. Sila log masuk ke www.facebook.com dan ikuti arahan yang diberi."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Anda tidak boleh log masuk ke aplikasi pada masa ini. Sila log masuk ke www.facebook.com dan ikuti arahan yang diberi."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Baru! Anda yang mengawal - pilih maklumat yang anda ingin kongsi dengan aplikasi."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Log Masuk"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Hantar"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Kongsi"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/nb.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Gå til %@ på smarttelefonen eller datamaskinen din, og oppgi denne koden:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Avbryt"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Logg deg inn igjen på denne appen for å koble til Facebook-kontoen på nytt."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Serveren er midlertidig opptatt. Prøv på nytt."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Liker"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Likt"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Avbryt"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Logg ut"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Logget inn med Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Logget inn som %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Logg inn"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Logg inn med Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Logg ut"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Det er ikke gitt tilgang til Facebook-kontoen. Bekreft enhetsinnstillinger."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Kunne ikke koble til Facebook. Kontroller nettverkstilkoblingen, og prøv på nytt."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Facebook-passordet ditt er endret. Bekreft passordet ditt ved å gå til Innstillinger > Facebook og trykke på navnet ditt."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Facebook-kontoen er ikke konfigurert på enheten."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Kontoen din er bekreftet. Logg deg inn på www.facebook.com, og følg instruksjonene."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Du kan ikke logge deg inn på apper for øyeblikket. Logg deg inn på www.facebook.com, og følg instruksjonene."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Nyhet! Du bestemmer – velg hvilke opplysninger du vil dele med appene."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Logg inn"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Send"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Del"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/nl.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Ga op je smartphone of computer naar %@ en voer deze code in:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Annuleren"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Meld je nogmaals aan bij deze app om verbinding te maken met je Facebook-account."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "De server is tijdelijk niet beschikbaar. Probeer het opnieuw."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Vind ik leuk"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Vind ik leuk"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Annuleren"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Afmelden"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Aangemeld via Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Aangemeld als %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Aanmelden"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Aanmelden met Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Afmelden"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Er is geen toegang verleend aan het Facebook-account. Verifieer de apparaatinstellingen."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Er kan geen verbinding worden gemaakt met Facebook. Controleer je netwerkverbinding en probeer het opnieuw."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Je Facebook-wachtwoord is gewijzigd. Open Instellingen > Facebook en tik op je naam om je wachtwoord te bevestigen."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Het Facebook-account is niet geconfigureerd op het apparaat."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Je account is niet bevestigd. Meld je aan bij www.facebook.com en volg de instructies."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Je kunt je momenteel niet aanmelden bij apps. Meld je aan bij www.facebook.com en volg de instructies."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Nieuw! Jij hebt de controle. Kies welke informatie je met apps wilt delen."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Aanmelden"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Verzenden"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Delen"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/pa.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "ਆਪਣੇ ਸਮਾਰਟਫ਼ੋਨ ਜਾਂ ਕੰਪਿਊਟਰ 'ਤੇ %@ ਵਿੱਚ ਜਾਓ ਅਤੇ ਇਸ ਕੋਡ ਨੂੰ ਦਾਖ਼ਲ ਕਰੋ:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "ਠੀਕ"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "ਰੱਦ ਕਰੋ"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "ਕਿਰਪਾ ਕਰਕੇ ਆਪਣੇ Facebook ਖਾਤੇ ਨਾਲ ਮੁੜ ਕਨੈਕਟ ਕਰਨ ਲਈ ਇਸ ਐਪ ਵਿੱਚ ਦੁਬਾਰਾ ਲੌਗ ਇਨ ਕਰੋ।"; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "ਠੀਕ"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "ਇਹ ਸਰਵਰ ਅਸਥਾਈ ਰੂਪ ਵਿੱਚ ਵਿਅਸਤ ਹੈ, ਕਿਰਪਾ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "ਪਸੰਦ ਕਰੋ"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "ਪਸੰਦ ਕੀਤਾ ਗਿਆ"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "ਰੱਦ ਕਰੋ"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "ਲੌਗ ਆਉਟ ਕਰੋ"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Facebook ਦਾ ਉਪਯੋਗ ਕਰਕੇ ਲੌਗ ਇਨ ਕੀਤਾ ਗਿਆ"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "%@ ਵੱਜੋਂ ਲੌਗ ਇਨ ਕੀਤਾ ਗਿਆ"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "ਲੌਗ ਇਨ ਕਰੋ"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Facebook ਦੇ ਨਾਲ ਲੌਗ ਇਨ ਕਰੋ"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "ਲੌਗ ਆਉਟ ਕਰੋ"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Facebook ਖਾਤੇ ਨੂੰ ਐਕਸੈਸ ਪ੍ਰਦਾਨ ਨਹੀਂ ਕੀਤੀ ਗਈ। ਡਿਵਾਈਸ ਸੈੱਟਿੰਗਜ਼ ਦੀ ਪੁਸ਼ਟੀ ਕਰੋ।"; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Facebook ਨਾਲ ਕਨੈਕਟ ਕਰਨ ਵਿੱਚ ਅਸਮਰਥਿਤ ਆਪਣੇ ਨੈੱਟਵਰਕ ਕਨੈਕਸ਼ਨ ਦੀ ਜਾਂਚ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "ਤੁਹਾਡੇ Facebook ਪਾਸਵਰਡ ਨੂੰ ਬਦਲ ਦਿੱਤਾ ਗਿਆ ਹੈ। ਆਪਣੇ ਪਾਸਵਰਡ ਦੀ ਪੁਸ਼ਟੀ ਕਰਨ ਲਈ, ਸੈੱਟਿੰਗਜ਼ > Facebook ਖੋਲ੍ਹੋ ਅਤੇ ਆਪਣੇ ਨਾਂ ਨੂੰ ਟੈਪ ਕਰੋ।"; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Facebook ਖਾਤੇ ਨੂੰ ਡਿਵਾਈਸ 'ਤੇ ਕਨਫ਼ੀਗਰ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ।"; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "ਤੁਹਾਡੇ ਖਾਤੇ ਦੀ ਪੁਸ਼ਟੀ ਨਹੀਂ ਕੀਤੀ ਗਈ ਹੈ। ਕਿਰਪਾ ਕਰਕੇ www.facebook.com ਵਿੱਚ ਲੌਗ ਇਨ ਕਰੋ ਅਤੇ ਹੇਠਾਂ ਦਿੱਤੇ ਨਿਰਦੇਸ਼ਾਂ ਦਾ ਪਾਲਣ ਕਰੋ।"; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "ਤੁਸੀਂ ਇਸ ਸਮੇਂ ਐਪ ਵਿੱਚ ਲੌਗ ਇਨ ਨਹੀਂ ਕਰ ਸਕਦੇ ਹੋ। ਕਿਰਪਾ ਕਰਕੇ www.facebook.com ਵਿੱਚ ਲੌਗ ਇਨ ਕਰੋ ਅਤੇ ਹੇਠਾਂ ਦਿੱਤੇ ਨਿਰਦੇਸ਼ਾਂ ਦਾ ਪਾਲਣ ਕਰੋ।"; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "ਨਵਾਂ! ਤੁਸੀਂ ਨਿਯੰਤਰਣ ਵਿੱਚ ਹੋ - ਉਹ ਜਾਣਕਾਰੀ ਚੁਣੋ ਜੋ ਤੁਸੀਂ ਐਪਸ ਦੇ ਨਾਲ ਸਾਂਝੀ ਕਰਨੀ ਚਾਹੁੰਦੇ ਹੋ।"; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "ਲੌਗ ਇਨ ਕਰੋ"; /* The label for FBSDKSendButton */ "SendButton.Send" = "ਸਾਂਝਾ ਕਰੋ"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "ਭੇਜੋ"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/pl.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Przejdź do %@ na smartfonie lub komputerze i wprowadź ten kod:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Anuluj"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Zaloguj się jeszcze raz do aplikacji, aby ponownie przyłączyć swoje konto na Facebooku."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Serwer jest zajęty, spróbuj później."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Lubię to!"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Polubione"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Anuluj"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Wyloguj się"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Zalogowano przez Facebooka"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Zalogowano jako %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Zaloguj się"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Zaloguj się przez Facebooka"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Wyloguj się"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Brak dostępu z tego konta na Facebooku. Sprawdź ustawienia urządzenia."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Nie można połączyć się z Facebookiem. Sprawdź połączenie sieciowe i spróbuj ponownie."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Twoje hasło do Facebooka zostało zmienione. Aby potwierdzić hasło, otwórz Ustawienia > Facebook i dotknij swojego imienia i nazwiska."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Na tym urządzeniu nie skonfigurowano konta na Facebooku."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Konto niepotwierdzone. Zaloguj się przez stronę www.facebook.com i postępuj zgodnie ze wskazówkami."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Brak możliwości logowania się do aplikacji. Zaloguj się przez stronę www.facebook.com i postępuj zgodnie ze wskazówkami."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Nowość! Masz pełną kontrolę – określ, jakie informacje chcesz udostępniać aplikacjom."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Zaloguj się"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Wyślij"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Udostępnij"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/pt.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Acesse %@ no seu smartphone ou computador e insira este código:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Cancelar"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Entre nesse aplicativo novamente para reconectar sua conta do Facebook."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "O servidor está temporariamente ocupado. Tente novamente."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Curtir"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Curtiu"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Cancelar"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Sair"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Você entrou usando o Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Conectado como %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Entrar"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Entrar com o Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Sair"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "O acesso à conta do Facebook não foi permitido. Verifique as configurações do dispositivo."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Não foi possível se conectar ao Facebook. Verifique sua conexão de rede e tente novamente."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "A sua senha do Facebook foi alterada. Para confirmar a sua senha, abra Configurações > Facebook e toque no seu nome."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "A conta do Facebook não foi configurada no dispositivo."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "A sua conta não foi confirmada. Entre no site www.facebook.com e siga as instruções fornecidas."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Não é possível entrar em aplicativos neste momento. Entre no site www.facebook.com e siga as instruções fornecidas."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Novidade! Você está no controle - escolha quais informações quer compartilhar com os aplicativos."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Entrar"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Envio"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Compartilhar"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/pt_PT.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Visita %@ no teu smartphone ou computador e insere este código:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Cancelar"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Volta a iniciar sessão nesta aplicação para te ligares novamente à tua conta do Facebook."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "O servidor está temporariamente ocupado. Tenta novamente."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Gosto"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Gostei"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Cancelar"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Terminar sessão"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Com sessão iniciada através do Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Com sessão iniciada como %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Iniciar sessão"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Iniciar sessão com o Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Terminar a sessão"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "O acesso não foi concedido à conta do Facebook. Verificar as definições do dispositivo."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Não é possível ligar ao Facebook. Verifica a tua ligação à rede e tenta novamente."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "A tua palavra-passe do Facebook foi alterada. Para confirmares a tua palavra-passe, abre as Definições > Facebook e toca no teu nome."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "A conta do Facebook não foi configurada no dispositivo."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "A tua conta não foi confirmada. Inicia sessão em www.facebook.com e segue as instruções indicadas."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Não podes iniciar sessão em aplicações neste momento. Inicia sessão em www.facebook.com e segue as instruções indicadas."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Novidade! Tens o controlo: escolhe a informação que pretendes partilhar com as aplicações."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Iniciar sessão"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Enviar"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Partilhar"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/ru.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Откройте «%@» на своем смартфофне или компьютере и введите этот код:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Отменить"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Войдите в это приложение еще раз, чтобы повторно подключить ваш аккаунт Facebook."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Сервер временно загружен, повторите попытку."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Нравится"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Понравилось"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Отменить"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Выход"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Выполнен вход с помощью Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Вы вошли как %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Вход"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Вход через Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Выход"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Аккаунту Facebook доступ не предоставлен. Проверьте настройки устройства."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Не удалось подключиться к Facebook. Проверьте сетевое подключение и повторите попытку."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Ваш пароль Facebook изменен. Чтобы подтвердить пароль, откройте «Настройки» > Facebook и коснитесь вашего имени."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "На устройстве не настроен аккаунт Facebook."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Ваш аккаунт не подтвержден. Войдите на сайт www.facebook.com и следуйте инструкциям."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Сейчас нельзя войти в приложения. Войдите на сайт www.facebook.com и следуйте инструкциям."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Новинка! У вас все под контролем — выбирайте, какой информацией вы хотите поделиться с приложениями."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Вход в систему"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Отправить"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Поделиться"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/sk.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Navštívte %@ v smartfóne alebo počítači a zadajte tento kód:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Zrušiť"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Ak sa chcete znova pripojiť k svojmu účtu na Facebooku, prihláste sa znova do tejto aplikácie."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Server je dočasne zaneprázdnený – skúste znova."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Páči sa mi to"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Páči sa mi to"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Zrušiť"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Odhlásiť"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Prihlásený cez Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Prihlásený ako %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Prihlásiť sa"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Prihlásiť sa cez Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Odhlásiť sa"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Danému účtu na Facebooku nebol poskytnutý prístup. Skontrolujte nastavenia zariadenia."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Nedá sa pripojiť k Facebooku. Skontrolujte svoje sieťové pripojenie a skúste znova."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Vaše heslo pre Facebook sa zmenilo. Na potvrdenie svojho hesla otvorte Nastavenia > Facebook a ťuknite na svoje meno."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Daný účet na Facebooku nebol nastavený v zariadení."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Váš účet nie je potvrdený. Prihláste sa na stránke www.facebook.com a postupujte podľa pokynov."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Momentálne sa nemôžete prihlásiť do aplikácií. Prihláste sa na stránke www.facebook.com a postupujte podľa pokynov."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Novinka! Máte to pod kontrolou: vyberte, ktoré informácie chcete zdieľať s aplikáciami."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Prihlásenie sa"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Odoslať"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Zdieľať"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/sv.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Besök %@ på din smartphone eller dator och ange den här koden:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Avbryt"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Logga in på den här appen igen om du vill ansluta ditt Facebook-konto på nytt."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Servern är upptagen för tillfället. Försök igen."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Gilla"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Gillade"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Avbryt"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Logga ut"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Inloggad med Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Inloggad som %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Logga in"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Logga in med Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Logga ut"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Du har inte fått tillgång till Facebook-kontot. Verifiera enhetsinställningar."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Det går inte att ansluta till Facebook. Kontrollera nätverksanslutningen och försök igen."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Ditt Facebook-lösenord har ändrats. Bekräfta lösenordet genom att öppna Inställningar > Facebook och skriva in ditt namn."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Facebook-konto har inte konfigurerats på enheten."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Ditt konto har inte bekräftats. Logga in på www.facebook.com och följ instruktionerna."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Du kan inte logga in på appar för närvarande. Logga in på www.facebook.com och följ instruktionerna."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Nyhet! Du bestämmer – välj vilken info du vill dela med appar."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Logga in"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Skicka"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Dela"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/ta.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "உங்கள் ஸ்மார்ட்ஃபோன் அல்லது கணினியில் %@ ஐப் பார்வையிட்டு, பின்வரும் குறியீட்டை உள்ளிடவும்:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "சரி"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "ரத்துசெய்"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "உங்கள் Facebook கணக்கில் மீண்டும் இணைய, இந்தப் பயன்பாட்டில் மீண்டும் உள்நுழையவும்."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "சரி"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "சேவையகம் தற்காலிகமாக பிஸியாக உள்ளது, மீண்டும் முயற்சிக்கவும்."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "விருப்பம்"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "விரும்பப்பட்டது"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "ரத்துசெய்"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "வெளியேறு"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Facebook மூலம் உள்நுழையப்பட்டுள்ளது"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "%@ இல் உள்நுழைந்துள்ளீர்கள்"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "உள்நுழைவு"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Facebook மூலம் உள்நுழையவும்"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "வெளியேறு"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Facebook கணக்கிற்கு அணுகல் வழங்கப்படவில்லை. சாதன அமைப்புகளைச் சரிபார்க்கவும்."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Facebook இல் இணைய முடியவில்லை. இணைய இணைப்பைச் சரிபார்த்து, மீண்டும் முயற்சிக்கவும்."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Facebook கடவுச்சொல் மாற்றப்பட்டது. கடவுச்சொல்லை உறுதிசெய்ய, அமைப்புகள் > Facebook க்கு சென்று உங்கள் பெயரைத் தட்டவும்."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "சாதனத்தில் Facebook கணக்கு உள்ளமைக்கப்படவில்லை."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "உங்கள் கணக்கு உறுதிசெய்யப்படவில்லை. www.facebook.com இல் உள்நுழைந்து, வழங்கப்பட்டுள்ள வழிமுறைகளைப் பின்பற்றவும்."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "இப்போது பயன்பாடுகளில் உள்நுழைய முடியாது. www.facebook.com இல் உள்நுழைந்து, வழங்கப்பட்டுள்ள வழிமுறைகளைப் பின்பற்றவும்."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "புதிது! உங்கள் கட்டுப்பாட்டில் இருப்பதால், பயன்பாடுகளுடன் பகிர வேண்டிய தகவலைத் தேர்வுசெய்யவும்."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "உள்நுழைவு"; /* The label for FBSDKSendButton */ "SendButton.Send" = "அனுப்பு"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "பகிர்"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/te.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "మీ స్మార్ట్‌ఫోన్ లేదా కంప్యూటర్‌లో %@ సందర్శించి, ఈ కోడ్‌ను నమోదు చేయండి:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "ఒప్పుకుంటున్నాను"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "రద్దు చేయి"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "దయచేసి మీ Facebook ఖాతాను మళ్లీ కనెక్ట్ చేయడానికి ఈ అప్లికేషన్‌కు మళ్లీ లాగిన్ చేయండి."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "ఒప్పుకుంటున్నాను"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "సర్వర్ తాత్కాలికంగా బిజీగా ఉంది, దయచేసి మళ్లీ ప్రయత్నించండి."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "ఇష్టంగా గుర్తు పెట్టు"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "ఇష్టంగా గుర్తు పెట్టబడింది"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "రద్దు చేయి"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "లాగ్ అవుట్ చేయి"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Facebook ఉపయోగించి లాగిన్ చేసారు"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "%@గా లాగిన్ చేసారు"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "లాగిన్ చేయి"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Facebookతో లాగిన్ చేయి"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "లాగ్ అవుట్ చేయి"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Facebook ఖాతాకు ప్రాప్యత మంజూరు చేయలేదు. పరికర సెట్టింగ్‌లను సరిచూడండి."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Facebookకి కనెక్ట్ చేయడం సాధ్యపడలేదు. మీ నెట్‌వర్క్ కనెక్షన్‌ను తనిఖీ చేసి, మళ్లీ ప్రయత్నించండి."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "మీ Facebook పాస్‌వర్డ్ మారింది. మీ పాస్‌వర్డ్‌ను నిర్ధారించడానికి, సెట్టింగ్‌లు > Facebook తెరిచి, మీ పేరు నొక్కండి."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "పరికరంలో Facebook ఖాతా కాన్ఫిగర్ చేయబడలేదు."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "మీ ఖాతా నిర్ధారించబడలేదు. దయచేసి www.facebook.comకి లాగిన్ చేసి, అందించిన సూచనలను అనుసరించండి."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "ప్రస్తుతం మీరు అప్లికేషన్‌లకు లాగిన్ చేయలేరు. దయచేసి www.facebook.comకి లాగిన్ చేసి, అందించిన సూచనలను అనుసరించండి."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "సరికొత్తది! మీకు నియంత్రణ ఉంది - మీరు అప్లికేషన్‌లతో ఏ సమాచారాన్ని భాగస్వామ్యం చేయాలనుకుంటున్నారో ఎంచుకోండి."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "లాగిన్ చేయండి"; /* The label for FBSDKSendButton */ "SendButton.Send" = "పంపు"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "భాగస్వామ్యం చేయండి"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/th.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "ไปที่ %@ ในสมาร์ทโฟนหรือคอมพิวเตอร์ของคุณ แล้วป้อนรหัสนี้:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "ตกลง"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "ยกเลิก"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "โปรดลงชื่อเข้าใช้แอพนี้อีกครั้งเพื่อเชื่อมต่อบัญชีผู้ใช้ Facebook ของคุณใหม่"; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "ตกลง"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "เซิร์ฟเวอร์ไม่พร้อมให้บริการชั่วคราว โปรดลองใหม่อีกครั้ง"; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "ถูกใจ"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "ถูกใจแล้ว"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "ยกเลิก"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "ออกจากระบบ"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "เข้าสู่ระบบโดยใช้ Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "เข้าสู่ระบบในชื่อ %@"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "เข้าสู่ระบบ"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "เข้าสู่ระบบด้วย Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "ออกจากระบบ"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "บัญชีผู้ใช้ Facebook ไม่ได้รับอนุญาตให้เข้าถึง ตรวจสอบการตั้งค่าของอุปกรณ์"; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "ไม่สามารถเชื่อมต่อกับ Facebook ตรวจสอบการเชื่อมต่อเครือข่ายและลองอีกครั้ง"; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "เปลี่ยนรหัสผ่าน Facebook ของคุณแล้ว เพื่อยืนยันรหัสผ่านของคุณ ให้เปิด การตั้งค่า > Facebook แล้วแตะชื่อของคุณ"; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "บัญชีผู้ใช้ Facebook ไม่ได้รับการกำหนดค่าบนอุปกรณ์เครื่องนี้"; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "บัญชีผู้ใช้ของคุณไม่ได้รับการยืนยัน โปรดเข้าสู่ระบบที่ www.facebook.com และทำตามคำแนะนำที่ปรากฏ"; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "คุณไม่สามารถเข้าสู่ระบบของแอพได้ในตอนนี้ โปรดเข้าสู่ระบบที่ www.facebook.com และทำตามคำแนะนำที่ปรากฏ"; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "ใหม่! คุณเป็นฝ่ายควบคุม โปรดเลือกสิ่งที่คุณต้องการแชร์ด้วยแอพ"; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "เข้าสู่ระบบ"; /* The label for FBSDKSendButton */ "SendButton.Send" = "ส่ง"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "แชร์"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/tr.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Akıllı telefonunda veya bilgisayarında %@ adresine git ve bu kodu gir:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "Tamam"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "İptal"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Facebook hesabına yeniden bağlanmak için lütfen bu uygulamaya tekrar giriş yap."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "Tamam"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Sunucu geçici olarak meşgul. Lütfen tekrar dene."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Beğen"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Beğendin"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "İptal"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Çıkış Yap"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Facebook ile giriş yapıldı"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "%@ olarak giriş yapıldı"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Giriş yap"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Facebook ile giriş yap"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Çıkış yap"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Facebook hesabına erişim izni verilmedi. Cihaz ayarlarını doğrula."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Facebook'a bağlanılamıyor. Ağ bağlantını kontrol edip tekrar dene."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Facebook şifren değiştirildi. Şifreni onaylamak için Ayarlar > Facebook'u aç ve adına dokunun."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Facebook hesabı cihaz üzerinde yapılandırılmadı."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Hesabın onaylanmadı. Lütfen www.facebook.com adresine giriş yap ve verilen talimatları izle."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Şu an için uygulamalara giriş yapamazsın. Lütfen www.facebook.com adresine giriş yap ve verilen talimatları izle."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Yeni! Kontrol sende. Uygulamalarla paylaşmak istediğin bilgileri seç."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Giriş Yap"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Gönder"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Paylaş"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/vi.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "Truy cập %@ trên điện thoại thông minh hoặc máy tính và nhập mã sau:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "OK"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "Hủy"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "Vui lòng đăng nhập lại vào ứng dụng này để kết nối lại tài khoản Facebook của bạn."; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "OK"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "Máy chủ hiện đang bận, vui lòng thử lại sau."; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "Thích"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "Đã thích"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "Hủy"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "Đăng xuất"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "Đã đăng nhập bằng Facebook"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "Đã đăng nhập với tư cách là"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "Đăng nhập"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "Đăng nhập bằng Facebook"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "Đăng xuất"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "Quyền truy cập chưa được cấp cho tài khoản Facebook. Xác minh thiết lập của thiết bị."; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "Không thể kết nối với Facebook. Vui lòng kiểm tra kết nối mạng của bạn và thử lại."; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "Mật khẩu Facebook của bạn đã thay đổi. Để xác nhận mật khẩu của bạn, hãy mở Thiết lập > Facebook và nhấn vào tên bạn."; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Tài khoản Facebook chưa được định cấu hình trên thiết bị."; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "Tài khoản của bạn không được xác nhận. Vui lòng đăng nhập vào www.facebook.com và làm theo hướng dẫn được cung cấp."; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "Bạn không thể đăng nhập vào các ứng dụng lúc này. Vui lòng đăng nhập vào www.facebook.com và làm theo hướng dẫn được cung cấp."; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "Mới! Bạn đang có quyền kiểm soát - hãy chọn thông tin bạn muốn chia sẻ với các ứng dụng."; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "Đăng nhập"; /* The label for FBSDKSendButton */ "SendButton.Send" = "Gửi"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "Chia sẻ"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/zh.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "请用智能手机或电脑访问 %@,然后输入验证码:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "确定"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "取消"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "请再次登录此应用,以便重新连接您的 Facebook 帐户。"; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "确定"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "服务器暂时繁忙,请重试。"; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "赞"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "赞了"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "取消"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "退出"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "已使用 Facebook 登录"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "已以 %@ 身份登录"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "登录"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "使用 Facebook 登录"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "退出"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "未授予该 Facebook 帐户访问权限。验证设备设置。"; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "无法连接到 Facebook。检查网络连接并重试。"; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "您的 Facebook 密码已更改。要确认密码,请打开设置 > Facebook,并轻触您的姓名。"; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "未在设备上配置 Facebook 帐户。"; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "您的帐户未确认。请登录 www.facebook.com,并按照提供的说明操作。"; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "您此时不能登录应用。请登录 www.facebook.com,并按照提供的说明操作。"; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "新增功能!一切任您掌控 — 选择您想通过应用分享的信息。"; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "登录"; /* The label for FBSDKSendButton */ "SendButton.Send" = "发送"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "分享"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/zh_Hant_HK.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "在智能手機或電腦前往 %@ 並輸入此代碼:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "確定"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "取消"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "請再次登入此應用程式以重新連接您的 Facebook 帳戶。"; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "確定"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "伺服器暫時忙碌中,請再試一次。"; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "讚好"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "已讚好"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "取消"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "登出"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "使用 Facebook 登入"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "以 %@ 身分登入"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "登入"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "使用 Facebook 登入"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "登出"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "沒有獲得 Facebook 帳戶的存取授權。確認裝置設定。"; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "無法與 Facebook 連線。請檢查網絡連線,然後再試一次。"; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "您的 Facebook 密碼已經變更。要確認密碼,請開啟設定 > Facebook,然後點按您的名稱。"; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "Facebook 帳戶尚未在此裝置上設定。"; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "您的帳戶尚未確認。請登入 www.facebook.com 並依據指示操作。"; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "您現時無法登入應用程式。請登入 www.facebook.com 並依據指示操作。"; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "最新消息!控制權在您 - 選擇您要與應用程式分享的資訊。"; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "登入"; /* The label for FBSDKSendButton */ "SendButton.Send" = "傳送"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "分享"; ================================================ FILE: Pods/FBSDKCoreKit/FacebookSDKStrings.bundle/Resources/zh_Hant_TW.lproj/FacebookSDK.strings ================================================ /* The format string for device login instructions */ "DeviceLogin.LogInPrompt" = "使用您的智慧型手機或電腦前往 %@,然後輸入此代碼:"; /* The title of the label to dismiss the alert when presenting user facing error messages */ "ErrorRecovery.Alert.OK" = "是"; /* The title of the label to decline attempting error recovery */ "ErrorRecovery.Cancel" = "取消"; /* The fallback message to display to recover invalidated tokens */ "ErrorRecovery.Login.Suggestion" = "請重新登入此應用程式以重新連結您的 Facebook 帳號。"; /* The title of the label to start attempting error recovery */ "ErrorRecovery.OK" = "是"; /* The fallback message to display to retry transient errors */ "ErrorRecovery.Transient.Suggestion" = "伺服器暫時忙碌中,請再試一次。"; /* The label for the FBSDKLikeButton when the object is not currently liked. */ "LikeButton.Like" = "讚"; /* The label for the FBSDKLikeButton when the object is currently liked. */ "LikeButton.Liked" = "說讚"; /* The label for the FBSDKLoginButton action sheet to cancel logging out */ "LoginButton.CancelLogout" = "取消"; /* The label for the FBSDKLoginButton action sheet to confirm logging out */ "LoginButton.ConfirmLogOut" = "登出"; /* The fallback string for the FBSDKLoginButton label when the user name is not available yet */ "LoginButton.LoggedIn" = "已使用 Facebook 登入"; /* The format string for the FBSDKLoginButton label when the user is logged in */ "LoginButton.LoggedInAs" = "以 %@ 身分登入"; /* The short label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogIn" = "登入"; /* The long label for the FBSDKLoginButton when the user is currently logged out */ "LoginButton.LogInLong" = "使用 Facebook 登入"; /* The label for the FBSDKLoginButton when the user is currently logged in */ "LoginButton.LogOut" = "登出"; /* The user facing error message when the app slider has been disabled and login fails. */ "LoginError.SystemAccount.Disabled" = "尚未取得授權,無法存取 Facebook 帳號。請確認裝置設定。"; /* The user facing error message when the Accounts framework encounters a network error. */ "LoginError.SystemAccount.Network" = "無法連線到 Facebook。請檢查網路連線,然後再試一次。"; /* The user facing error message when the device Facebook account password is incorrect and login fails. */ "LoginError.SystemAccount.PasswordChange" = "您的 Facebook 密碼已經更改。若要確認您的密碼,請開啟「設定」>「Facebook」,然後點按您的姓名。"; /* The user facing error message when the device Facebook account is unavailable and login fails. */ "LoginError.SystemAccount.Unavailable" = "尚未透過裝置設定 Facebook 帳號。"; /* The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed. */ "LoginError.SystemAccount.UnconfirmedUser" = "您的帳號尚未確認。請登入 www.facebook.com,然後按照指示操作。"; /* The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed. */ "LoginError.SystemAccount.UserCheckpointed" = "您目前無法登入應用程式。請登入 www.facebook.com,然後按照指示操作。"; /* The message of the FBSDKLoginTooltipView */ "LoginTooltip.Message" = "新消息!您已成功登入,請選擇要與應用程式分享的資訊。"; /* Title of the web dialog that prompts the user to log in to Facebook. */ "LoginWeb.LogInTitle" = "登入"; /* The label for FBSDKSendButton */ "SendButton.Send" = "傳送"; /* The label for FBSDKShareButton */ "ShareButton.Share" = "分享"; ================================================ FILE: Pods/FBSDKCoreKit/LICENSE ================================================ Copyright (c) 2014-present, Facebook, Inc. All rights reserved. You are hereby granted a non-exclusive, worldwide, royalty-free license to use, copy, modify, and distribute this software in source code or binary form for use in connection with the web services and APIs provided by Facebook. As with any software that integrates with the Facebook platform, your use of this software is subject to the Facebook Developer Principles and Policies [http://developers.facebook.com/policy/]. This copyright 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. ================================================ FILE: Pods/FBSDKCoreKit/README.mdown ================================================ Facebook SDK for iOS ==================== This open-source library allows you to integrate Facebook into your iOS app. Learn more about the provided samples, documentation, integrating the SDK into your app, accessing source code, and more at https://developers.facebook.com/docs/ios NOTE: By default, the Facebook SDK for iOS is installed in ~/Documents/FacebookSDK TRY IT OUT ---------- 1. Download the SDK at https://developers.facebook.com/docs/ios or via CocoaPods by adding the 'FBSDKCoreKit', 'FBSDKLoginKit', and 'FBSDKShareKit' pods. 2. Test your install: build and run the project at ~/Documents/FacebookSDK/Samples/Scrumptious/Scrumptious.xcodeproj 3. Check-out the tutorials available online at: https://developers.facebook.com/docs/ios/getting-started 4. Start coding! Visit https://developers.facebook.com/docs/ios for tutorials and reference documentation. FEATURES -------- * Login - https://developers.facebook.com/docs/facebook-login * Sharing - https://developers.facebook.com/docs/sharing * App Links - https://developers.facebook.com/docs/applinks * Graph API - https://developers.facebook.com/docs/ios/graph * Analytics for Apps - https://developers.facebook.com/docs/analytics GIVE FEEDBACK ------------- Please report bugs or issues to https://developers.facebook.com/bugs/ You can also join the Facebook Developers Group on Facebook (https://www.facebook.com/groups/fbdevelopers/) or ask questions on Stack Overflow (http://facebook.stackoverflow.com) LICENSE ------- See the LICENSE file. DEVELOPER TERMS --------------- - By enabling Facebook integrations, including through this SDK, you can share information with Facebook, including information about people’s use of your app. Facebook will use information received in accordance with our Data Use Policy [https://www.facebook.com/about/privacy/], including to provide you with insights about the effectiveness of your ads and the use of your app. These integrations also enable us and our partners to serve ads on and off Facebook. - You may limit your sharing of information with us by updating the Insights control in the developer tool [https://developers.facebook.com/apps/{app_id}/settings/advanced]. - If you use a Facebook integration, including to share information with us, you agree and confirm that you have provided appropriate and sufficiently prominent notice to and obtained the appropriate consent from your users regarding such collection, use, and disclosure (including, at a minimum, through your privacy policy). You further agree that you will not share information with us about children under the age of 13. - You agree to comply with all applicable laws and regulations and also agree to our Terms , including our Platform Policies .and Advertising Guidelines, as applicable . By using the Facebook SDK for iOS you agree to these terms. ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import "FBSDKTooltipView.h" @protocol FBSDKLoginButtonDelegate; /*! @typedef NS_ENUM(NSUInteger, FBSDKLoginButtonTooltipBehavior) @abstract Indicates the desired login tooltip behavior. */ typedef NS_ENUM(NSUInteger, FBSDKLoginButtonTooltipBehavior) { /*! The default behavior. The tooltip will only be displayed if the app is eligible (determined by possible server round trip) */ FBSDKLoginButtonTooltipBehaviorAutomatic = 0, /*! Force display of the tooltip (typically for UI testing) */ FBSDKLoginButtonTooltipBehaviorForceDisplay = 1, /*! Force disable. In this case you can still exert more refined control by manually constructing a `FBSDKLoginTooltipView` instance. */ FBSDKLoginButtonTooltipBehaviorDisable = 2 }; /*! @abstract A button that initiates a log in or log out flow upon tapping. @discussion `FBSDKLoginButton` works with `[FBSDKAccessToken currentAccessToken]` to determine what to display, and automatically starts authentication when tapped (i.e., you do not need to manually subscribe action targets). Like `FBSDKLoginManager`, you should make sure your app delegate is connected to `FBSDKApplicationDelegate` in order for the button's delegate to receive messages. `FBSDKLoginButton` has a fixed height of @c 30 pixels, but you may change the width. `initWithFrame:CGRectZero` will size the button to its minimum frame. */ @interface FBSDKLoginButton : FBSDKButton /*! @abstract The default audience to use, if publish permissions are requested at login time. */ @property (assign, nonatomic) FBSDKDefaultAudience defaultAudience; /*! @abstract Gets or sets the delegate. */ @property (weak, nonatomic) IBOutlet id delegate; /*! @abstract Gets or sets the login behavior to use */ @property (assign, nonatomic) FBSDKLoginBehavior loginBehavior; /*! @abstract The publish permissions to request. @discussion Use `defaultAudience` to specify the default audience to publish to. Note this is converted to NSSet and is only an NSArray for the convenience of literal syntax. */ @property (copy, nonatomic) NSArray *publishPermissions; /*! @abstract The read permissions to request. @discussion Note, that if read permissions are specified, then publish permissions should not be specified. This is converted to NSSet and is only an NSArray for the convenience of literal syntax. */ @property (copy, nonatomic) NSArray *readPermissions; /*! @abstract Gets or sets the desired tooltip behavior. */ @property (assign, nonatomic) FBSDKLoginButtonTooltipBehavior tooltipBehavior; /*! @abstract Gets or sets the desired tooltip color style. */ @property (assign, nonatomic) FBSDKTooltipColorStyle tooltipColorStyle; @end /*! @protocol @abstract A delegate for `FBSDKLoginButton` */ @protocol FBSDKLoginButtonDelegate @required /*! @abstract Sent to the delegate when the button was used to login. @param loginButton the sender @param result The results of the login @param error The error (if any) from the login */ - (void) loginButton:(FBSDKLoginButton *)loginButton didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error; /*! @abstract Sent to the delegate when the button was used to logout. @param loginButton The button that was clicked. */ - (void)loginButtonDidLogOut:(FBSDKLoginButton *)loginButton; @optional /*! @abstract Sent to the delegate when the button is about to login. @param loginButton the sender @return YES if the login should be allowed to proceed, NO otherwise */ - (BOOL) loginButtonWillLogin:(FBSDKLoginButton *)loginButton; @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLoginButton.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKLoginTooltipView.h" @interface FBSDKLoginButton() @end @implementation FBSDKLoginButton { BOOL _hasShownTooltipBubble; FBSDKLoginManager *_loginManager; NSString *_userID; NSString *_userName; } #pragma mark - Object Lifecycle - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } #pragma mark - Properties - (FBSDKDefaultAudience)defaultAudience { return _loginManager.defaultAudience; } - (void)setDefaultAudience:(FBSDKDefaultAudience)defaultAudience { _loginManager.defaultAudience = defaultAudience; } - (FBSDKLoginBehavior)loginBehavior { return _loginManager.loginBehavior; } - (void)setLoginBehavior:(FBSDKLoginBehavior)loginBehavior { _loginManager.loginBehavior = loginBehavior; } #pragma mark - UIView - (void)didMoveToWindow { [super didMoveToWindow]; if (self.window && ((self.tooltipBehavior == FBSDKLoginButtonTooltipBehaviorForceDisplay) || !_hasShownTooltipBubble)) { [self performSelector:@selector(_showTooltipIfNeeded) withObject:nil afterDelay:0]; _hasShownTooltipBubble = YES; } } #pragma mark - Layout - (void)layoutSubviews { CGSize size = self.bounds.size; CGSize longTitleSize = [self sizeThatFits:size title:[self _longLogInTitle]]; NSString *title = (longTitleSize.width <= size.width ? [self _longLogInTitle] : [self _shortLogInTitle]); if (![title isEqualToString:[self titleForState:UIControlStateNormal]]) { [self setTitle:title forState:UIControlStateNormal]; } [super layoutSubviews]; } - (CGSize)sizeThatFits:(CGSize)size { if ([self isHidden]) { return CGSizeZero; } CGSize selectedSize = [self sizeThatFits:size title:[self _logOutTitle]]; CGSize normalSize = [self sizeThatFits:CGSizeMake(CGFLOAT_MAX, size.height) title:[self _longLogInTitle]]; if (normalSize.width > size.width) { return normalSize = [self sizeThatFits:size title:[self _shortLogInTitle]]; } return CGSizeMake(MAX(normalSize.width, selectedSize.width), MAX(normalSize.height, selectedSize.height)); } #pragma mark - UIActionSheetDelegate #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex { if (buttonIndex == 0) { [_loginManager logOut]; [self.delegate loginButtonDidLogOut:self]; } } #pragma clang diagnostic pop #pragma mark - FBSDKButtonImpressionTracking - (NSDictionary *)analyticsParameters { return nil; } - (NSString *)impressionTrackingEventName { return FBSDKAppEventNameFBSDKLoginButtonImpression; } - (NSString *)impressionTrackingIdentifier { return @"login"; } #pragma mark - FBSDKButton - (void)configureButton { _loginManager = [[FBSDKLoginManager alloc] init]; NSString *logInTitle = [self _shortLogInTitle]; NSString *logOutTitle = [self _logOutTitle]; [self configureWithIcon:nil title:logInTitle backgroundColor:[super defaultBackgroundColor] highlightedColor:nil selectedTitle:logOutTitle selectedIcon:nil selectedColor:[super defaultBackgroundColor] selectedHighlightedColor:nil]; self.titleLabel.textAlignment = NSTextAlignmentCenter; [self _updateContent]; [self addTarget:self action:@selector(_buttonPressed:) forControlEvents:UIControlEventTouchUpInside]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_accessTokenDidChangeNotification:) name:FBSDKAccessTokenDidChangeNotification object:nil]; } #pragma mark - Helper Methods - (void)_accessTokenDidChangeNotification:(NSNotification *)notification { if (notification.userInfo[FBSDKAccessTokenDidChangeUserID]) { [self _updateContent]; } } - (void)_buttonPressed:(id)sender { [self logTapEventWithEventName:FBSDKAppEventNameFBSDKLoginButtonDidTap parameters:[self analyticsParameters]]; if ([FBSDKAccessToken currentAccessToken]) { NSString *title = nil; if (_userName) { NSString *localizedFormatString = NSLocalizedStringWithDefaultValue(@"LoginButton.LoggedInAs", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Logged in as %@", @"The format string for the FBSDKLoginButton label when the user is logged in"); title = [NSString localizedStringWithFormat:localizedFormatString, _userName]; } else { NSString *localizedLoggedIn = NSLocalizedStringWithDefaultValue(@"LoginButton.LoggedIn", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Logged in using Facebook", @"The fallback string for the FBSDKLoginButton label when the user name is not available yet"); title = localizedLoggedIn; } NSString *cancelTitle = NSLocalizedStringWithDefaultValue(@"LoginButton.CancelLogout", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Cancel", @"The label for the FBSDKLoginButton action sheet to cancel logging out"); NSString *logOutTitle = NSLocalizedStringWithDefaultValue(@"LoginButton.ConfirmLogOut", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Log Out", @"The label for the FBSDKLoginButton action sheet to confirm logging out"); if ([UIAlertController class]) { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleActionSheet]; alertController.popoverPresentationController.sourceView = self; alertController.popoverPresentationController.sourceRect = self.bounds; UIAlertAction *cancel = [UIAlertAction actionWithTitle:cancelTitle style:UIAlertActionStyleCancel handler:nil]; UIAlertAction *logout = [UIAlertAction actionWithTitle:logOutTitle style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { [_loginManager logOut]; [self.delegate loginButtonDidLogOut:self]; }]; [alertController addAction:cancel]; [alertController addAction:logout]; UIViewController *topMostViewController = [FBSDKInternalUtility topMostViewController]; [topMostViewController presentViewController:alertController animated:YES completion:nil]; } else { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:title delegate:self cancelButtonTitle:cancelTitle destructiveButtonTitle:logOutTitle otherButtonTitles:nil]; [sheet showInView:self]; #pragma clang diagnostic pop } } else { if ([self.delegate respondsToSelector:@selector(loginButtonWillLogin:)]) { if (![self.delegate loginButtonWillLogin:self]) { return; } } FBSDKLoginManagerRequestTokenHandler handler = ^(FBSDKLoginManagerLoginResult *result, NSError *error) { if ([self.delegate respondsToSelector:@selector(loginButton:didCompleteWithResult:error:)]) { [self.delegate loginButton:self didCompleteWithResult:result error:error]; } }; if (self.publishPermissions.count > 0) { [_loginManager logInWithPublishPermissions:self.publishPermissions fromViewController:[FBSDKInternalUtility viewControllerForView:self] handler:handler]; } else { [_loginManager logInWithReadPermissions:self.readPermissions fromViewController:[FBSDKInternalUtility viewControllerForView:self] handler:handler]; } } } - (NSString *)_logOutTitle { return NSLocalizedStringWithDefaultValue(@"LoginButton.LogOut", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Log out", @"The label for the FBSDKLoginButton when the user is currently logged in"); ; } - (NSString *)_longLogInTitle { return NSLocalizedStringWithDefaultValue(@"LoginButton.LogInLong", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Log in with Facebook", @"The long label for the FBSDKLoginButton when the user is currently logged out"); } - (NSString *)_shortLogInTitle { return NSLocalizedStringWithDefaultValue(@"LoginButton.LogIn", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Log in", @"The short label for the FBSDKLoginButton when the user is currently logged out"); } - (void)_showTooltipIfNeeded { if ([FBSDKAccessToken currentAccessToken] || self.tooltipBehavior == FBSDKLoginButtonTooltipBehaviorDisable) { return; } else { FBSDKLoginTooltipView *tooltipView = [[FBSDKLoginTooltipView alloc] init]; tooltipView.colorStyle = self.tooltipColorStyle; if (self.tooltipBehavior == FBSDKLoginButtonTooltipBehaviorForceDisplay) { tooltipView.forceDisplay = YES; } [tooltipView presentFromView:self]; } } - (void)_updateContent { self.selected = ([FBSDKAccessToken currentAccessToken] != nil); if ([FBSDKAccessToken currentAccessToken]) { if (![[FBSDKAccessToken currentAccessToken].userID isEqualToString:_userID]) { FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me?fields=id,name" parameters:nil flags:FBSDKGraphRequestFlagDisableErrorRecovery]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { NSString *userID = [FBSDKTypeUtility stringValue:result[@"id"]]; if (!error && [[FBSDKAccessToken currentAccessToken].userID isEqualToString:userID]) { _userName = [FBSDKTypeUtility stringValue:result[@"name"]]; _userID = userID; } }]; } } } @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConstants.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /*! @abstract The error domain for all errors from FBSDKLoginKit @discussion Error codes from the SDK in the range 300-399 are reserved for this domain. */ FBSDK_EXTERN NSString *const FBSDKLoginErrorDomain; /*! @typedef NS_ENUM(NSInteger, FBSDKLoginErrorCode) @abstract Error codes for FBSDKLoginErrorDomain. */ typedef NS_ENUM(NSInteger, FBSDKLoginErrorCode) { /*! @abstract Reserved. */ FBSDKLoginReservedErrorCode = 300, /*! @abstract The error code for unknown errors. */ FBSDKLoginUnknownErrorCode, /*! @abstract The user's password has changed and must log in again */ FBSDKLoginPasswordChangedErrorCode, /*! @abstract The user must log in to their account on www.facebook.com to restore access */ FBSDKLoginUserCheckpointedErrorCode, /*! @abstract Indicates a failure to request new permissions because the user has changed. */ FBSDKLoginUserMismatchErrorCode, /*! @abstract The user must confirm their account with Facebook before logging in */ FBSDKLoginUnconfirmedUserErrorCode, /*! @abstract The Accounts framework failed without returning an error, indicating the app's slider in the iOS Facebook Settings (device Settings -> Facebook -> App Name) has been disabled. */ FBSDKLoginSystemAccountAppDisabledErrorCode, /*! @abstract An error occurred related to Facebook system Account store */ FBSDKLoginSystemAccountUnavailableErrorCode, /*! @abstract The login response was missing a valid challenge string. */ FBSDKLoginBadChallengeString, }; ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConstants.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLoginConstants.h" NSString *const FBSDKLoginErrorDomain = @"com.facebook.sdk.login"; ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import #import #import ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import @class FBSDKLoginManagerLoginResult; /*! @abstract Describes the call back to the FBSDKLoginManager @param result the result of the authorization @param error the authorization error, if any. */ typedef void (^FBSDKLoginManagerRequestTokenHandler)(FBSDKLoginManagerLoginResult *result, NSError *error); /*! @typedef FBSDKDefaultAudience enum @abstract Passed to open to indicate which default audience to use for sessions that post data to Facebook. @discussion Certain operations such as publishing a status or publishing a photo require an audience. When the user grants an application permission to perform a publish operation, a default audience is selected as the publication ceiling for the application. This enumerated value allows the application to select which audience to ask the user to grant publish permission for. */ typedef NS_ENUM(NSUInteger, FBSDKDefaultAudience) { /*! Indicates that the user's friends are able to see posts made by the application */ FBSDKDefaultAudienceFriends = 0, /*! Indicates that only the user is able to see posts made by the application */ FBSDKDefaultAudienceOnlyMe, /*! Indicates that all Facebook users are able to see posts made by the application */ FBSDKDefaultAudienceEveryone, }; /*! @typedef FBSDKLoginBehavior enum @abstract Passed to the \c FBSDKLoginManager to indicate how Facebook Login should be attempted. @discussion Facebook Login authorizes the application to act on behalf of the user, using the user's Facebook account. Usually a Facebook Login will rely on an account maintained outside of the application, by the native Facebook application, the browser, or perhaps the device itself. This avoids the need for a user to enter their username and password directly, and provides the most secure and lowest friction way for a user to authorize the application to interact with Facebook. The \c FBSDKLoginBehavior enum specifies which log-in methods may be used. The SDK will determine the best behavior based on the current device (such as iOS version). */ typedef NS_ENUM(NSUInteger, FBSDKLoginBehavior) { /*! @abstract This is the default behavior, and indicates logging in through the native Facebook app may be used. The SDK may still use Safari instead. */ FBSDKLoginBehaviorNative = 0, /*! @abstract Attempts log in through the Safari or SFSafariViewController, if available. */ FBSDKLoginBehaviorBrowser, /*! @abstract Attempts log in through the Facebook account currently signed in through the device Settings. @note If the account is not available to the app (either not configured by user or as determined by the SDK) this behavior falls back to \c FBSDKLoginBehaviorNative. */ FBSDKLoginBehaviorSystemAccount, /*! @abstract Attempts log in through a modal \c UIWebView pop up @note This behavior is only available to certain types of apps. Please check the Facebook Platform Policy to verify your app meets the restrictions. */ FBSDKLoginBehaviorWeb, }; /*! @abstract `FBSDKLoginManager` provides methods for logging the user in and out. @discussion `FBSDKLoginManager` works directly with `[FBSDKAccessToken currentAccessToken]` and sets the "currentAccessToken" upon successful authorizations (or sets `nil` in case of `logOut`). You should check `[FBSDKAccessToken currentAccessToken]` before calling logIn* to see if there is a cached token available (typically in your viewDidLoad). If you are managing your own token instances outside of "currentAccessToken", you will need to set "currentAccessToken" before calling logIn* to authorize further permissions on your tokens. */ @interface FBSDKLoginManager : NSObject /*! @abstract the default audience. @discussion you should set this if you intend to ask for publish permissions. */ @property (assign, nonatomic) FBSDKDefaultAudience defaultAudience; /*! @abstract the login behavior */ @property (assign, nonatomic) FBSDKLoginBehavior loginBehavior; /*! @deprecated use logInWithReadPermissions:fromViewController:handler: instead */ - (void)logInWithReadPermissions:(NSArray *)permissions handler:(FBSDKLoginManagerRequestTokenHandler)handler __attribute__ ((deprecated("use logInWithReadPermissions:fromViewController:handler: instead"))); /*! @deprecated use logInWithPublishPermissions:fromViewController:handler: instead */ - (void)logInWithPublishPermissions:(NSArray *)permissions handler:(FBSDKLoginManagerRequestTokenHandler)handler __attribute__ ((deprecated("use logInWithPublishPermissions:fromViewController:handler: instead"))); /*! @abstract Logs the user in or authorizes additional permissions. @param permissions the optional array of permissions. Note this is converted to NSSet and is only an NSArray for the convenience of literal syntax. @param fromViewController the view controller to present from. If nil, the topmost view controller will be automatically determined as best as possible. @param handler the callback. @discussion Use this method when asking for read permissions. You should only ask for permissions when they are needed and explain the value to the user. You can inspect the result.declinedPermissions to also provide more information to the user if they decline permissions. This method will present UI the user. You typically should check if `[FBSDKAccessToken currentAccessToken]` already contains the permissions you need before asking to reduce unnecessary app switching. For example, you could make that check at viewDidLoad. */ - (void)logInWithReadPermissions:(NSArray *)permissions fromViewController:(UIViewController *)fromViewController handler:(FBSDKLoginManagerRequestTokenHandler)handler; /*! @abstract Logs the user in or authorizes additional permissions. @param permissions the optional array of permissions. Note this is converted to NSSet and is only an NSArray for the convenience of literal syntax. @param fromViewController the view controller to present from. If nil, the topmost view controller will be automatically determined as best as possible. @param handler the callback. @discussion Use this method when asking for publish permissions. You should only ask for permissions when they are needed and explain the value to the user. You can inspect the result.declinedPermissions to also provide more information to the user if they decline permissions. This method will present UI the user. You typically should check if `[FBSDKAccessToken currentAccessToken]` already contains the permissions you need before asking to reduce unnecessary app switching. For example, you could make that check at viewDidLoad. */ - (void)logInWithPublishPermissions:(NSArray *)permissions fromViewController:(UIViewController *)fromViewController handler:(FBSDKLoginManagerRequestTokenHandler)handler; /*! @abstract Logs the user out @discussion This calls [FBSDKAccessToken setCurrentAccessToken:nil] and [FBSDKProfile setCurrentProfile:nil]. */ - (void)logOut; /*! @method @abstract Issues an asynchronous renewCredentialsForAccount call to the device's Facebook account store. @param handler The completion handler to call when the renewal is completed. This can be invoked on an arbitrary thread. @discussion This can be used to explicitly renew account credentials and is provided as a convenience wrapper around `[ACAccountStore renewCredentialsForAccount:completion]`. Note the method will not issue the renewal call if the the Facebook account has not been set on the device, or if access had not been granted to the account (though the handler wil receive an error). If the `[FBSDKAccessToken currentAccessToken]` was from the account store, a succesful renewal will also set a new "currentAccessToken". */ + (void)renewSystemCredentials:(void (^)(ACAccountCredentialRenewResult result, NSError *error))handler; @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLoginManager+Internal.h" #import "FBSDKLoginManagerLoginResult+Internal.h" #import #import #import "_FBSDKLoginRecoveryAttempter.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKLoginCompletion.h" #import "FBSDKLoginConstants.h" #import "FBSDKLoginError.h" #import "FBSDKLoginManagerLogger.h" #import "FBSDKLoginUtility.h" static int const FBClientStateChallengeLength = 20; static NSString *const FBSDKExpectedChallengeKey = @"expected_login_challenge"; @implementation FBSDKLoginManager { FBSDKLoginManagerRequestTokenHandler _handler; FBSDKLoginManagerLogger *_logger; // YES if we're calling out to the Facebook app or Safari to perform a log in BOOL _performingLogIn; FBSDKKeychainStore *_keychainStore; } + (void)initialize { if (self == [FBSDKLoginManager class]) { [_FBSDKLoginRecoveryAttempter class]; [FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL]; } } - (instancetype)init { self = [super init]; if (self) { NSString *keyChainServiceIdentifier = [NSString stringWithFormat:@"com.facebook.sdk.loginmanager.%@", [[NSBundle mainBundle] bundleIdentifier]]; _keychainStore = [[FBSDKKeychainStore alloc] initWithService:keyChainServiceIdentifier accessGroup:nil]; } return self; } - (void)logInWithReadPermissions:(NSArray *)permissions handler:(FBSDKLoginManagerRequestTokenHandler)handler { [self logInWithReadPermissions:permissions fromViewController:nil handler:handler]; } - (void)logInWithReadPermissions:(NSArray *)permissions fromViewController:(UIViewController *)fromViewController handler:(FBSDKLoginManagerRequestTokenHandler)handler { [self assertPermissions:permissions]; NSSet *permissionSet = [NSSet setWithArray:permissions]; if (![FBSDKInternalUtility areAllPermissionsReadPermissions:permissionSet]) { [[NSException exceptionWithName:NSInvalidArgumentException reason:@"Publish or manage permissions are not permitted to be requested with read permissions." userInfo:nil] raise]; } self.fromViewController = fromViewController; [self logInWithPermissions:permissionSet handler:handler]; } - (void)logInWithPublishPermissions:(NSArray *)permissions handler:(FBSDKLoginManagerRequestTokenHandler)handler { [self logInWithPublishPermissions:permissions fromViewController:nil handler:handler]; } - (void)logInWithPublishPermissions:(NSArray *)permissions fromViewController:(UIViewController *)fromViewController handler:(FBSDKLoginManagerRequestTokenHandler)handler { [self assertPermissions:permissions]; NSSet *permissionSet = [NSSet setWithArray:permissions]; if (![FBSDKInternalUtility areAllPermissionsPublishPermissions:permissionSet]) { [[NSException exceptionWithName:NSInvalidArgumentException reason:@"Read permissions are not permitted to be requested with publish or manage permissions." userInfo:nil] raise]; } self.fromViewController = fromViewController; [self logInWithPermissions:permissionSet handler:handler]; } - (void)logOut { [FBSDKAccessToken setCurrentAccessToken:nil]; [FBSDKProfile setCurrentProfile:nil]; } + (void)renewSystemCredentials:(void (^)(ACAccountCredentialRenewResult result, NSError *error))handler { FBSDKSystemAccountStoreAdapter *adapter = [FBSDKSystemAccountStoreAdapter sharedInstance]; if (!adapter.accountType) { handler(ACAccountCredentialRenewResultFailed, [FBSDKLoginError errorForFailedLoginWithCode:FBSDKLoginSystemAccountUnavailableErrorCode]); } else if (!adapter.accountType.accessGranted) { handler(ACAccountCredentialRenewResultFailed, [FBSDKLoginError errorForFailedLoginWithCode:FBSDKLoginSystemAccountAppDisabledErrorCode]); } else { [[FBSDKSystemAccountStoreAdapter sharedInstance] renewSystemAuthorization:handler]; } } #pragma mark - Private - (void)assertPermissions:(NSArray *)permissions { for (NSString *permission in permissions) { if (![permission isKindOfClass:[NSString class]]) { [[NSException exceptionWithName:NSInvalidArgumentException reason:@"Permissions must be string values." userInfo:nil] raise]; } if ([permission rangeOfString:@","].location != NSNotFound) { [[NSException exceptionWithName:NSInvalidArgumentException reason:@"Permissions should each be specified in separate string values in the array." userInfo:nil] raise]; } } } - (void)completeAuthentication:(FBSDKLoginCompletionParameters *)parameters expectChallenge:(BOOL)expectChallenge { FBSDKLoginManagerLoginResult *result = nil; NSError *error = parameters.error; NSString *tokenString = parameters.accessTokenString; BOOL cancelled = (tokenString == nil); BOOL challengePassed = YES; if (expectChallenge) { // Perform this check early so we be sure to clear expected challenge in all cases. NSString *challengeReceived = parameters.challenge; NSString *challengeExpected = [self loadExpectedChallenge]; if (![challengeExpected isEqualToString:challengeReceived]) { challengePassed = NO; } // Don't overwrite an existing error, if any. if (!error && !cancelled && !challengePassed) { error = [FBSDKLoginError errorForFailedLoginWithCode:FBSDKLoginBadChallengeString]; } } [self storeExpectedChallenge:nil]; if (!error) { if (!cancelled) { NSSet *grantedPermissions = parameters.permissions; NSSet *declinedPermissions = parameters.declinedPermissions; NSSet *recentlyGrantedPermissions = nil; NSSet *recentlyDeclinedPermissions = nil; [self determineRecentlyGrantedPermissions:&recentlyGrantedPermissions recentlyDeclinedPermissions:&recentlyDeclinedPermissions forGrantedPermission:grantedPermissions declinedPermissions:declinedPermissions]; if (recentlyGrantedPermissions.count > 0) { FBSDKAccessToken *token = [[FBSDKAccessToken alloc] initWithTokenString:tokenString permissions:[grantedPermissions allObjects] declinedPermissions:[declinedPermissions allObjects] appID:parameters.appID userID:parameters.userID expirationDate:parameters.expirationDate refreshDate:[NSDate date]]; result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:token isCancelled:NO grantedPermissions:recentlyGrantedPermissions declinedPermissions:recentlyDeclinedPermissions]; if ([FBSDKAccessToken currentAccessToken]) { [self validateReauthentication:[FBSDKAccessToken currentAccessToken] withResult:result]; // in a reauth, short circuit and let the login handler be called when the validation finishes. return; } } else { cancelled = YES; } } if (cancelled) { NSSet *declinedPermissions = nil; // If a System Account reauthorization was cancelled by the user tapping Don't Allow // then add the declined permissions to the login result. The Accounts framework // doesn't register the decline with Facebook, which is why we don't update the // access token. if ([FBSDKAccessToken currentAccessToken] != nil && parameters.isSystemAccount) { declinedPermissions = parameters.declinedPermissions; } result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:nil isCancelled:YES grantedPermissions:nil declinedPermissions:declinedPermissions]; } } if (result.token) { [FBSDKAccessToken setCurrentAccessToken:result.token]; } [self invokeHandler:result error:error]; } - (void)determineRecentlyGrantedPermissions:(NSSet **)recentlyGrantedPermissionsRef recentlyDeclinedPermissions:(NSSet **)recentlyDeclinedPermissionsRef forGrantedPermission:(NSSet *)grantedPermissions declinedPermissions:(NSSet *)declinedPermissions { NSMutableSet *recentlyGrantedPermissions = [grantedPermissions mutableCopy]; NSSet *previouslyGrantedPermissions = ([FBSDKAccessToken currentAccessToken] ? [FBSDKAccessToken currentAccessToken].permissions : nil); if (previouslyGrantedPermissions.count > 0) { // If there were no requested permissions for this auth - treat all permissions as granted. // Otherwise this is a reauth, so recentlyGranted should be a subset of what was requested. if (_requestedPermissions.count != 0) { [recentlyGrantedPermissions intersectSet:_requestedPermissions]; } } NSMutableSet *recentlyDeclinedPermissions = [_requestedPermissions mutableCopy]; [recentlyDeclinedPermissions intersectSet:declinedPermissions]; if (recentlyGrantedPermissionsRef != NULL) { *recentlyGrantedPermissionsRef = [recentlyGrantedPermissions copy]; } if (recentlyDeclinedPermissionsRef != NULL) { *recentlyDeclinedPermissionsRef = [recentlyDeclinedPermissions copy]; } } - (void)invokeHandler:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error { [_logger endLoginWithResult:result error:error]; [_logger endSession]; _logger = nil; if (_handler) { FBSDKLoginManagerRequestTokenHandler handler = _handler; _handler(result, error); if (handler == _handler) { _handler = nil; } else { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors formatString:@"** WARNING: You are requesting permissions inside the completion block of an existing login." "This is unsupported behavior. You should request additional permissions only when they are needed, such as requesting for publish_actions" "when the user performs a sharing action."]; } } } - (NSString *)loadExpectedChallenge { return [_keychainStore stringForKey:FBSDKExpectedChallengeKey]; } - (NSDictionary *)logInParametersWithPermissions:(NSSet *)permissions serverConfiguration:(FBSDKServerConfiguration *)serverConfiguration { [FBSDKInternalUtility validateURLSchemes]; NSMutableDictionary *loginParams = [NSMutableDictionary dictionary]; loginParams[@"client_id"] = [FBSDKSettings appID]; loginParams[@"response_type"] = @"token,signed_request"; loginParams[@"redirect_uri"] = @"fbconnect://success"; loginParams[@"display"] = @"touch"; loginParams[@"sdk"] = @"ios"; loginParams[@"return_scopes"] = @"true"; loginParams[@"sdk_version"] = FBSDK_VERSION_STRING; loginParams[@"fbapp_pres"] = @([FBSDKInternalUtility isFacebookAppInstalled]); loginParams[@"auth_type"] = @"rerequest"; loginParams[@"logging_token"] = serverConfiguration.loggingToken; [FBSDKInternalUtility dictionary:loginParams setObject:[FBSDKSettings appURLSchemeSuffix] forKey:@"local_client_id"]; [FBSDKInternalUtility dictionary:loginParams setObject:[FBSDKLoginUtility stringForAudience:self.defaultAudience] forKey:@"default_audience"]; [FBSDKInternalUtility dictionary:loginParams setObject:[[permissions allObjects] componentsJoinedByString:@","] forKey:@"scope"]; NSString *expectedChallenge = [FBSDKLoginManager stringForChallenge]; NSDictionary *state = @{@"challenge": [FBSDKUtility URLEncode:expectedChallenge]}; loginParams[@"state"] = [FBSDKInternalUtility JSONStringForObject:state error:NULL invalidObjectHandler:nil]; [self storeExpectedChallenge:expectedChallenge]; return loginParams; } - (void)logInWithPermissions:(NSSet *)permissions handler:(FBSDKLoginManagerRequestTokenHandler)handler { _logger = [[FBSDKLoginManagerLogger alloc] init]; _handler = [handler copy]; _requestedPermissions = permissions; [_logger startSessionForLoginManager:self]; [self logInWithBehavior:self.loginBehavior]; } - (void)logInWithBehavior:(FBSDKLoginBehavior)loginBehavior { __weak __typeof__(self) weakSelf = self; [FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:^(FBSDKServerConfiguration *serverConfiguration, NSError *loadError) { [weakSelf logInWithBehavior:loginBehavior serverConfiguration:serverConfiguration serverConfigurationLoadError:loadError]; }]; } - (void)logInWithBehavior:(FBSDKLoginBehavior)loginBehavior serverConfiguration:(FBSDKServerConfiguration *)serverConfiguration serverConfigurationLoadError:(NSError *)loadError { NSDictionary *loginParams = [self logInParametersWithPermissions:_requestedPermissions serverConfiguration:serverConfiguration]; void(^completion)(BOOL, NSString *, NSError *) = ^void(BOOL didPerformLogIn, NSString *authMethod, NSError *error) { if (didPerformLogIn) { [_logger startAuthMethod:authMethod]; _performingLogIn = YES; } else { if (!error) { error = [NSError errorWithDomain:FBSDKLoginErrorDomain code:FBSDKLoginUnknownErrorCode userInfo:nil]; } [self invokeHandler:nil error:error]; } }; switch (loginBehavior) { case FBSDKLoginBehaviorNative: { if ([FBSDKInternalUtility isFacebookAppInstalled]) { BOOL useNativeDialog = [serverConfiguration useNativeDialogForDialogName:FBSDKDialogConfigurationNameLogin]; if (useNativeDialog && loadError == nil) { [self performNativeLogInWithParameters:loginParams handler:^(BOOL openedURL, NSError *openedURLError) { if (openedURLError) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors formatString:@"FBSDKLoginBehaviorNative failed : %@\nTrying FBSDKLoginBehaviorBrowser", openedURLError]; } if (openedURL) { completion(YES, FBSDKLoginManagerLoggerAuthMethod_Native, openedURLError); } else { [self logInWithBehavior:FBSDKLoginBehaviorBrowser]; } }]; } else { [self logInWithBehavior:FBSDKLoginBehaviorBrowser]; } break; } // intentional fall through. } case FBSDKLoginBehaviorBrowser: { [self performBrowserLogInWithParameters:loginParams handler:^(BOOL openedURL, NSString *authMethod, NSError *openedURLError) { completion(openedURL, authMethod, openedURLError); }]; break; } case FBSDKLoginBehaviorSystemAccount: { if (serverConfiguration.isSystemAuthenticationEnabled && loadError == nil) { [self beginSystemLogIn]; } else { [self logInWithBehavior:FBSDKLoginBehaviorNative]; } completion(YES, FBSDKLoginManagerLoggerAuthMethod_System, nil); break; } case FBSDKLoginBehaviorWeb: [self performWebLogInWithParameters:loginParams handler:^(BOOL openedURL, NSError *openedURLError) { completion(openedURL, FBSDKLoginManagerLoggerAuthMethod_Webview, openedURLError); }]; break; } } - (void)storeExpectedChallenge:(NSString *)challengeExpected { [_keychainStore setString:challengeExpected forKey:FBSDKExpectedChallengeKey accessibility:[FBSDKDynamicFrameworkLoader loadkSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]]; } + (NSString *)stringForChallenge { return [FBSDKCrypto randomString:FBClientStateChallengeLength]; } - (void)validateReauthentication:(FBSDKAccessToken *)currentToken withResult:(FBSDKLoginManagerLoginResult *)loginResult { FBSDKGraphRequest *requestMe = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields":@""} tokenString:loginResult.token.tokenString HTTPMethod:nil flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; [requestMe startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { NSString *actualID = result[@"id"]; if ([currentToken.userID isEqualToString:actualID]) { [FBSDKAccessToken setCurrentAccessToken:loginResult.token]; [self invokeHandler:loginResult error:nil]; } else { NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; [FBSDKInternalUtility dictionary:userInfo setObject:error forKey:NSUnderlyingErrorKey]; NSError *resultError = [NSError errorWithDomain:FBSDKLoginErrorDomain code:FBSDKLoginUserMismatchErrorCode userInfo:userInfo]; [self invokeHandler:nil error:resultError]; } }]; } #pragma mark - Test Methods - (void)setHandler:(FBSDKLoginManagerRequestTokenHandler)handler { _handler = [handler copy]; } - (void)setRequestedPermissions:(NSSet *)requestedPermissions { _requestedPermissions = [requestedPermissions copy]; } @end #pragma mark - @implementation FBSDKLoginManager (Native) - (void)performNativeLogInWithParameters:(NSDictionary *)loginParams handler:(void(^)(BOOL, NSError*))handler { [_logger willAttemptAppSwitchingBehavior]; loginParams = [_logger parametersWithTimeStampAndClientState:loginParams forAuthMethod:FBSDKLoginManagerLoggerAuthMethod_Native]; NSString *scheme = ([FBSDKSettings appURLSchemeSuffix] ? @"fbauth2" : @"fbauth"); NSMutableDictionary *mutableParams = [NSMutableDictionary dictionaryWithDictionary:loginParams]; mutableParams[@"legacy_override"] = FBSDK_TARGET_PLATFORM_VERSION; NSError *error; NSURL *authURL = [FBSDKInternalUtility URLWithScheme:scheme host:@"authorize" path:@"" queryParameters:mutableParams error:&error]; [[FBSDKApplicationDelegate sharedInstance] openURL:authURL sender:self handler:^(BOOL openedURL) { if (handler) { handler(openedURL, error); } }]; } // change bool to auth method string. - (void)performBrowserLogInWithParameters:(NSDictionary *)loginParams handler:(void(^)(BOOL didOpen, NSString *authMethod, NSError *error))handler { [_logger willAttemptAppSwitchingBehavior]; FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration]; BOOL useSafariViewController = [configuration useSafariViewControllerForDialogName:FBSDKDialogConfigurationNameLogin]; NSString *authMethod = (useSafariViewController ? FBSDKLoginManagerLoggerAuthMethod_SFVC : FBSDKLoginManagerLoggerAuthMethod_Browser); loginParams = [_logger parametersWithTimeStampAndClientState:loginParams forAuthMethod:authMethod]; NSURL *authURL = nil; NSError *error; NSURL *redirectURL = [FBSDKInternalUtility appURLWithHost:@"authorize" path:nil queryParameters:nil error:&error]; if (!error) { NSMutableDictionary *browserParams = [loginParams mutableCopy]; [FBSDKInternalUtility dictionary:browserParams setObject:redirectURL forKey:@"redirect_uri"]; authURL = [FBSDKInternalUtility facebookURLWithHostPrefix:@"m." path:@"/dialog/oauth" queryParameters:browserParams error:&error]; } if (authURL) { void(^handlerWrapper)(BOOL) = ^(BOOL didOpen) { if (handler) { handler(didOpen, authMethod, nil); } }; if (useSafariViewController) { // Note based on above, authURL must be a http scheme. If that changes, add a guard, otherwise SFVC can throw [[FBSDKApplicationDelegate sharedInstance] openURLWithSafariViewController:authURL sender:self fromViewController:self.fromViewController handler:handlerWrapper]; } else { [[FBSDKApplicationDelegate sharedInstance] openURL:authURL sender:self handler:handlerWrapper]; } } else { error = error ?: [FBSDKError errorWithCode:FBSDKLoginUnknownErrorCode message:@"Failed to construct oauth browser url"]; if (handler) { handler(NO, nil, error); } } } - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { // verify the URL is intended as a callback for the SDK's log in BOOL isFacebookURL = [[url scheme] hasPrefix:[NSString stringWithFormat:@"fb%@", [FBSDKSettings appID]]] && [[url host] isEqualToString:@"authorize"]; BOOL isExpectedSourceApplication = [sourceApplication hasPrefix:@"com.facebook"] || [sourceApplication hasPrefix:@"com.apple"]; if (!isFacebookURL && _performingLogIn) { [self handleImplicitCancelOfLogIn]; } _performingLogIn = NO; if (isFacebookURL && isExpectedSourceApplication) { NSDictionary *urlParameters = [FBSDKLoginUtility queryParamsFromLoginURL:url]; id completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:urlParameters appID:[FBSDKSettings appID]]; if (_logger == nil) { _logger = [FBSDKLoginManagerLogger loggerFromParameters:urlParameters]; } // any necessary strong reference is maintained by the FBSDKLoginURLCompleter handler [completer completeLogIn:self withHandler:^(FBSDKLoginCompletionParameters *parameters) { [self completeAuthentication:parameters expectChallenge:YES]; }]; } return isFacebookURL; } - (void)applicationDidBecomeActive:(UIApplication *)application { if (_performingLogIn) { _performingLogIn = NO; [self handleImplicitCancelOfLogIn]; } } - (void)handleImplicitCancelOfLogIn { FBSDKLoginManagerLoginResult *result = [[FBSDKLoginManagerLoginResult alloc] initWithToken:nil isCancelled:YES grantedPermissions:nil declinedPermissions:nil]; [result addLoggingExtra:@(YES) forKey:@"implicit_cancel"]; [self invokeHandler:result error:nil]; } @end @implementation FBSDKLoginManager (Accounts) - (void)beginSystemLogIn { // First, we need to validate the current access token. The user may have uninstalled the // app, changed their password, etc., or the access token may have expired, which // requires us to renew the account before asking for additional permissions. NSString *accessTokenString = [FBSDKSystemAccountStoreAdapter sharedInstance].accessTokenString; if (accessTokenString.length > 0) { FBSDKGraphRequest *meRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{ @"fields" : @"id" } tokenString:accessTokenString HTTPMethod:nil flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; [meRequest startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (!error) { // If there was no error, make an explicit renewal call anyway to cover cases where user has revoked some read permission like email. // Otherwise, iOS system account may continue to think email was granted and never prompt UI again. [[FBSDKSystemAccountStoreAdapter sharedInstance] renewSystemAuthorization:^(ACAccountCredentialRenewResult renewResult, NSError *renewError) { dispatch_async(dispatch_get_main_queue(), ^{ [self performSystemLogIn]; }); }]; } else { // If there was an error, FBSDKGraphRequestConnection would have already done work already (like renewal calls) [self performSystemLogIn]; } }]; } else { [self performSystemLogIn]; } } - (void)performSystemLogIn { if (![FBSDKSystemAccountStoreAdapter sharedInstance].accountType) { // There is no Facebook system account type. Fallback to Native behavior [self fallbackToNativeBehavior]; return; } BOOL isReauthorize = [FBSDKAccessToken currentAccessToken] != nil; // app may be asking for nothing, but we will always have a set here NSMutableSet *permissionsToUse = _requestedPermissions ? [_requestedPermissions mutableCopy] : [NSMutableSet set]; // Only add basic info if this is not reauthorize case, if it is the app should already have basic info ToSed if (!isReauthorize) { // Ensure that basic info is among the permissions requested so that the app will install if necessary. // "email" is used as a proxy for basic_info permission. [permissionsToUse addObject:@"email"]; } [permissionsToUse removeObject:@"public_profile"]; [permissionsToUse removeObject:@"user_friends"]; NSString *audience; switch (self.defaultAudience) { case FBSDKDefaultAudienceOnlyMe: audience = fbsdkdfl_ACFacebookAudienceOnlyMe(); break; case FBSDKDefaultAudienceFriends: audience = fbsdkdfl_ACFacebookAudienceFriends(); break; case FBSDKDefaultAudienceEveryone: audience = fbsdkdfl_ACFacebookAudienceEveryone(); break; default: audience = nil; } unsigned long timePriorToSystemAuthUI = [FBSDKInternalUtility currentTimeInMilliseconds]; // the FBSDKSystemAccountStoreAdapter completion handler maintains the strong reference during the the asynchronous operation [[FBSDKSystemAccountStoreAdapter sharedInstance] requestAccessToFacebookAccountStore:permissionsToUse defaultAudience:audience isReauthorize:isReauthorize appID:[FBSDKSettings appID] handler:^(NSString *oauthToken, NSError *accountStoreError) { // There doesn't appear to be a reliable way to determine whether UI was shown or // whether the cached token was sufficient. So we use a timer heuristic assuming that // human response time couldn't complete a dialog in under the interval given here, but // the process will return here fast enough if the token is cached. The threshold was // chosen empirically, so there may be some edge cases that are false negatives or // false positives. BOOL didShowDialog = [FBSDKInternalUtility currentTimeInMilliseconds] - timePriorToSystemAuthUI > 350; BOOL isUnTOSedDevice = !oauthToken && accountStoreError.code == ACErrorAccountNotFound; [_logger systemAuthDidShowDialog:didShowDialog isUnTOSedDevice:isUnTOSedDevice]; if (accountStoreError && [FBSDKSystemAccountStoreAdapter sharedInstance].forceBlockingRenew) { accountStoreError = [FBSDKLoginError errorForSystemPasswordChange:accountStoreError]; } if (!oauthToken && !accountStoreError) { // This means iOS did not give an error nor granted, even after a renew. In order to // surface this to users, stuff in our own error that can be inspected. accountStoreError = [FBSDKLoginError errorForFailedLoginWithCode:FBSDKLoginSystemAccountAppDisabledErrorCode]; } FBSDKLoginManagerSystemAccountState *state = [[FBSDKLoginManagerSystemAccountState alloc] init]; state.didShowDialog = didShowDialog; state.reauthorize = isReauthorize; state.unTOSedDevice = isUnTOSedDevice; [self continueSystemLogInWithTokenString:oauthToken error:accountStoreError state:state]; }]; } - (void)continueSystemLogInWithTokenString:(NSString *)oauthToken error:(NSError *)accountStoreError state:(FBSDKLoginManagerSystemAccountState *)state { id completer = nil; if (!oauthToken && accountStoreError.code == ACErrorAccountNotFound) { // Even with the Accounts framework we use the Facebook app or Safari to log in if // the user has not signed in. This condition can only be detected by attempting to // log in because the framework does not otherwise indicate whether a Facebook account // exists on the device unless the user has granted the app permissions. // Do this asynchronously so the logger correctly notes the system account was skipped dispatch_async(dispatch_get_main_queue(), ^{ [self fallbackToNativeBehavior]; }); } else if (oauthToken) { completer = [[FBSDKLoginSystemAccountCompleter alloc] initWithTokenString:oauthToken appID:[FBSDKSettings appID]]; } else { completer = [[FBSDKLoginSystemAccountErrorCompleter alloc] initWithError:accountStoreError permissions:_requestedPermissions]; } // any necessary strong reference is maintained by the FBSDKLoginSystemAccount[Error]Completer handler [completer completeLogIn:self withHandler:^(FBSDKLoginCompletionParameters *parameters) { NSString *eventName = [NSString stringWithFormat:@"%@ %@", (state.isReauthorize ? @"Reauthorization" : @"Authorization"), (parameters.error ? @"Error" : (parameters.accessTokenString ? @"succeeded" : @"cancelled")) ]; [self completeAuthentication:parameters expectChallenge:NO]; if (eventName != nil) { NSString *sortedPermissions = (parameters.permissions.count == 0) ? @"" : [[parameters.permissions.allObjects sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)] componentsJoinedByString:@","]; [FBSDKAppEvents logImplicitEvent:FBSDKAppEventNamePermissionsUILaunch valueToSum:nil parameters:@{ @"ui_dialog_type" : @"iOS integrated auth", @"permissions_requested" : sortedPermissions } accessToken:nil]; [FBSDKAppEvents logImplicitEvent:FBSDKAppEventNamePermissionsUIDismiss valueToSum:nil parameters:@{ @"ui_dialog_type" : @"iOS integrated auth", FBSDKAppEventParameterDialogOutcome : eventName, @"permissions_requested" : sortedPermissions } accessToken:nil]; } }]; } - (void)fallbackToNativeBehavior { FBSDKLoginManagerLoginResult *skippedResult = [[FBSDKLoginManagerLoginResult alloc] initWithToken:nil isCancelled:NO grantedPermissions:nil declinedPermissions:nil]; skippedResult.isSkipped = YES; [_logger endLoginWithResult:skippedResult error:nil]; // any necessary strong reference will be maintained by the mechanism that is used [self logInWithBehavior:FBSDKLoginBehaviorNative]; } @end @implementation FBSDKLoginManager (WebDialog) - (void)performWebLogInWithParameters:(NSDictionary *)loginParams handler:(void(^)(BOOL, NSError*))handler { [FBSDKInternalUtility registerTransientObject:self]; [FBSDKInternalUtility deleteFacebookCookies]; NSMutableDictionary *parameters = [[NSMutableDictionary alloc] initWithDictionary:loginParams]; parameters[@"title"] = NSLocalizedStringWithDefaultValue(@"LoginWeb.LogInTitle", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Log In", @"Title of the web dialog that prompts the user to log in to Facebook."); [FBSDKWebDialog showWithName:@"oauth" parameters:parameters delegate:self]; if (handler) { handler(YES, nil); } } - (void)webDialog:(FBSDKWebDialog *)webDialog didCompleteWithResults:(NSDictionary *)results { NSString *token = results[@"access_token"]; if (token.length == 0) { [self webDialogDidCancel:webDialog]; } else { id completer = [[FBSDKLoginURLCompleter alloc] initWithURLParameters:results appID:[FBSDKSettings appID]]; [completer completeLogIn:self withHandler:^(FBSDKLoginCompletionParameters *parameters) { [self completeAuthentication:parameters expectChallenge:YES]; }]; [FBSDKInternalUtility unregisterTransientObject:self]; } } - (void)webDialog:(FBSDKWebDialog *)webDialog didFailWithError:(NSError *)error { FBSDKLoginCompletionParameters *parameters = [[FBSDKLoginCompletionParameters alloc] initWithError:error]; [self completeAuthentication:parameters expectChallenge:YES]; [FBSDKInternalUtility unregisterTransientObject:self]; } - (void)webDialogDidCancel:(FBSDKWebDialog *)webDialog { FBSDKLoginCompletionParameters *parameters = [[FBSDKLoginCompletionParameters alloc] init]; [self completeAuthentication:parameters expectChallenge:YES]; [FBSDKInternalUtility unregisterTransientObject:self]; } @end @implementation FBSDKLoginManagerSystemAccountState @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @class FBSDKAccessToken; /*! @abstract Describes the result of a login attempt. */ @interface FBSDKLoginManagerLoginResult : NSObject /*! @abstract the access token. */ @property (copy, nonatomic) FBSDKAccessToken *token; /*! @abstract whether the login was cancelled by the user. */ @property (readonly, nonatomic) BOOL isCancelled; /*! @abstract the set of permissions granted by the user in the associated request. @discussion inspect the token's permissions set for a complete list. */ @property (copy, nonatomic) NSSet *grantedPermissions; /*! @abstract the set of permissions declined by the user in the associated request. @discussion inspect the token's permissions set for a complete list. */ @property (copy, nonatomic) NSSet *declinedPermissions; /*! @abstract Initializes a new instance. @param token the access token @param isCancelled whether the login was cancelled by the user @param grantedPermissions the set of granted permissions @param declinedPermissions the set of declined permissions */ - (instancetype)initWithToken:(FBSDKAccessToken *)token isCancelled:(BOOL)isCancelled grantedPermissions:(NSSet *)grantedPermissions declinedPermissions:(NSSet *)declinedPermissions NS_DESIGNATED_INITIALIZER; @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLoginManagerLoginResult+Internal.h" #import "FBSDKCoreKit+Internal.h" @implementation FBSDKLoginManagerLoginResult { NSMutableDictionary *_mutableLoggingExtras; } - (instancetype)init NS_UNAVAILABLE { assert(0); } - (instancetype)initWithToken:(FBSDKAccessToken *)token isCancelled:(BOOL)isCancelled grantedPermissions:(NSSet *)grantedPermissions declinedPermissions:(NSSet *)declinedPermissions { if ((self = [super init])) { _mutableLoggingExtras = [NSMutableDictionary dictionary]; _token = [token copy]; _isCancelled = isCancelled; _grantedPermissions = [grantedPermissions copy]; _declinedPermissions = [declinedPermissions copy]; }; return self; } - (void)addLoggingExtra:(id)object forKey:(id)key { [FBSDKInternalUtility dictionary:_mutableLoggingExtras setObject:object forKey:key]; } - (NSDictionary *)loggingExtras { return [_mutableLoggingExtras copy]; } @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginTooltipView.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @protocol FBSDKLoginTooltipViewDelegate; /*! @class FBSDKLoginTooltipView @abstract Represents a tooltip to be displayed next to a Facebook login button to highlight features for new users. @discussion The `FBSDKLoginButton` may display this view automatically. If you do not use the `FBSDKLoginButton`, you can manually call one of the `present*` methods as appropriate and customize behavior via `FBSDKLoginTooltipViewDelegate` delegate. By default, the `FBSDKLoginTooltipView` is not added to the superview until it is determined the app has migrated to the new login experience. You can override this (e.g., to test the UI layout) by implementing the delegate or setting `forceDisplay` to YES. */ @interface FBSDKLoginTooltipView : FBSDKTooltipView /*! @abstract the delegate */ @property (nonatomic, weak) id delegate; /*! @abstract if set to YES, the view will always be displayed and the delegate's `loginTooltipView:shouldAppear:` will NOT be called. */ @property (nonatomic, assign) BOOL forceDisplay; @end /*! @protocol @abstract The `FBSDKLoginTooltipViewDelegate` protocol defines the methods used to receive event notifications from `FBSDKLoginTooltipView` objects. */ @protocol FBSDKLoginTooltipViewDelegate @optional /*! @abstract Asks the delegate if the tooltip view should appear @param view The tooltip view. @param appIsEligible The value fetched from the server identifying if the app is eligible for the new login experience. @discussion Use this method to customize display behavior. */ - (BOOL)loginTooltipView:(FBSDKLoginTooltipView *)view shouldAppear:(BOOL)appIsEligible; /*! @abstract Tells the delegate the tooltip view will appear, specifically after it's been added to the super view but before the fade in animation. @param view The tooltip view. */ - (void)loginTooltipViewWillAppear:(FBSDKLoginTooltipView *)view; /*! @abstract Tells the delegate the tooltip view will not appear (i.e., was not added to the super view). @param view The tooltip view. */ - (void)loginTooltipViewWillNotAppear:(FBSDKLoginTooltipView *)view; @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginTooltipView.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLoginTooltipView.h" #import "FBSDKCoreKit+Internal.h" @interface FBSDKLoginTooltipView () @end @implementation FBSDKLoginTooltipView - (instancetype)init { NSString *tooltipMessage = NSLocalizedStringWithDefaultValue(@"LoginTooltip.Message", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"New! You're in control - choose what info you want to share with apps.", @"The message of the FBSDKLoginTooltipView"); return [super initWithTagline:nil message:tooltipMessage colorStyle:FBSDKTooltipColorStyleFriendlyBlue]; } - (void)presentInView:(UIView *)view withArrowPosition:(CGPoint)arrowPosition direction:(FBSDKTooltipViewArrowDirection)arrowDirection { if (self.forceDisplay) { [super presentInView:view withArrowPosition:arrowPosition direction:arrowDirection]; } else { [FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:^(FBSDKServerConfiguration *serverConfiguration, NSError *error) { self.message = serverConfiguration.loginTooltipText; BOOL shouldDisplay = serverConfiguration.loginTooltipEnabled; if ([self.delegate respondsToSelector:@selector(loginTooltipView:shouldAppear:)]) { shouldDisplay = [self.delegate loginTooltipView:self shouldAppear:shouldDisplay]; } if (shouldDisplay) { [super presentInView:view withArrowPosition:arrowPosition direction:arrowDirection]; if ([self.delegate respondsToSelector:@selector(loginTooltipViewWillAppear:)]) { [self.delegate loginTooltipViewWillAppear:self]; } } else { if ([self.delegate respondsToSelector:@selector(loginTooltipViewWillNotAppear:)]) { [self.delegate loginTooltipViewWillNotAppear:self]; } } }]; } } @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/FBSDKTooltipView.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import /*! @typedef FBSDKTooltipViewArrowDirection enum @abstract Passed on construction to determine arrow orientation. */ typedef NS_ENUM(NSUInteger, FBSDKTooltipViewArrowDirection) { /*! View is located above given point, arrow is pointing down. */ FBSDKTooltipViewArrowDirectionDown = 0, /*! View is located below given point, arrow is pointing up. */ FBSDKTooltipViewArrowDirectionUp = 1, }; /*! @typedef FBSDKTooltipColorStyle enum @abstract Passed on construction to determine color styling. */ typedef NS_ENUM(NSUInteger, FBSDKTooltipColorStyle) { /*! Light blue background, white text, faded blue close button. */ FBSDKTooltipColorStyleFriendlyBlue = 0, /*! Dark gray background, white text, light gray close button. */ FBSDKTooltipColorStyleNeutralGray = 1, }; /*! @class FBSDKTooltipView @abstract Tooltip bubble with text in it used to display tips for UI elements, with a pointed arrow (to refer to the UI element). @discussion The tooltip fades in and will automatically fade out. See `displayDuration`. */ @interface FBSDKTooltipView : UIView /*! @abstract Gets or sets the amount of time in seconds the tooltip should be displayed. @discussion Set this to zero to make the display permanent until explicitly dismissed. Defaults to six seconds. */ @property (nonatomic, assign) CFTimeInterval displayDuration; /*! @abstract Gets or sets the color style after initialization. @discussion Defaults to value passed to -initWithTagline:message:colorStyle:. */ @property (nonatomic, assign) FBSDKTooltipColorStyle colorStyle; /*! @abstract Gets or sets the message. */ @property (nonatomic, copy) NSString *message; /*! @abstract Gets or sets the optional phrase that comprises the first part of the label (and is highlighted differently). */ @property (nonatomic, copy) NSString *tagline; /*! @abstract Designated initializer. @param tagline First part of the label, that will be highlighted with different color. Can be nil. @param message Main message to display. @param colorStyle Color style to use for tooltip. @discussion If you need to show a tooltip for login, consider using the `FBSDKLoginTooltipView` view. @see FBSDKLoginTooltipView */ - (instancetype)initWithTagline:(NSString *)tagline message:(NSString *)message colorStyle:(FBSDKTooltipColorStyle)colorStyle; /*! @abstract Show tooltip at the top or at the bottom of given view. Tooltip will be added to anchorView.window.rootViewController.view @param anchorView view to show at, must be already added to window view hierarchy, in order to decide where tooltip will be shown. (If there's not enough space at the top of the anchorView in window bounds - tooltip will be shown at the bottom of it) @discussion Use this method to present the tooltip with automatic positioning or use -presentInView:withArrowPosition:direction: for manual positioning If anchorView is nil or has no window - this method does nothing. */ - (void)presentFromView:(UIView *)anchorView; /*! @abstract Adds tooltip to given view, with given position and arrow direction. @param view View to be used as superview. @param arrowPosition Point in view's cordinates, where arrow will be pointing @param arrowDirection whenever arrow should be pointing up (message bubble is below the arrow) or down (message bubble is above the arrow). */ - (void)presentInView:(UIView *)view withArrowPosition:(CGPoint)arrowPosition direction:(FBSDKTooltipViewArrowDirection)arrowDirection; /*! @abstract Remove tooltip manually. @discussion Calling this method isn't necessary - tooltip will dismiss itself automatically after the `displayDuration`. */ - (void)dismiss; @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/FBSDKTooltipView.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKTooltipView.h" #import #import "FBSDKCoreKit+Internal.h" static const CGFloat kTransitionDuration = 0.3; static const CGFloat kZoomOutScale = 0.001f; static const CGFloat kZoomInScale = 1.1f; static const CGFloat kZoomBounceScale = 0.98f; static const CGFloat kNUXRectInset = 6; static const CGFloat kNUXBubbleMargin = 17 - kNUXRectInset; static const CGFloat kNUXPointMargin = -3; static const CGFloat kNUXCornerRadius = 4; static const CGFloat kNUXStrokeLineWidth = 0.5f; static const CGFloat kNUXSideCap = 6; static const CGFloat kNUXFontSize = 10; static const CGFloat kNUXCrossGlyphSize = 11; static CGMutablePathRef _fbsdkCreateUpPointingBubbleWithRect(CGRect rect, CGFloat arrowMidpoint, CGFloat arrowHeight, CGFloat radius); static CGMutablePathRef _fbsdkCreateDownPointingBubbleWithRect(CGRect rect, CGFloat arrowMidpoint, CGFloat arrowHeight, CGFloat radius); #pragma mark - @implementation FBSDKTooltipView { CGPoint _positionInView; CFAbsoluteTime _displayTime; CFTimeInterval _minimumDisplayDuration; UILabel *_textLabel; UITapGestureRecognizer *_insideTapGestureRecognizer; CGFloat _leftWidth; CGFloat _rightWidth; CGFloat _arrowMidpoint; BOOL _pointingUp; BOOL _isFadingOut; // style UIColor *_innerStrokeColor; CGFloat _arrowHeight; CGFloat _textPadding; CGFloat _maximumTextWidth; CGFloat _verticalTextOffset; CGFloat _verticalCrossOffset; FBSDKTooltipColorStyle _colorStyle; NSArray *_gradientColors; UIColor *_crossCloseGlyphColor; } - (instancetype)initWithTagline:(NSString *)tagline message:(NSString *)message colorStyle:(FBSDKTooltipColorStyle)colorStyle { self = [super initWithFrame:CGRectZero]; if (self) { // Define style _textLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _textLabel.backgroundColor = [UIColor clearColor]; _textLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin; _textLabel.numberOfLines = 0; _textLabel.font = [UIFont boldSystemFontOfSize: kNUXFontSize]; _textLabel.textAlignment = NSTextAlignmentLeft; _arrowHeight = 7; _textPadding = 10; _maximumTextWidth = 185; _verticalCrossOffset = - 2.5f; _verticalTextOffset = 0; _displayDuration = 6.0; [self setColorStyle:colorStyle]; _message = [message copy]; _tagline = [tagline copy]; [self setMessage:message tagline:tagline]; [self addSubview:_textLabel]; _insideTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapInTooltip:)]; [self addGestureRecognizer:_insideTapGestureRecognizer]; self.opaque = NO; self.backgroundColor = [UIColor clearColor]; self.layer.needsDisplayOnBoundsChange = YES; self.layer.shadowColor = [UIColor blackColor].CGColor; self.layer.shadowOpacity = 0.5f; self.layer.shadowOffset = CGSizeMake(0.0f, 2.0f); self.layer.shadowRadius = 5.0f; self.layer.masksToBounds = NO; } return self; } - (void)dealloc { [_insideTapGestureRecognizer removeTarget:self action:NULL]; } #pragma mark - Public Methods - (void)setMessage:(NSString *)message { if (![message isEqualToString:_message]) { _message = [message copy]; [self setMessage:_message tagline:self.tagline]; } } - (void)setTagline:(NSString *)tagline { if (![tagline isEqualToString:_tagline]) { _tagline = [tagline copy]; [self setMessage:self.message tagline:_tagline]; } } #pragma mark Presentation - (void)presentFromView:(UIView *)anchorView { UIView *superview = anchorView.window.rootViewController.view; if (!superview) { return; } // By default - attach to the top, pointing down CGPoint position = CGPointMake(CGRectGetMidX(anchorView.bounds), CGRectGetMinY(anchorView.bounds)); CGPoint positionInSuperview = [superview convertPoint:position fromView:anchorView]; FBSDKTooltipViewArrowDirection direction = FBSDKTooltipViewArrowDirectionDown; // If not enough space to point up from top of anchor view - point up to it's bottom CGFloat bubbleHeight = CGRectGetHeight(_textLabel.bounds) + _verticalTextOffset + _textPadding * 2; if (positionInSuperview.y - bubbleHeight - kNUXBubbleMargin < CGRectGetMinY(superview.bounds)) { direction = FBSDKTooltipViewArrowDirectionUp; position = CGPointMake(CGRectGetMidX(anchorView.bounds), CGRectGetMaxY(anchorView.bounds)); positionInSuperview = [superview convertPoint:position fromView:anchorView]; } [self presentInView:superview withArrowPosition:positionInSuperview direction:direction]; } - (void)presentInView:(UIView *)view withArrowPosition:(CGPoint)arrowPosition direction:(FBSDKTooltipViewArrowDirection)arrowDirection { _pointingUp = arrowDirection == FBSDKTooltipViewArrowDirectionUp; _positionInView = arrowPosition; self.frame = [self layoutSubviewsAndDetermineFrame]; // Add to view, while invisible. self.hidden = YES; if ([self superview]) { [self removeFromSuperview]; } [view addSubview:self]; // Layout & schedule dismissal. _displayTime = CFAbsoluteTimeGetCurrent(); _isFadingOut = NO; [self scheduleAutomaticFadeout]; [self layoutSubviews]; [self animateFadeIn]; } - (void)dismiss { if (_isFadingOut) { return; } _isFadingOut = YES; [self animateFadeOutWithCompletion:^{ [self removeFromSuperview]; [self cancelAllScheduledFadeOutMethods]; _isFadingOut = NO; }]; } #pragma mark Style - (FBSDKTooltipColorStyle)colorStyle { return _colorStyle; } - (void)setColorStyle:(FBSDKTooltipColorStyle)colorStyle { _colorStyle = colorStyle; switch (colorStyle) { case FBSDKTooltipColorStyleNeutralGray: _gradientColors = @[ (id)(FBSDKUIColorWithRGB(0x51, 0x50, 0x4f).CGColor), (id)(FBSDKUIColorWithRGB(0x2d, 0x2c, 0x2c).CGColor) ]; _innerStrokeColor = [UIColor colorWithWhite:0.13f alpha:1.0f]; _crossCloseGlyphColor = [UIColor colorWithWhite:0.69f alpha:1.0f]; break; case FBSDKTooltipColorStyleFriendlyBlue: default: _gradientColors = @[ (id)(FBSDKUIColorWithRGB(0x6e, 0x9c, 0xf5).CGColor), (id)(FBSDKUIColorWithRGB(0x49, 0x74, 0xc6).CGColor) ]; _innerStrokeColor = [UIColor colorWithRed:0.12f green:0.26f blue:0.55f alpha:1.0f]; _crossCloseGlyphColor = [UIColor colorWithRed:0.60f green:0.73f blue:1.0f alpha:1.0f]; break; } _textLabel.textColor = [UIColor whiteColor]; } #pragma mark - Private Methods #pragma mark Animation - (void)animateFadeIn { // Prepare Animation: Zoom in with bounce. Keep the arrow point in place. // Set initial transform (zoomed out) & become visible. CGFloat centerPos = self.bounds.size.width / 2.0; CGFloat zoomOffsetX = (centerPos - _arrowMidpoint) * (kZoomOutScale - 1.0f); CGFloat zoomOffsetY = -0.5f * self.bounds.size.height * (kZoomOutScale - 1.0f); if (_pointingUp) { zoomOffsetY = -zoomOffsetY; } self.layer.transform = fbsdkdfl_CATransform3DConcat(fbsdkdfl_CATransform3DMakeScale(kZoomOutScale, kZoomOutScale, kZoomOutScale), fbsdkdfl_CATransform3DMakeTranslation(zoomOffsetX, zoomOffsetY, 0)); self.hidden = NO; // Prepare animation steps // 1st Step. void (^zoomIn)(void) = ^{ self.alpha = 1.0; CGFloat newZoomOffsetX = (centerPos - _arrowMidpoint) * (kZoomInScale - 1.0f); CGFloat newZoomOffsetY = -0.5f * self.bounds.size.height * (kZoomInScale - 1.0f); if (_pointingUp) { newZoomOffsetY = -newZoomOffsetY; } CATransform3D scale = fbsdkdfl_CATransform3DMakeScale(kZoomInScale, kZoomInScale, kZoomInScale); CATransform3D translate =fbsdkdfl_CATransform3DMakeTranslation(newZoomOffsetX, newZoomOffsetY, 0); self.layer.transform = fbsdkdfl_CATransform3DConcat(scale, translate); }; // 2nd Step. void (^bounceZoom)(void) = ^{ CGFloat centerPos2 = self.bounds.size.width / 2.0; CGFloat zoomOffsetX2 = (centerPos2 - _arrowMidpoint) * (kZoomBounceScale - 1.0f); CGFloat zoomOffsetY2 = -0.5f * self.bounds.size.height * (kZoomBounceScale - 1.0f); if (_pointingUp) { zoomOffsetY2 = -zoomOffsetY2; } self.layer.transform = fbsdkdfl_CATransform3DConcat(fbsdkdfl_CATransform3DMakeScale(kZoomBounceScale, kZoomBounceScale, kZoomBounceScale), fbsdkdfl_CATransform3DMakeTranslation(zoomOffsetX2, zoomOffsetY2, 0)); }; // 3rd Step. void (^normalizeZoom)(void) = ^{ self.layer.transform = fbsdkdfl_CATransform3DIdentity; }; // Animate 3 steps sequentially [UIView animateWithDuration:kTransitionDuration/1.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:zoomIn completion:^(BOOL finished) { [UIView animateWithDuration:kTransitionDuration/2.2 animations:bounceZoom completion:^(BOOL innerFinished) { [UIView animateWithDuration:kTransitionDuration/5 animations:normalizeZoom]; }]; }]; } - (void) animateFadeOutWithCompletion: (void(^)(void)) completionHandler { [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ self.alpha = 0.0; } completion:^(BOOL complete) { if(completionHandler) completionHandler(); }]; } #pragma mark Gestures - (void)onTapInTooltip:(UIGestureRecognizer*)sender { // ignore incomplete tap gestures if (sender.state != UIGestureRecognizerStateEnded) { return; } // fade out the tooltip view right away [self dismiss]; } #pragma mark Drawing CGMutablePathRef _fbsdkCreateUpPointingBubbleWithRect(CGRect rect, CGFloat arrowMidpoint, CGFloat arrowHeight, CGFloat radius) { CGMutablePathRef path = CGPathCreateMutable(); CGFloat arrowHalfWidth = arrowHeight; // start with arrow CGPathMoveToPoint(path, NULL, arrowMidpoint - arrowHalfWidth, CGRectGetMinY(rect)); CGPathAddLineToPoint(path, NULL, arrowMidpoint, CGRectGetMinY(rect) - arrowHeight); CGPathAddLineToPoint(path, NULL, arrowMidpoint + arrowHalfWidth, CGRectGetMinY(rect)); // rest of curved rectangle CGPathAddArcToPoint(path, NULL, CGRectGetMaxX(rect), CGRectGetMinY(rect), CGRectGetMaxX(rect), CGRectGetMaxY(rect), radius); CGPathAddArcToPoint(path, NULL, CGRectGetMaxX(rect), CGRectGetMaxY(rect), CGRectGetMinX(rect), CGRectGetMaxY(rect), radius); CGPathAddArcToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMaxY(rect), CGRectGetMinX(rect), CGRectGetMinY(rect), radius); CGPathAddArcToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetMaxX(rect), CGRectGetMinY(rect), radius); CGPathCloseSubpath(path); return path; } CGMutablePathRef _fbsdkCreateDownPointingBubbleWithRect(CGRect rect, CGFloat arrowMidpoint, CGFloat arrowHeight, CGFloat radius) { CGMutablePathRef path = CGPathCreateMutable(); CGFloat arrowHalfWidth = arrowHeight; // start with arrow CGPathMoveToPoint(path, NULL, arrowMidpoint + arrowHalfWidth, CGRectGetMaxY(rect)); CGPathAddLineToPoint(path, NULL, arrowMidpoint, CGRectGetMaxY(rect) + arrowHeight); CGPathAddLineToPoint(path, NULL, arrowMidpoint - arrowHalfWidth, CGRectGetMaxY(rect)); // rest of curved rectangle CGPathAddArcToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMaxY(rect), CGRectGetMinX(rect), CGRectGetMinY(rect), radius); CGPathAddArcToPoint(path, NULL, CGRectGetMinX(rect), CGRectGetMinY(rect), CGRectGetMaxX(rect), CGRectGetMinY(rect), radius); CGPathAddArcToPoint(path, NULL, CGRectGetMaxX(rect), CGRectGetMinY(rect), CGRectGetMaxX(rect), CGRectGetMaxY(rect), radius); CGPathAddArcToPoint(path, NULL, CGRectGetMaxX(rect), CGRectGetMaxY(rect), CGRectGetMinX(rect), CGRectGetMaxY(rect), radius); CGPathCloseSubpath(path); return path; } static CGMutablePathRef _createCloseCrossGlyphWithRect(CGRect rect) { CGFloat lineThickness = 0.20f * CGRectGetHeight(rect); // One rectangle CGMutablePathRef path1 = CGPathCreateMutable(); CGPathMoveToPoint(path1, NULL, CGRectGetMinX(rect), CGRectGetMinY(rect) + lineThickness); CGPathAddLineToPoint(path1, NULL, CGRectGetMinX(rect) + lineThickness, CGRectGetMinY(rect)); CGPathAddLineToPoint(path1, NULL, CGRectGetMaxX(rect), CGRectGetMaxY(rect) - lineThickness); CGPathAddLineToPoint(path1, NULL, CGRectGetMaxX(rect) - lineThickness, CGRectGetMaxY(rect)); CGPathCloseSubpath(path1); // 2nd rectangle - mirrored horizontally CGMutablePathRef path2 = CGPathCreateMutable(); CGPathMoveToPoint(path2, NULL, CGRectGetMinX(rect), CGRectGetMaxY(rect) - lineThickness); CGPathAddLineToPoint(path2, NULL, CGRectGetMaxX(rect) - lineThickness, CGRectGetMinY(rect)); CGPathAddLineToPoint(path2, NULL, CGRectGetMaxX(rect), CGRectGetMinY(rect) + lineThickness); CGPathAddLineToPoint(path2, NULL, CGRectGetMinX(rect) + lineThickness, CGRectGetMaxY(rect)); CGPathCloseSubpath(path2); CGMutablePathRef groupedPath = CGPathCreateMutable(); CGPathAddPath(groupedPath, NULL, path1); CGPathAddPath(groupedPath, NULL, path2); CFRelease(path1); CFRelease(path2); return groupedPath; } - (void)drawRect:(CGRect)rect { // Ignore dirty rect and just redraw the entire nux bubble CGFloat arrowSideMargin = 1 + 0.5f * MAX(kNUXRectInset, _arrowHeight); CGFloat arrowYMarginOffset = _pointingUp ? arrowSideMargin : kNUXRectInset; CGFloat halfStroke = kNUXStrokeLineWidth / 2.0; CGRect outerRect = CGRectMake(kNUXRectInset + halfStroke, arrowYMarginOffset + halfStroke, self.bounds.size.width - 2 * kNUXRectInset - kNUXStrokeLineWidth, self.bounds.size.height - kNUXRectInset - arrowSideMargin - kNUXStrokeLineWidth); outerRect = CGRectInset(outerRect, 5, 5); CGRect innerRect = CGRectInset(outerRect, kNUXStrokeLineWidth, kNUXStrokeLineWidth); CGRect fillRect = CGRectInset(innerRect, kNUXStrokeLineWidth/2.0, kNUXStrokeLineWidth/2.0); CGFloat closeCrossGlyphPositionY = MIN(CGRectGetMinY(fillRect) + _textPadding + _verticalCrossOffset, CGRectGetMidY(fillRect) - 0.5f * kNUXCrossGlyphSize); CGRect closeCrossGlyphRect = CGRectMake(CGRectGetMaxX(fillRect) - 2 * kNUXFontSize, closeCrossGlyphPositionY, kNUXCrossGlyphSize, kNUXCrossGlyphSize); // setup and get paths CGContextRef context = UIGraphicsGetCurrentContext(); CGMutablePathRef outerPath; CGMutablePathRef innerPath; CGMutablePathRef fillPath; CGMutablePathRef crossCloseGlyphPath = _createCloseCrossGlyphWithRect(closeCrossGlyphRect); CGRect gradientRect = fillRect; if (_pointingUp) { outerPath = _fbsdkCreateUpPointingBubbleWithRect(outerRect, _arrowMidpoint, _arrowHeight, kNUXCornerRadius + kNUXStrokeLineWidth); innerPath = _fbsdkCreateUpPointingBubbleWithRect(innerRect, _arrowMidpoint, _arrowHeight, kNUXCornerRadius); fillPath = _fbsdkCreateUpPointingBubbleWithRect(fillRect, _arrowMidpoint, _arrowHeight, kNUXCornerRadius - kNUXStrokeLineWidth); gradientRect.origin.y -= _arrowHeight; gradientRect.size.height += _arrowHeight; } else { outerPath = _fbsdkCreateDownPointingBubbleWithRect(outerRect, _arrowMidpoint, _arrowHeight, kNUXCornerRadius + kNUXStrokeLineWidth); innerPath = _fbsdkCreateDownPointingBubbleWithRect(innerRect, _arrowMidpoint, _arrowHeight, kNUXCornerRadius); fillPath = _fbsdkCreateDownPointingBubbleWithRect(fillRect, _arrowMidpoint, _arrowHeight, kNUXCornerRadius - kNUXStrokeLineWidth); gradientRect.size.height += _arrowHeight; } self.layer.shadowPath = outerPath; // This tooltip has two borders, so draw two strokes and a fill. CGColorRef strokeColor = _innerStrokeColor.CGColor; CGContextSaveGState(context); CGContextSetStrokeColorWithColor(context, strokeColor); CGContextSetLineWidth(context, kNUXStrokeLineWidth); CGContextAddPath(context, innerPath); CGContextStrokePath(context); CGContextAddPath(context, fillPath); CGContextClip(context); CGColorSpaceRef rgbColorspace = CGColorSpaceCreateDeviceRGB(); CGGradientRef gradient = CGGradientCreateWithColors(rgbColorspace, (CFArrayRef)_gradientColors, nil); CGColorSpaceRelease(rgbColorspace); CGPoint start = CGPointMake(gradientRect.origin.x, gradientRect.origin.y); CGPoint end = CGPointMake(gradientRect.origin.x, CGRectGetMaxY(gradientRect)); CGContextDrawLinearGradient(context, gradient, start, end, 0); CGContextAddPath(context, crossCloseGlyphPath); CGContextSetFillColorWithColor(context, _crossCloseGlyphColor.CGColor); CGContextFillPath(context); CGGradientRelease(gradient); CGContextRestoreGState(context); CFRelease(outerPath); CFRelease(innerPath); CFRelease(fillPath); CFRelease(crossCloseGlyphPath); } #pragma mark Layout - (void)layoutSubviews { [super layoutSubviews]; // We won't set the frame in layoutSubviews to avoid potential infinite loops. // Frame is set in -presentInView:withArrowPosition:direction: method. [self layoutSubviewsAndDetermineFrame]; } - (CGRect)layoutSubviewsAndDetermineFrame { // Compute the positioning of the arrow. CGRect screenBounds = [[UIScreen mainScreen] bounds]; UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; if (!UIInterfaceOrientationIsPortrait(orientation)) { screenBounds = CGRectMake(0, 0, screenBounds.size.height, screenBounds.size.width); } CGFloat arrowHalfWidth = _arrowHeight; CGFloat arrowXPos = _positionInView.x - arrowHalfWidth; arrowXPos = MAX(arrowXPos, kNUXSideCap + kNUXBubbleMargin); arrowXPos = MIN(arrowXPos, screenBounds.size.width - kNUXBubbleMargin - kNUXSideCap - 2 * arrowHalfWidth); _positionInView = CGPointMake(arrowXPos + arrowHalfWidth, _positionInView.y); CGFloat arrowYMarginOffset = _pointingUp ? MAX(kNUXRectInset, _arrowHeight) : kNUXRectInset; // Set the lock image frame. CGFloat xPos = kNUXRectInset + _textPadding + kNUXStrokeLineWidth; CGFloat yPos = arrowYMarginOffset + kNUXStrokeLineWidth + _textPadding; // Set the text label frame. _textLabel.frame = CGRectMake(xPos, yPos + _verticalTextOffset, // sizing function may not return desired height exactly CGRectGetWidth(_textLabel.bounds), CGRectGetHeight(_textLabel.bounds)); // Determine the size of the nux bubble. CGFloat bubbleHeight = CGRectGetHeight(_textLabel.bounds) + _verticalTextOffset + _textPadding * 2; CGFloat crossGlyphWidth = 2 * kNUXFontSize; CGFloat bubbleWidth = CGRectGetWidth(_textLabel.bounds) + _textPadding * 2 + kNUXStrokeLineWidth * 2 + crossGlyphWidth; // Compute the widths to the left and right of the arrow. _leftWidth = roundf(0.5f * (bubbleWidth - 2 * arrowHalfWidth)); _rightWidth = _leftWidth; CGFloat originX = arrowXPos - _leftWidth; if (originX < kNUXBubbleMargin) { CGFloat xShift = kNUXBubbleMargin - originX; originX += xShift; _leftWidth -= xShift; _rightWidth += xShift; } else if (originX + bubbleWidth > screenBounds.size.width - kNUXBubbleMargin) { CGFloat xShift = originX + bubbleWidth - (screenBounds.size.width - kNUXBubbleMargin); originX -= xShift; _leftWidth += xShift; _rightWidth -= xShift; } _arrowMidpoint = _positionInView.x - originX + kNUXRectInset; // Set the frame for the view. CGFloat nuxWidth = bubbleWidth + 2 * kNUXRectInset; CGFloat nuxHeight = bubbleHeight + kNUXRectInset + MAX(kNUXRectInset, _arrowHeight) + 2 * kNUXStrokeLineWidth; CGFloat yOrigin = 0; if (_pointingUp) { yOrigin = _positionInView.y + kNUXPointMargin - MAX(0, kNUXRectInset - _arrowHeight); } else { yOrigin = _positionInView.y - nuxHeight - kNUXPointMargin + MAX(0, kNUXRectInset - _arrowHeight); } return CGRectMake(originX - kNUXRectInset, yOrigin, nuxWidth, nuxHeight); } #pragma mark Message & Tagline - (void)setMessage:(NSString *)message tagline:(NSString *)tagline { message = message ?: @""; // Ensure tagline is empty string or ends with space tagline = tagline ?: @""; if ([tagline length] && ![tagline hasSuffix:@" "]) tagline = [tagline stringByAppendingString:@" "]; // Concatenate tagline & main message message = [tagline stringByAppendingString:message]; NSRange fullRange = NSMakeRange(0, message.length); NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString: message]; UIFont *font=[UIFont boldSystemFontOfSize:kNUXFontSize]; [attrString addAttribute:NSFontAttributeName value:font range:fullRange]; [attrString addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:fullRange]; if ([tagline length]) { [attrString addAttribute:NSForegroundColorAttributeName value: FBSDKUIColorWithRGB(0x6D, 0x87, 0xC7) range:NSMakeRange(0, [tagline length])]; } _textLabel.attributedText = attrString; CGSize textLabelSize = [_textLabel sizeThatFits:CGSizeMake(_maximumTextWidth, MAXFLOAT)]; _textLabel.bounds = CGRectMake(0, 0, textLabelSize.width, textLabelSize.height); self.frame = [self layoutSubviewsAndDetermineFrame]; [self setNeedsDisplay]; } #pragma mark Auto Dismiss Timeout - (void)scheduleAutomaticFadeout { [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(scheduleFadeoutRespectingMinimumDisplayDuration) object:nil]; if (_displayDuration > 0.0 && [self superview]) { CFTimeInterval intervalAlreadyDisplaying = CFAbsoluteTimeGetCurrent() - _displayTime; CFTimeInterval timeRemainingBeforeAutomaticFadeout = _displayDuration - intervalAlreadyDisplaying; if (timeRemainingBeforeAutomaticFadeout > 0.0) { [self performSelector:@selector(scheduleFadeoutRespectingMinimumDisplayDuration) withObject:nil afterDelay:timeRemainingBeforeAutomaticFadeout]; } else { [self scheduleFadeoutRespectingMinimumDisplayDuration]; } } } - (void)scheduleFadeoutRespectingMinimumDisplayDuration { CFTimeInterval intervalAlreadyDisplaying = CFAbsoluteTimeGetCurrent() - _displayTime; CFTimeInterval remainingDisplayTime = _minimumDisplayDuration - intervalAlreadyDisplaying; if (remainingDisplayTime > 0.0) { [self performSelector:@selector(dismiss) withObject:nil afterDelay:remainingDisplayTime]; } else { [self dismiss]; } } - (void)cancelAllScheduledFadeOutMethods { [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(scheduleFadeoutRespectingMinimumDisplayDuration) object:nil]; [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(dismiss) object:nil]; } @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLoginCompletion.h" @interface FBSDKLoginCompletionParameters () @property (nonatomic, copy, readwrite) NSString *accessTokenString; @property (nonatomic, copy, readwrite) NSSet *permissions; @property (nonatomic, copy, readwrite) NSSet *declinedPermissions; @property (nonatomic, copy, readwrite) NSString *appID; @property (nonatomic, copy, readwrite) NSString *userID; @property (nonatomic, copy, readwrite) NSError *error; @property (nonatomic, readwrite, getter=isSystemAccount) BOOL systemAccount; @property (nonatomic, copy, readwrite) NSDate *expirationDate; @property (nonatomic, copy, readwrite) NSString *challenge; @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @class FBSDKLoginManager; /*! @abstract Structured interface for accessing the parameters used to complete a log in request. If \c accessTokenString is non-nil, the authentication succeeded. If \c error is non-nil the request failed. If both are \c nil, the request was cancelled. */ @interface FBSDKLoginCompletionParameters : NSObject - (instancetype)init NS_DESIGNATED_INITIALIZER; - (instancetype)initWithError:(NSError *)error; @property (nonatomic, copy, readonly) NSString *accessTokenString; @property (nonatomic, copy, readonly) NSSet *permissions; @property (nonatomic, copy, readonly) NSSet *declinedPermissions; @property (nonatomic, copy, readonly) NSString *appID; @property (nonatomic, copy, readonly) NSString *userID; @property (nonatomic, copy, readonly) NSError *error; @property (nonatomic, readonly, getter=isSystemAccount) BOOL systemAccount; @property (nonatomic, copy, readonly) NSDate *expirationDate; @property (nonatomic, copy, readonly) NSString *challenge; @end @protocol FBSDKLoginCompleting /*! @abstract Invoke \p handler with the login parameters derived from the authentication result. See the implementing class's documentation for whether it completes synchronously or asynchronously. */ - (void)completeLogIn:(FBSDKLoginManager *)loginManager withHandler:(void(^)(FBSDKLoginCompletionParameters *parameters))handler; @end #pragma mark - Completers /*! @abstract Extracts the log in completion parameters from the \p parameters dictionary, which must contain the parsed result of the return URL query string. The \c user_id key is first used to derive the User ID. If that fails, \c signed_request is used. Completion occurs synchronously. */ @interface FBSDKLoginURLCompleter : NSObject - (instancetype)initWithURLParameters:(NSDictionary *)parameters appID:(NSString *)appID NS_DESIGNATED_INITIALIZER; @end /*! @abstract Requests the User ID, granted permissions and declined permissions from the server using the given access token, which must occur before authentication can be completed. Completion occurs asynchronously. */ @interface FBSDKLoginSystemAccountCompleter : NSObject - (instancetype)initWithTokenString:(NSString *)tokenString appID:(NSString *)appID NS_DESIGNATED_INITIALIZER; @end /*! @abstract Converts an Accounts framework error in to an error or cancellation result Completion occurs synchronously. */ @interface FBSDKLoginSystemAccountErrorCompleter : NSObject - (instancetype)initWithError:(NSError *)accountStoreError permissions:(NSSet *)permissions NS_DESIGNATED_INITIALIZER; @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLoginCompletion+Internal.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKLoginConstants.h" #import "FBSDKLoginError.h" #import "FBSDKLoginManager+Internal.h" #import "FBSDKLoginUtility.h" static void FBSDKLoginRequestMeAndPermissions(FBSDKLoginCompletionParameters *parameters, void(^completionBlock)(void)) { __block NSUInteger pendingCount = 1; void(^didCompleteBlock)(void) = ^{ if (--pendingCount == 0) { completionBlock(); } }; NSString *tokenString = parameters.accessTokenString; FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; pendingCount++; FBSDKGraphRequest *userIDRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{ @"fields" : @"id" } tokenString:tokenString HTTPMethod:nil flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; [connection addRequest:userIDRequest completionHandler:^(FBSDKGraphRequestConnection *requestConnection, id result, NSError *error) { parameters.userID = [result objectForKey:@"id"]; if (error) { parameters.error = error; } didCompleteBlock(); }]; pendingCount++; FBSDKGraphRequest *permissionsRequest = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/permissions" parameters:@{@"fields":@""} tokenString:tokenString HTTPMethod:nil flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; [connection addRequest:permissionsRequest completionHandler:^(FBSDKGraphRequestConnection *requestConnection, id result, NSError *error) { NSMutableSet *grantedPermissions = [NSMutableSet set]; NSMutableSet *declinedPermissions = [NSMutableSet set]; [FBSDKInternalUtility extractPermissionsFromResponse:result grantedPermissions:grantedPermissions declinedPermissions:declinedPermissions]; parameters.permissions = [grantedPermissions copy]; parameters.declinedPermissions = [declinedPermissions copy]; if (error) { parameters.error = error; } didCompleteBlock(); }]; [connection start]; didCompleteBlock(); } @implementation FBSDKLoginCompletionParameters - (instancetype)init { return [super init]; } - (instancetype)initWithError:(NSError *)error { if ((self = [self init]) != nil) { self.error = error; } return self; } @end #pragma mark - Completers @implementation FBSDKLoginURLCompleter { FBSDKLoginCompletionParameters *_parameters; id _observer ; BOOL _performExplicitFallback; } - (instancetype)init NS_UNAVAILABLE { assert(0); } - (instancetype)initWithURLParameters:(NSDictionary *)parameters appID:(NSString *)appID { if ((self = [super init]) != nil) { _parameters = [[FBSDKLoginCompletionParameters alloc] init]; _parameters.accessTokenString = parameters[@"access_token"]; if (_parameters.accessTokenString.length > 0) { [self setParametersWithDictionary:parameters appID:appID]; } else { _parameters.accessTokenString = nil; [self setErrorWithDictionary:parameters]; } } return self; } - (void)completeLogIn:(FBSDKLoginManager *)loginManager withHandler:(void(^)(FBSDKLoginCompletionParameters *parameters))handler { if (_performExplicitFallback && loginManager.loginBehavior == FBSDKLoginBehaviorNative) { // UIKit and iOS don't like an application opening a URL during a URL open callback, so // we need to wait until *at least* the next turn of the run loop to open the URL to // perform the browser log in behavior. However we also need to wait for the application // to become active so FBSDKApplicationDelegate doesn't erroneously call back the URL // opener before the URL has been opened. if ([FBSDKApplicationDelegate sharedInstance].isActive) { // The application is active so there's no need to wait. [loginManager logInWithBehavior:FBSDKLoginBehaviorBrowser]; } else { // use the block version to guarantee there's a strong reference to self _observer = [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^ (NSNotification *notification) { [self attemptBrowserLogIn:loginManager]; }]; } return; } if (_parameters.accessTokenString && !_parameters.userID) { void(^handlerCopy)(FBSDKLoginCompletionParameters *) = [handler copy]; FBSDKLoginRequestMeAndPermissions(_parameters, ^{ handlerCopy(_parameters); }); return; } handler(_parameters); } - (void)setParametersWithDictionary:(NSDictionary *)parameters appID:(NSString *)appID { NSString *grantedPermissionsString = parameters[@"granted_scopes"]; NSString *declinedPermissionsString = parameters[@"denied_scopes"]; NSString *signedRequest = parameters[@"signed_request"]; NSString *userID = parameters[@"user_id"]; // check the string length so that we assign an empty set rather than a set with an empty string _parameters.permissions = (grantedPermissionsString.length > 0) ? [NSSet setWithArray:[grantedPermissionsString componentsSeparatedByString:@","]] : [NSSet set]; _parameters.declinedPermissions = (declinedPermissionsString.length > 0) ? [NSSet setWithArray:[declinedPermissionsString componentsSeparatedByString:@","]] : [NSSet set]; _parameters.appID = appID; if (userID.length == 0 && signedRequest.length > 0) { _parameters.userID = [FBSDKLoginUtility userIDFromSignedRequest:signedRequest]; } else { _parameters.userID = userID; } NSString *expirationDateString = parameters[@"expires"] ?: parameters[@"expires_at"]; NSDate *expirationDate = [NSDate distantFuture]; if (expirationDateString && [expirationDateString doubleValue] > 0) { expirationDate = [NSDate dateWithTimeIntervalSince1970:[expirationDateString doubleValue]]; } else if (parameters[@"expires_in"] && [parameters[@"expires_in"] integerValue] > 0) { expirationDate = [NSDate dateWithTimeIntervalSinceNow:[parameters[@"expires_in"] integerValue]]; } _parameters.expirationDate = expirationDate; NSError *error = nil; NSDictionary *state = [FBSDKInternalUtility objectForJSONString:parameters[@"state"] error:&error]; _parameters.challenge = [FBSDKUtility URLDecode:state[@"challenge"]]; } - (void)setErrorWithDictionary:(NSDictionary *)parameters { NSString *legacyErrorReason = parameters[@"error"]; if ([legacyErrorReason isEqualToString:@"service_disabled_use_browser"] || [legacyErrorReason isEqualToString:@"service_disabled"]) { _performExplicitFallback = YES; } // if error is nil, then this should be processed as a cancellation unless // _performExplicitFallback is set to YES and the log in behavior is Native. _parameters.error = [FBSDKLoginError errorFromReturnURLParameters:parameters]; } - (void)attemptBrowserLogIn:(FBSDKLoginManager *)loginManager { if (_observer != nil) { [[NSNotificationCenter defaultCenter] removeObserver:_observer]; _observer = nil; } if ([FBSDKApplicationDelegate sharedInstance].isActive) { [loginManager logInWithBehavior:FBSDKLoginBehaviorBrowser]; } else { // The application is active but due to notification ordering the FBSDKApplicationDelegate // doesn't know it yet. Wait one more turn of the run loop. dispatch_async(dispatch_get_main_queue(), ^{ [self attemptBrowserLogIn:loginManager]; }); } } @end @implementation FBSDKLoginSystemAccountCompleter { FBSDKLoginCompletionParameters *_parameters; } - (instancetype)init NS_UNAVAILABLE { assert(0); } - (instancetype)initWithTokenString:(NSString *)tokenString appID:(NSString *)appID { if ((self = [super init]) != nil) { _parameters = [[FBSDKLoginCompletionParameters alloc] init]; _parameters.accessTokenString = tokenString; _parameters.appID = appID; _parameters.systemAccount = YES; } return self; } - (void)completeLogIn:(FBSDKLoginManager *)loginManager withHandler:(void(^)(FBSDKLoginCompletionParameters *parameters))handler { void(^handlerCopy)(FBSDKLoginCompletionParameters *) = [handler copy]; FBSDKLoginRequestMeAndPermissions(_parameters, ^{ // Transform the FBSDKCoreKit error in to an FBSDKLoginKit error, if necessary. This specializes // the graph errors in to User Checkpointed, Password Changed or Unconfirmed User. // // It's possible the graph error has a value set for NSRecoveryAttempterErrorKey but we don't // have any login-specific attempter to provide since system auth succeeded and the error is a // graph API error. NSError *serverError = _parameters.error; NSError *error = [FBSDKLoginError errorFromServerError:serverError]; if (error != nil) { // In the event the user's password changed the Accounts framework will still return // an access token but API calls will fail. Clear the access token from the result // and use the special-case System Password changed error, which has different text // to display to the user. if (error.code == FBSDKLoginPasswordChangedErrorCode) { [FBSDKSystemAccountStoreAdapter sharedInstance].forceBlockingRenew = YES; _parameters.accessTokenString = nil; _parameters.appID = nil; error = [FBSDKLoginError errorForSystemPasswordChange:serverError]; } _parameters.error = error; } handlerCopy(_parameters); }); } @end @implementation FBSDKLoginSystemAccountErrorCompleter { FBSDKLoginCompletionParameters *_parameters; } - (instancetype)init NS_UNAVAILABLE { assert(0); } - (instancetype)initWithError:(NSError *)accountStoreError permissions:(NSSet *)permissions { if ((self = [super init]) != nil) { _parameters = [[FBSDKLoginCompletionParameters alloc] init]; NSError *error = [FBSDKLoginError errorForSystemAccountStoreError:accountStoreError]; if (error != nil) { _parameters.error = error; } else { // The lack of an error indicates the user declined permissions _parameters.declinedPermissions = permissions; } _parameters.systemAccount = YES; } return self; } - (void)completeLogIn:(FBSDKLoginManager *)loginManager withHandler:(void(^)(FBSDKLoginCompletionParameters *parameters))handler { handler(_parameters); } @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @interface FBSDKLoginError : NSObject + (NSString *)errorDomain; + (NSError *)errorForFailedLoginWithCode:(FBSDKLoginErrorCode)code; + (NSError *)errorForSystemAccountStoreError:(NSError *)accountStoreError; + (NSError *)errorForSystemPasswordChange:(NSError *)innerError; + (NSError *)errorFromReturnURLParameters:(NSDictionary *)parameters; + (NSError *)errorFromServerError:(NSError *)serverError; @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLoginError.h" #import "FBSDKCoreKit+Internal.h" typedef NS_ENUM(NSUInteger, FBSDKLoginErrorSubcode) { FBSDKLoginUserCheckpointedErrorSubcode = 459, FBSDKLoginPasswordChangedErrorSubcode = 460, FBSDKLoginUnconfirmedUserErrorSubcode = 464, }; @implementation FBSDKLoginError + (NSString *)errorDomain { return FBSDKLoginErrorDomain; } + (NSError *)errorForFailedLoginWithCode:(FBSDKLoginErrorCode)code; { return [self errorForFailedLoginWithCode:code innerError:nil]; } + (NSError *)errorForFailedLoginWithCode:(FBSDKLoginErrorCode)code innerError:(NSError *)innerError { NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; [FBSDKInternalUtility dictionary:userInfo setObject:innerError forKey:NSUnderlyingErrorKey]; NSString *errorDomain = [self errorDomain]; NSString *localizedDescription = nil; switch ((NSInteger)code) { case FBSDKNetworkErrorCode: errorDomain = FBSDKErrorDomain; localizedDescription = NSLocalizedStringWithDefaultValue(@"LoginError.SystemAccount.Network", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Unable to connect to Facebook. Check your network connection and try again.", @"The user facing error message when the Accounts framework encounters a network error."); break; case FBSDKLoginUserCheckpointedErrorCode: localizedDescription = NSLocalizedStringWithDefaultValue(@"LoginError.SystemAccount.UserCheckpointed", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"You cannot log in to apps at this time. Please log in to www.facebook.com and follow the instructions given.", @"The user facing error message when the Facebook account signed in to the Accounts framework has been checkpointed."); break; case FBSDKLoginUnconfirmedUserErrorCode: localizedDescription = NSLocalizedStringWithDefaultValue(@"LoginError.SystemAccount.UnconfirmedUser", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Your account is not confirmed. Please log in to www.facebook.com and follow the instructions given.", @"The user facing error message when the Facebook account signed in to the Accounts framework becomes unconfirmed."); break; case FBSDKLoginSystemAccountAppDisabledErrorCode: localizedDescription = NSLocalizedStringWithDefaultValue(@"LoginError.SystemAccount.Disabled", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Access has not been granted to the Facebook account. Verify device settings.", @"The user facing error message when the app slider has been disabled and login fails."); break; case FBSDKLoginSystemAccountUnavailableErrorCode: localizedDescription = NSLocalizedStringWithDefaultValue(@"LoginError.SystemAccount.Unavailable", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"The Facebook account has not been configured on the device.", @"The user facing error message when the device Facebook account is unavailable and login fails."); break; default: break; } [FBSDKInternalUtility dictionary:userInfo setObject:localizedDescription forKey:NSLocalizedDescriptionKey]; [FBSDKInternalUtility dictionary:userInfo setObject:localizedDescription forKey:FBSDKErrorLocalizedDescriptionKey]; return [NSError errorWithDomain:errorDomain code:code userInfo:userInfo]; } + (NSError *)errorForSystemAccountStoreError:(NSError *)accountStoreError { NSError *err = nil; BOOL cancellation = NO; if ([accountStoreError.domain isEqualToString:[self errorDomain]] || [accountStoreError.domain isEqualToString:[FBSDKError errorDomain]]) { // If the requestAccess call results in a Facebook error, surface it as a top-level // error. This implies it is not the typical user "disallows" case. err = accountStoreError; } else if ([accountStoreError.domain isEqualToString:@"com.apple.accounts"] && accountStoreError.code == 7) { err = [self errorWithSystemAccountStoreDeniedError:accountStoreError isCancellation:&cancellation]; } if (err == nil && !cancellation) { // create an error object with additional info regarding failed login NSInteger errorCode = FBSDKLoginSystemAccountUnavailableErrorCode; NSString *errorDomain = accountStoreError.domain; if ([errorDomain isEqualToString:NSURLErrorDomain] || [errorDomain isEqualToString:@"kCFErrorDomainCFNetwork"]) { errorCode = FBSDKNetworkErrorCode; } err = [self errorForFailedLoginWithCode:errorCode innerError:accountStoreError]; } return err; } + (NSError *)errorForSystemPasswordChange:(NSError *)innerError { NSString *failureReasonAndDescription = NSLocalizedStringWithDefaultValue(@"LoginError.SystemAccount.PasswordChange", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Your Facebook password has changed. To confirm your password, open Settings > Facebook and tap your name.", @"The user facing error message when the device Facebook account password is incorrect and login fails."); NSMutableDictionary *userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys: failureReasonAndDescription, FBSDKErrorLocalizedDescriptionKey, failureReasonAndDescription, NSLocalizedDescriptionKey, nil]; [FBSDKInternalUtility dictionary:userInfo setObject:innerError forKey:NSUnderlyingErrorKey]; return [NSError errorWithDomain:[self errorDomain] code:FBSDKLoginPasswordChangedErrorCode userInfo:userInfo]; } + (NSError *)errorFromReturnURLParameters:(NSDictionary *)parameters { NSError *error = nil; NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:userInfo setObject:parameters[@"error_message"] forKey:FBSDKErrorDeveloperMessageKey]; if (userInfo.count > 0) { [FBSDKInternalUtility dictionary:userInfo setObject:parameters[@"error"] forKey:FBSDKErrorDeveloperMessageKey]; [FBSDKInternalUtility dictionary:userInfo setObject:parameters[@"error_code"] forKey:FBSDKGraphRequestErrorGraphErrorCode]; if (!userInfo[FBSDKErrorDeveloperMessageKey]) { [FBSDKInternalUtility dictionary:userInfo setObject:parameters[@"error_reason"] forKey:FBSDKErrorDeveloperMessageKey]; } userInfo[FBSDKGraphRequestErrorCategoryKey] = @(FBSDKGraphRequestErrorCategoryOther); error = [NSError errorWithDomain:FBSDKErrorDomain code:FBSDKGraphRequestGraphAPIErrorCode userInfo:userInfo]; } return error; } + (NSError *)errorFromServerError:(NSError *)serverError { NSError *loginError = nil; if ([serverError.domain isEqualToString:FBSDKErrorDomain]) { NSDictionary *response = [FBSDKTypeUtility dictionaryValue:serverError.userInfo[FBSDKGraphRequestErrorParsedJSONResponseKey]]; NSDictionary *body = [FBSDKTypeUtility dictionaryValue:response[@"body"]]; NSDictionary *error = [FBSDKTypeUtility dictionaryValue:body[@"error"]]; NSInteger subcode = [FBSDKTypeUtility integerValue:error[@"error_subcode"]]; switch (subcode) { case FBSDKLoginUserCheckpointedErrorSubcode: loginError = [self errorForFailedLoginWithCode:FBSDKLoginUserCheckpointedErrorCode innerError:serverError]; break; case FBSDKLoginPasswordChangedErrorSubcode: loginError = [self errorForFailedLoginWithCode:FBSDKLoginPasswordChangedErrorCode innerError:serverError]; break; case FBSDKLoginUnconfirmedUserErrorSubcode: loginError = [self errorForFailedLoginWithCode:FBSDKLoginUnconfirmedUserErrorCode innerError:serverError]; break; } } return loginError; } + (NSError *)errorWithSystemAccountStoreDeniedError:(NSError *)accountStoreError isCancellation:(BOOL *)cancellation { // The Accounts framework returns an ACErrorPermissionDenied error for both user denied errors, // Facebook denied errors, and other things. Unfortunately examining the contents of the // description is the only means available to determine the reason for the error. NSString *description = accountStoreError.userInfo[NSLocalizedDescriptionKey]; NSError *err = nil; if (description) { // If a parenthetical error code exists, map it ot a Facebook server error FBSDKLoginErrorCode errorCode = FBSDKLoginReservedErrorCode; if ([description rangeOfString:@"(459)"].location != NSNotFound) { // The Facebook server could not fulfill this access request: Error validating access token: // You cannot access the app till you log in to www.facebook.com and follow the instructions given. (459) // The OAuth endpoint directs people to www.facebook.com when an account has been // checkpointed. If the web address is present, assume it's due to a checkpoint. errorCode = FBSDKLoginUserCheckpointedErrorCode; } else if ([description rangeOfString:@"(452)"].location != NSNotFound || [description rangeOfString:@"(460)"].location != NSNotFound) { // The Facebook server could not fulfill this access request: Error validating access token: // Session does not match current stored session. This may be because the user changed the password since // the time the session was created or Facebook has changed the session for security reasons. (452)or(460) // If the login failed due to the session changing, maybe it's due to the password // changing. Direct the user to update the password in the Settings > Facebook. err = [self errorForSystemPasswordChange:accountStoreError]; } else if ([description rangeOfString:@"(464)"].location != NSNotFound) { // The Facebook server could not fulfill this access request: Error validating access token: // Sessions for the user are not allowed because the user is not a confirmed user. (464) errorCode = FBSDKLoginUnconfirmedUserErrorCode; } if (errorCode != FBSDKLoginReservedErrorCode) { err = [self errorForFailedLoginWithCode:errorCode]; } } else { // If there is no description, assume this is a user cancellation. No error object is // returned for a cancellation. if (cancellation != NULL) { *cancellation = YES; } } return err; } - (instancetype)init { FBSDK_NO_DESIGNATED_INITIALIZER(); return nil; } @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginKit+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKLoginCompletion+Internal.h" #import "FBSDKLoginError.h" #import "FBSDKLoginManager+Internal.h" #import "FBSDKLoginUtility.h" ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import "FBSDKCoreKit+Internal.h" @class FBSDKAccessToken; @class FBSDKLoginCompletionParameters; @interface FBSDKLoginManagerSystemAccountState : NSObject @property (nonatomic) BOOL didShowDialog; @property (nonatomic, getter=isReauthorize) BOOL reauthorize; @property (nonatomic, getter=isUnTOSedDevice) BOOL unTOSedDevice; @end @interface FBSDKLoginManager () @property (nonatomic, weak) UIViewController *fromViewController; @property (nonatomic, readonly) NSSet *requestedPermissions; - (void)completeAuthentication:(FBSDKLoginCompletionParameters *)parameters expectChallenge:(BOOL)expectChallenge; // available to internal types to trigger login without checking read/publish mixtures. - (void)logInWithPermissions:(NSSet *)permissions handler:(FBSDKLoginManagerRequestTokenHandler)handler; - (void)logInWithBehavior:(FBSDKLoginBehavior)loginBehavior; // made available for testing only - (NSDictionary *)logInParametersWithPermissions:(NSSet *)permissions serverConfiguration:(FBSDKServerConfiguration *)serverConfiguration; // made available for testing only - (void)validateReauthentication:(FBSDKAccessToken *)currentToken withResult:(FBSDKLoginManagerLoginResult *)loginResult; // for testing only - (void)setHandler:(FBSDKLoginManagerRequestTokenHandler)handler; // for testing only - (void)setRequestedPermissions:(NSSet *)requestedPermissions; // for testing only - (NSString *)loadExpectedChallenge; @end // the category is made available for testing only @interface FBSDKLoginManager (Native) - (void)performNativeLogInWithParameters:(NSDictionary *)loginParams handler:(void(^)(BOOL, NSError*))handler; - (void)performBrowserLogInWithParameters:(NSDictionary *)loginParams handler:(void(^)(BOOL, NSString *,NSError*))handler; @end // the category is made available for testing only @interface FBSDKLoginManager (Accounts) - (void)beginSystemLogIn; - (void)performSystemLogIn; - (void)continueSystemLogInWithTokenString:(NSString *)oauthToken error:(NSError *)accountStoreError state:(FBSDKLoginManagerSystemAccountState *)state; - (void)fallbackToNativeBehavior; @end // the category is made available for testing only @interface FBSDKLoginManager (WebDialog) - (void)performWebLogInWithParameters:(NSDictionary *)loginParams handler:(void(^)(BOOL, NSError*))handler; @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLoginManager+Internal.h" extern NSString *const FBSDKLoginManagerLoggerAuthMethod_Native; extern NSString *const FBSDKLoginManagerLoggerAuthMethod_Browser; extern NSString *const FBSDKLoginManagerLoggerAuthMethod_System; extern NSString *const FBSDKLoginManagerLoggerAuthMethod_Webview; extern NSString *const FBSDKLoginManagerLoggerAuthMethod_SFVC; @interface FBSDKLoginManagerLogger : NSObject + (FBSDKLoginManagerLogger *)loggerFromParameters:(NSDictionary *)parameters; // this must not retain loginManager - only used to conveniently grab various properties to log. - (void)startSessionForLoginManager:(FBSDKLoginManager *)loginManager; - (void)endSession; - (void)startAuthMethod:(NSString *)authMethod; - (void)endLoginWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error; - (NSDictionary *)parametersWithTimeStampAndClientState:(NSDictionary *)loginParams forAuthMethod:(NSString *)authMethod; - (void)willAttemptAppSwitchingBehavior; - (void)systemAuthDidShowDialog:(BOOL)didShowDialog isUnTOSedDevice:(BOOL)isUnTOSedDevice; @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLoginManagerLogger.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKLoginError.h" #import "FBSDKLoginManagerLoginResult+Internal.h" #import "FBSDKLoginUtility.h" NSString *const FBSDKLoginManagerLoggerAuthMethod_Native = @"fb_application_web_auth"; NSString *const FBSDKLoginManagerLoggerAuthMethod_Browser = @"browser_auth"; NSString *const FBSDKLoginManagerLoggerAuthMethod_System = @"integrated_auth"; NSString *const FBSDKLoginManagerLoggerAuthMethod_Webview = @"fallback_auth"; NSString *const FBSDKLoginManagerLoggerAuthMethod_SFVC = @"sfvc_auth"; static NSString *const FBSDKLoginManagerLoggingClientStateKey = @"state"; static NSString *const FBSDKLoginManagerLoggingClientStateIsClientState = @"com.facebook.sdk_client_state"; static NSString *const FBSDKLoginManagerLoggerParamIdentifierKey = @"0_auth_logger_id"; static NSString *const FBSDKLoginManagerLoggerParamTimestampKey = @"1_timestamp_ms"; static NSString *const FBSDKLoginManagerLoggerParamResultKey = @"2_result"; static NSString *const FBSDKLoginManagerLoggerParamAuthMethodKey = @"3_method"; static NSString *const FBSDKLoginManagerLoggerParamErrorCodeKey = @"4_error_code"; static NSString *const FBSDKLoginManagerLoggerParamErrorMessageKey = @"5_error_message"; static NSString *const FBSDKLoginManagerLoggerParamExtrasKey = @"6_extras"; static NSString *const FBSDKLoginManagerLoggerValueEmpty = @""; static NSString *const FBSDKLoginManagerLoggerResultSuccessString = @"success"; static NSString *const FBSDKLoginManagerLoggerResultCancelString = @"cancelled"; static NSString *const FBSDKLoginManagerLoggerResultErrorString = @"error"; static NSString *const FBSDKLoginManagerLoggerResultSkippedString = @"skipped"; static NSString *const FBSDKLoginManagerLoggerTryNative = @"tryFBAppAuth"; static NSString *const FBSDKLoginManagerLoggerTryBrowser = @"trySafariAuth"; static NSString *const FBSDKLoginManagerLoggerTrySystemAccount = @"tryIntegratedAuth"; static NSString *const FBSDKLoginManagerLoggerTryWebView = @"tryFallback"; @implementation FBSDKLoginManagerLogger { @private NSString *_identifier; NSMutableDictionary *_extras; NSString *_lastResult; NSError *_lastError; NSString *_authMethod; } + (FBSDKLoginManagerLogger *)loggerFromParameters:(NSDictionary *)parameters { NSDictionary *clientState = [FBSDKInternalUtility objectForJSONString:parameters[FBSDKLoginManagerLoggingClientStateKey] error:NULL]; id isClientState = clientState[FBSDKLoginManagerLoggingClientStateIsClientState]; if ([isClientState isKindOfClass:[NSNumber class]] && [isClientState boolValue]) { FBSDKLoginManagerLogger *logger = [[self alloc] init]; if (logger != nil) { logger->_identifier = clientState[FBSDKLoginManagerLoggerParamIdentifierKey]; logger->_authMethod = clientState[FBSDKLoginManagerLoggerParamAuthMethodKey]; return logger; } } return nil; } - (instancetype)init { if ((self = [super init]) != nil) { _identifier = [[NSUUID UUID] UUIDString]; _extras = [NSMutableDictionary dictionary]; } return self; } - (void)startSessionForLoginManager:(FBSDKLoginManager *)loginManager { BOOL isReauthorize = ([FBSDKAccessToken currentAccessToken] != nil); BOOL willTryNative = NO; BOOL willTryBrowser = NO; BOOL willTrySystemAccount = NO; BOOL willTryWebView = NO; NSString *behaviorString = nil; switch (loginManager.loginBehavior) { case FBSDKLoginBehaviorNative: willTryNative = YES; willTryBrowser = YES; behaviorString = @"FBSDKLoginBehaviorNative"; break; case FBSDKLoginBehaviorBrowser: willTryBrowser = YES; behaviorString = @"FBSDKLoginBehaviorBrowser"; break; case FBSDKLoginBehaviorSystemAccount: willTryNative = YES; willTryBrowser = YES; willTrySystemAccount = YES; behaviorString = @"FBSDKLoginBehaviorSystemAccount"; break; case FBSDKLoginBehaviorWeb: willTryWebView = YES; behaviorString = @"FBSDKLoginBehaviorWeb"; break; } [_extras addEntriesFromDictionary:@{ FBSDKLoginManagerLoggerTryNative : @(willTryNative), FBSDKLoginManagerLoggerTryBrowser : @(willTryBrowser), FBSDKLoginManagerLoggerTrySystemAccount : @(willTrySystemAccount), FBSDKLoginManagerLoggerTryWebView : @(willTryWebView), @"isReauthorize" : @(isReauthorize), @"login_behavior" : behaviorString, @"default_audience" : [FBSDKLoginUtility stringForAudience:loginManager.defaultAudience], @"permissions" : [[loginManager.requestedPermissions allObjects] componentsJoinedByString:@","] ?: @"" }]; [self logEvent:FBSDKAppEventNameFBSessionAuthStart params:[self _parametersForNewEvent]]; } - (void)endSession { [self logEvent:FBSDKAppEventNameFBSessionAuthEnd result:_lastResult error:_lastError]; } - (void)startAuthMethod:(NSString *)authMethod { _authMethod = authMethod; [self logEvent:FBSDKAppEventNameFBSessionAuthMethodStart params:[self _parametersForNewEvent]]; } - (void)endLoginWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error { NSString *resultString = @""; if (error != nil) { resultString = FBSDKLoginManagerLoggerResultErrorString; } else if (result.isCancelled) { resultString = FBSDKLoginManagerLoggerResultCancelString; } else if (result.isSkipped) { resultString = FBSDKLoginManagerLoggerResultSkippedString; } else if (result.token) { resultString = FBSDKLoginManagerLoggerResultSuccessString; if (result.declinedPermissions.count) { _extras[@"declined_permissions"] = [[result.declinedPermissions allObjects] componentsJoinedByString:@","]; } } _lastResult = resultString; _lastError = error; [_extras addEntriesFromDictionary:result.loggingExtras]; [self logEvent:FBSDKAppEventNameFBSessionAuthMethodEnd result:resultString error:error]; } - (NSDictionary *)parametersWithTimeStampAndClientState:(NSDictionary *)loginParams forAuthMethod:(NSString *)authMethod { NSMutableDictionary *params = [loginParams mutableCopy]; NSTimeInterval timeValue = (NSTimeInterval)FBSDKMonotonicTimeGetCurrentSeconds(); NSString *e2eTimestampString = [FBSDKInternalUtility JSONStringForObject:@{ @"init" : @(timeValue) } error:NULL invalidObjectHandler:NULL]; params[@"e2e"] = e2eTimestampString; NSDictionary *existingState = [FBSDKInternalUtility objectForJSONString:params[FBSDKLoginManagerLoggingClientStateKey] error:NULL]; params[FBSDKLoginManagerLoggingClientStateKey] = [self clientStateForAuthMethod:authMethod andExistingState:existingState]; return params; } - (void)willAttemptAppSwitchingBehavior { NSString *defaultUrlScheme = [NSString stringWithFormat:@"fb%@%@", [FBSDKSettings appID], [FBSDKSettings appURLSchemeSuffix] ?: @""]; BOOL isURLSchemeRegistered = [FBSDKInternalUtility isRegisteredURLScheme:defaultUrlScheme]; BOOL isFacebookAppCanOpenURLSchemeRegistered = [FBSDKInternalUtility isRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_FACEBOOK]; BOOL isMessengerAppCanOpenURLSchemeRegistered = [FBSDKInternalUtility isRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_MESSENGER]; [_extras addEntriesFromDictionary:@{ @"isURLSchemeRegistered" : @(isURLSchemeRegistered), @"isFacebookAppCanOpenURLSchemeRegistered" : @(isFacebookAppCanOpenURLSchemeRegistered), @"isMessengerAppCanOpenURLSchemeRegistered" : @(isMessengerAppCanOpenURLSchemeRegistered), }]; } - (void)systemAuthDidShowDialog:(BOOL)didShowDialog isUnTOSedDevice:(BOOL)isUnTOSedDevice { [_extras addEntriesFromDictionary:@{ @"isUntosedDevice" : @(isUnTOSedDevice), @"dialogShown" : @(didShowDialog), }]; } #pragma mark - Private - (NSString *)clientStateForAuthMethod:(NSString *)authMethod andExistingState:(NSDictionary *)existingState { NSDictionary *clientState = @{ FBSDKLoginManagerLoggerParamAuthMethodKey: authMethod ?: @"", FBSDKLoginManagerLoggerParamIdentifierKey: _identifier, FBSDKLoginManagerLoggingClientStateIsClientState: @YES, }; if (existingState) { NSMutableDictionary *mutableState = [clientState mutableCopy]; [mutableState addEntriesFromDictionary:existingState]; clientState = mutableState; } return [FBSDKInternalUtility JSONStringForObject:clientState error:NULL invalidObjectHandler:NULL]; } - (NSMutableDictionary *)_parametersForNewEvent { NSMutableDictionary *eventParameters = [[NSMutableDictionary alloc] init]; // NOTE: We ALWAYS add all params to each event, to ensure predictable mapping on the backend. eventParameters[FBSDKLoginManagerLoggerParamIdentifierKey] = _identifier ?: FBSDKLoginManagerLoggerValueEmpty; eventParameters[FBSDKLoginManagerLoggerParamTimestampKey] = [NSNumber numberWithDouble:round(1000 * [[NSDate date] timeIntervalSince1970])]; eventParameters[FBSDKLoginManagerLoggerParamResultKey] = FBSDKLoginManagerLoggerValueEmpty; [FBSDKInternalUtility dictionary:eventParameters setObject:_authMethod forKey:FBSDKLoginManagerLoggerParamAuthMethodKey]; eventParameters[FBSDKLoginManagerLoggerParamErrorCodeKey] = FBSDKLoginManagerLoggerValueEmpty; eventParameters[FBSDKLoginManagerLoggerParamErrorMessageKey] = FBSDKLoginManagerLoggerValueEmpty; eventParameters[FBSDKLoginManagerLoggerParamExtrasKey] = FBSDKLoginManagerLoggerValueEmpty; return eventParameters; } - (void)logEvent:(NSString *)eventName params:(NSMutableDictionary *)params { if (_identifier) { NSString *extrasJSONString = [FBSDKInternalUtility JSONStringForObject:_extras error:NULL invalidObjectHandler:NULL]; if (extrasJSONString) { params[FBSDKLoginManagerLoggerParamExtrasKey] = extrasJSONString; } [_extras removeAllObjects]; [FBSDKAppEvents logImplicitEvent:eventName valueToSum:nil parameters:params accessToken:nil]; } } - (void)logEvent:(NSString *)eventName result:(NSString *)result error:(NSError *)error { NSMutableDictionary *params = [self _parametersForNewEvent]; params[FBSDKLoginManagerLoggerParamResultKey] = result; if ([error.domain isEqualToString:FBSDKErrorDomain] || [error.domain isEqualToString:FBSDKLoginErrorDomain]) { // tease apart the structure. // first see if there is an explicit message in the error's userInfo. If not, default to the reason, // which is less useful. NSString *value = error.userInfo[@"error_message"] ?: error.userInfo[FBSDKErrorLocalizedDescriptionKey]; [FBSDKInternalUtility dictionary:params setObject:value forKey:FBSDKLoginManagerLoggerParamErrorMessageKey]; value = error.userInfo[FBSDKGraphRequestErrorGraphErrorCode] ?: [NSString stringWithFormat:@"%ld", (long)error.code]; [FBSDKInternalUtility dictionary:params setObject:value forKey:FBSDKLoginManagerLoggerParamErrorCodeKey]; NSError *innerError = error.userInfo[NSUnderlyingErrorKey]; if (innerError != nil) { value = innerError.userInfo[@"error_message"] ?: innerError.userInfo[NSLocalizedDescriptionKey]; [FBSDKInternalUtility dictionary:_extras setObject:value forKey:@"inner_error_message"]; value = innerError.userInfo[FBSDKGraphRequestErrorGraphErrorCode] ?: [NSString stringWithFormat:@"%ld", (long)innerError.code]; [FBSDKInternalUtility dictionary:_extras setObject:value forKey:@"inner_error_code"]; } } else if (error) { params[FBSDKLoginManagerLoggerParamErrorCodeKey] = @(error.code); } [self logEvent:eventName params:params]; } @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLoginResult+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @interface FBSDKLoginManagerLoginResult() @property (nonatomic, readonly) NSDictionary *loggingExtras; // legacy flag indicating this is an intermediary result only for logging purposes. @property (nonatomic) BOOL isSkipped; // adds additional logging entry to extras - only sent as part of `endLoginWithResult:` -(void)addLoggingExtra:(id)object forKey:(id)key; @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @interface FBSDKLoginUtility : NSObject + (NSString *)stringForAudience:(FBSDKDefaultAudience)audience; + (NSDictionary *)queryParamsFromLoginURL:(NSURL *)url; + (NSString *)userIDFromSignedRequest:(NSString *)signedRequest; @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLoginUtility.h" #import #import #import "FBSDKCoreKit+Internal.h" #import "FBSDKLoginConstants.h" @implementation FBSDKLoginUtility + (NSString *)stringForAudience:(FBSDKDefaultAudience)audience { switch (audience) { case FBSDKDefaultAudienceOnlyMe: return @"only_me"; case FBSDKDefaultAudienceFriends: return @"friends"; case FBSDKDefaultAudienceEveryone: return @"everyone"; } } + (NSDictionary *)queryParamsFromLoginURL:(NSURL *)url { NSString *expectedUrlPrefix = [FBSDKInternalUtility appURLWithHost:@"authorize" path:nil queryParameters:nil error:NULL].absoluteString; if (![[url absoluteString] hasPrefix:expectedUrlPrefix]) { // Don't have an App ID, just verify path. NSString *host = url.host; if (![host isEqualToString:@"authorize"]) { return nil; } } NSMutableDictionary *params = [NSMutableDictionary dictionaryWithDictionary:[FBSDKInternalUtility dictionaryFromFBURL:url]]; NSString *userID = [[self class] userIDFromSignedRequest:params[@"signed_request"]]; if (userID) { params[@"user_id"] = userID; } return params; } + (NSString *)userIDFromSignedRequest:(NSString *)signedRequest { if (!signedRequest) { return nil; } NSArray *signatureAndPayload = [signedRequest componentsSeparatedByString:@"."]; NSString *userID = nil; if (signatureAndPayload.count == 2) { NSData *data = [FBSDKBase64 decodeAsData:signatureAndPayload[1]]; if (data) { NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; userID = dictionary[@"user_id"]; } } return userID; } - (instancetype)init { FBSDK_NO_DESIGNATED_INITIALIZER(); return nil; } @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKCoreKit+Internal.h" @interface _FBSDKLoginRecoveryAttempter : FBSDKErrorRecoveryAttempter @end ================================================ FILE: Pods/FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "_FBSDKLoginRecoveryAttempter.h" #import "FBSDKLoginKit+Internal.h" @implementation _FBSDKLoginRecoveryAttempter - (void)attemptRecoveryFromError:(NSError *)error optionIndex:(NSUInteger)recoveryOptionIndex delegate:(id)delegate didRecoverSelector:(SEL)didRecoverSelector contextInfo:(void *)contextInfo { void(^handler)(BOOL) = ^(BOOL didRecover) { [super completeRecovery:didRecover delegate:delegate didRecoverSelector:didRecoverSelector contextInfo:contextInfo]; }; NSSet *currentPermissions = [FBSDKAccessToken currentAccessToken].permissions; if (recoveryOptionIndex == 0 && currentPermissions.count > 0) { FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; [login logInWithPermissions:currentPermissions handler:^(FBSDKLoginManagerLoginResult *result, NSError *loginError) { // we can only consider a recovery successful if there are no declines // (note this could still set an updated currentAccessToken). handler(!loginError && !result.isCancelled && result.declinedPermissions.count == 0); }]; } else { handler(NO); } } @end ================================================ FILE: Pods/FBSDKLoginKit/LICENSE ================================================ Copyright (c) 2014-present, Facebook, Inc. All rights reserved. You are hereby granted a non-exclusive, worldwide, royalty-free license to use, copy, modify, and distribute this software in source code or binary form for use in connection with the web services and APIs provided by Facebook. As with any software that integrates with the Facebook platform, your use of this software is subject to the Facebook Developer Principles and Policies [http://developers.facebook.com/policy/]. This copyright 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. ================================================ FILE: Pods/FBSDKLoginKit/README.mdown ================================================ Facebook SDK for iOS ==================== This open-source library allows you to integrate Facebook into your iOS app. Learn more about the provided samples, documentation, integrating the SDK into your app, accessing source code, and more at https://developers.facebook.com/docs/ios NOTE: By default, the Facebook SDK for iOS is installed in ~/Documents/FacebookSDK TRY IT OUT ---------- 1. Download the SDK at https://developers.facebook.com/docs/ios or via CocoaPods by adding the 'FBSDKCoreKit', 'FBSDKLoginKit', and 'FBSDKShareKit' pods. 2. Test your install: build and run the project at ~/Documents/FacebookSDK/Samples/Scrumptious/Scrumptious.xcodeproj 3. Check-out the tutorials available online at: https://developers.facebook.com/docs/ios/getting-started 4. Start coding! Visit https://developers.facebook.com/docs/ios for tutorials and reference documentation. FEATURES -------- * Login - https://developers.facebook.com/docs/facebook-login * Sharing - https://developers.facebook.com/docs/sharing * App Links - https://developers.facebook.com/docs/applinks * Graph API - https://developers.facebook.com/docs/ios/graph * Analytics for Apps - https://developers.facebook.com/docs/analytics GIVE FEEDBACK ------------- Please report bugs or issues to https://developers.facebook.com/bugs/ You can also join the Facebook Developers Group on Facebook (https://www.facebook.com/groups/fbdevelopers/) or ask questions on Stack Overflow (http://facebook.stackoverflow.com) LICENSE ------- See the LICENSE file. DEVELOPER TERMS --------------- - By enabling Facebook integrations, including through this SDK, you can share information with Facebook, including information about people’s use of your app. Facebook will use information received in accordance with our Data Use Policy [https://www.facebook.com/about/privacy/], including to provide you with insights about the effectiveness of your ads and the use of your app. These integrations also enable us and our partners to serve ads on and off Facebook. - You may limit your sharing of information with us by updating the Insights control in the developer tool [https://developers.facebook.com/apps/{app_id}/settings/advanced]. - If you use a Facebook integration, including to share information with us, you agree and confirm that you have provided appropriate and sufficiently prominent notice to and obtained the appropriate consent from your users regarding such collection, use, and disclosure (including, at a minimum, through your privacy policy). You further agree that you will not share information with us about children under the age of 13. - You agree to comply with all applicable laws and regulations and also agree to our Terms , including our Platform Policies .and Advertising Guidelines, as applicable . By using the Facebook SDK for iOS you agree to these terms. ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupAddDialog.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @protocol FBSDKAppGroupAddDialogDelegate; /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ __attribute__ ((deprecated)) @interface FBSDKAppGroupAddDialog : NSObject /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ + (instancetype)showWithContent:(FBSDKAppGroupContent *)content delegate:(id)delegate __attribute__ ((deprecated)); /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ @property (nonatomic, weak) id delegate __attribute__ ((deprecated)); /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ @property (nonatomic, copy) FBSDKAppGroupContent *content __attribute__ ((deprecated)); /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ - (BOOL)canShow __attribute__ ((deprecated)); /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ - (BOOL)show __attribute__ ((deprecated)); /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ - (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef __attribute__ ((deprecated)); @end /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ __attribute__ ((deprecated)) @protocol FBSDKAppGroupAddDialogDelegate /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ - (void)appGroupAddDialog:(FBSDKAppGroupAddDialog *)appGroupAddDialog didCompleteWithResults:(NSDictionary *)results __attribute__ ((deprecated)); /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ - (void)appGroupAddDialog:(FBSDKAppGroupAddDialog *)appGroupAddDialog didFailWithError:(NSError *)error __attribute__ ((deprecated)); /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ - (void)appGroupAddDialogDidCancel:(FBSDKAppGroupAddDialog *)appGroupAddDialog __attribute__ ((deprecated)); @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupAddDialog.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAppGroupAddDialog.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKShareConstants.h" #import "FBSDKShareError.h" #import "FBSDKShareUtility.h" @interface FBSDKAppGroupAddDialog () @end @implementation FBSDKAppGroupAddDialog { FBSDKWebDialog *_webDialog; } #define FBSDK_APP_GROUP_CREATE_METHOD_NAME @"game_group_create" #pragma mark - Class Methods + (instancetype)showWithContent:(FBSDKAppGroupContent *)content delegate:(id)delegate { FBSDKAppGroupAddDialog *dialog = [[self alloc] init]; dialog.content = content; dialog.delegate = delegate; [dialog show]; return dialog; } #pragma mark - Object Lifecycle - (instancetype)init { if ((self = [super init])) { _webDialog = [[FBSDKWebDialog alloc] init]; _webDialog.delegate = self; _webDialog.name = FBSDK_APP_GROUP_CREATE_METHOD_NAME; } return self; } - (void)dealloc { _webDialog.delegate = nil; } #pragma mark - Public Methods - (BOOL)canShow { return YES; } - (BOOL)show { NSError *error; if (![self canShow]) { error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode message:@"App group create dialog is not available."]; [_delegate appGroupAddDialog:self didFailWithError:error]; return NO; } if (![self validateWithError:&error]) { [_delegate appGroupAddDialog:self didFailWithError:error]; return NO; } FBSDKAppGroupContent *content = self.content; NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:parameters setObject:content.name forKey:@"name"]; [FBSDKInternalUtility dictionary:parameters setObject:content.groupDescription forKey:@"description"]; [FBSDKInternalUtility dictionary:parameters setObject:NSStringFromFBSDKAppGroupPrivacy(content.privacy) forKey:@"privacy"]; _webDialog.parameters = parameters; [_webDialog show]; [FBSDKInternalUtility registerTransientObject:self]; return YES; } - (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef { FBSDKAppGroupContent *content = self.content; if (!content) { if (errorRef != NULL) { *errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"content" message:nil]; } return NO; } if (![content.name length]) { if (errorRef != NULL) { *errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"name" message:nil]; } return NO; } if (![content.groupDescription length]) { if (errorRef != NULL) { *errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"groupDescription" message:nil]; } return NO; } if (errorRef != NULL) { *errorRef = nil; } return YES; } #pragma mark - FBSDKWebDialogDelegate - (void)webDialog:(FBSDKWebDialog *)webDialog didCompleteWithResults:(NSDictionary *)results { if (_webDialog != webDialog) { return; } NSError *error = [FBSDKShareError errorWithCode:[FBSDKTypeUtility unsignedIntegerValue:results[@"error_code"]] message:[FBSDKTypeUtility stringValue:results[@"error_message"]]]; [self _handleCompletionWithDialogResults:results error:error]; [FBSDKInternalUtility unregisterTransientObject:self]; } - (void)webDialog:(FBSDKWebDialog *)webDialog didFailWithError:(NSError *)error { if (_webDialog != webDialog) { return; } [self _handleCompletionWithDialogResults:nil error:error]; [FBSDKInternalUtility unregisterTransientObject:self]; } - (void)webDialogDidCancel:(FBSDKWebDialog *)webDialog { if (_webDialog != webDialog) { return; } [_delegate appGroupAddDialogDidCancel:self]; [FBSDKInternalUtility unregisterTransientObject:self]; } #pragma mark - Helper Methods - (void)_handleCompletionWithDialogResults:(NSDictionary *)results error:(NSError *)error { if (!_delegate) { return; } switch (error.code) { case 0:{ [_delegate appGroupAddDialog:self didCompleteWithResults:results]; break; } case 4201:{ [_delegate appGroupAddDialogDidCancel:self]; break; } default:{ [_delegate appGroupAddDialog:self didFailWithError:error]; break; } } if (error) { return; } else { } } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupContent.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import /*! @typedef NS_ENUM(NSUInteger, FBSDKAppGroupPrivacy) @abstract Specifies the privacy of a group. */ typedef NS_ENUM(NSUInteger, FBSDKAppGroupPrivacy) { /*! Anyone can see the group, who's in it and what members post. */ FBSDKAppGroupPrivacyOpen = 0, /*! Anyone can see the group and who's in it, but only members can see posts. */ FBSDKAppGroupPrivacyClosed, }; /*! @abstract Converts an FBSDKAppGroupPrivacy to an NSString. */ FBSDK_EXTERN NSString *NSStringFromFBSDKAppGroupPrivacy(FBSDKAppGroupPrivacy privacy); /*! @abstract A model for creating an app group. */ @interface FBSDKAppGroupContent : NSObject /*! @abstract The description of the group. */ @property (nonatomic, copy) NSString *groupDescription; /*! @abstract The name of the group. */ @property (nonatomic, copy) NSString *name; /*! @abstract The privacy for the group. */ @property (nonatomic, assign) FBSDKAppGroupPrivacy privacy; /*! @abstract Compares the receiver to another app group content. @param content The other content @return YES if the receiver's values are equal to the other content's values; otherwise NO */ - (BOOL)isEqualToAppGroupContent:(FBSDKAppGroupContent *)content; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupContent.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAppGroupContent.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKShareUtility.h" #define FBSDK_APP_GROUP_CONTENT_GROUP_DESCRIPTION_KEY @"groupDescription" #define FBSDK_APP_GROUP_CONTENT_NAME_KEY @"name" #define FBSDK_APP_GROUP_CONTENT_PRIVACY_KEY @"privacy" NSString *NSStringFromFBSDKAppGroupPrivacy(FBSDKAppGroupPrivacy privacy) { switch (privacy) { case FBSDKAppGroupPrivacyClosed:{ return @"closed"; } case FBSDKAppGroupPrivacyOpen:{ return @"open"; } } } @implementation FBSDKAppGroupContent #pragma mark - Equality - (NSUInteger)hash { NSUInteger subhashes[] = { [_groupDescription hash], [_name hash], _privacy, }; return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKAppGroupContent class]]) { return NO; } return [self isEqualToAppGroupContent:(FBSDKAppGroupContent *)object]; } - (BOOL)isEqualToAppGroupContent:(FBSDKAppGroupContent *)content { return (content && (_privacy == content.privacy) && [FBSDKInternalUtility object:_name isEqualToObject:content.name] && [FBSDKInternalUtility object:_groupDescription isEqualToObject:content.groupDescription]); } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [self init])) { _groupDescription = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_APP_GROUP_CONTENT_GROUP_DESCRIPTION_KEY]; _name = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_APP_GROUP_CONTENT_PRIVACY_KEY]; _privacy = [decoder decodeIntegerForKey:FBSDK_APP_GROUP_CONTENT_PRIVACY_KEY]; } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_groupDescription forKey:FBSDK_APP_GROUP_CONTENT_GROUP_DESCRIPTION_KEY]; [encoder encodeObject:_name forKey:FBSDK_APP_GROUP_CONTENT_NAME_KEY]; [encoder encodeInteger:_privacy forKey:FBSDK_APP_GROUP_CONTENT_PRIVACY_KEY]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { FBSDKAppGroupContent *copy = [[FBSDKAppGroupContent alloc] init]; copy->_groupDescription = [_groupDescription copy]; copy->_name = [_name copy]; copy->_privacy = _privacy; return copy; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupJoinDialog.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @protocol FBSDKAppGroupJoinDialogDelegate; /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ __attribute__ ((deprecated)) @interface FBSDKAppGroupJoinDialog : NSObject /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ + (instancetype)showWithGroupID:(NSString *)groupID delegate:(id)delegate __attribute__ ((deprecated)); /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ @property (nonatomic, weak) id delegate __attribute__ ((deprecated)); /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ @property (nonatomic, copy) NSString *groupID __attribute__ ((deprecated)); /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ - (BOOL)canShow __attribute__ ((deprecated)); /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ - (BOOL)show __attribute__ ((deprecated)); /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ - (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef __attribute__ ((deprecated)); @end /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ __attribute__ ((deprecated)) @protocol FBSDKAppGroupJoinDialogDelegate /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ - (void)appGroupJoinDialog:(FBSDKAppGroupJoinDialog *)appGroupJoinDialog didCompleteWithResults:(NSDictionary *)results __attribute__ ((deprecated)); /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ - (void)appGroupJoinDialog:(FBSDKAppGroupJoinDialog *)appGroupJoinDialog didFailWithError:(NSError *)error __attribute__ ((deprecated)); /*! @deprecated App and game groups are being deprecated. See https://developers.facebook.com/docs/games/services/game-groups for more information. */ - (void)appGroupJoinDialogDidCancel:(FBSDKAppGroupJoinDialog *)appGroupJoinDialog __attribute__ ((deprecated)); @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupJoinDialog.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAppGroupJoinDialog.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKShareConstants.h" #import "FBSDKShareError.h" #import "FBSDKShareUtility.h" @interface FBSDKAppGroupJoinDialog () @end @implementation FBSDKAppGroupJoinDialog { FBSDKWebDialog *_webDialog; } #define FBSDK_APP_GROUP_JOIN_METHOD_NAME @"game_group_join" #pragma mark - Class Methods + (instancetype)showWithGroupID:(NSString *)groupID delegate:(id)delegate { FBSDKAppGroupJoinDialog *dialog = [[self alloc] init]; dialog.groupID = groupID; dialog.delegate = delegate; [dialog show]; return dialog; } #pragma mark - Object Lifecycle - (instancetype)init { if ((self = [super init])) { _webDialog = [[FBSDKWebDialog alloc] init]; _webDialog.delegate = self; _webDialog.name = FBSDK_APP_GROUP_JOIN_METHOD_NAME; } return self; } - (void)dealloc { _webDialog.delegate = nil; } #pragma mark - Public Methods - (BOOL)canShow { return YES; } - (BOOL)show { NSError *error; if (![self canShow]) { error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode message:@"App group join dialog is not available."]; [_delegate appGroupJoinDialog:self didFailWithError:error]; return NO; } if (![self validateWithError:&error]) { [_delegate appGroupJoinDialog:self didFailWithError:error]; return NO; } NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:parameters setObject:self.groupID forKey:@"id"]; _webDialog.parameters = parameters; [_webDialog show]; [FBSDKInternalUtility registerTransientObject:self]; return YES; } - (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef { if (![self.groupID length]) { if (errorRef != NULL) { *errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"groupID" message:nil]; } return NO; } if (errorRef != NULL) { *errorRef = nil; } return YES; } #pragma mark - FBSDKWebDialogDelegate - (void)webDialog:(FBSDKWebDialog *)webDialog didCompleteWithResults:(NSDictionary *)results { if (_webDialog != webDialog) { return; } NSError *error = [FBSDKShareError errorWithCode:[FBSDKTypeUtility unsignedIntegerValue:results[@"error_code"]] message:[FBSDKTypeUtility stringValue:results[@"error_message"]]]; [self _handleCompletionWithDialogResults:results error:error]; [FBSDKInternalUtility unregisterTransientObject:self]; } - (void)webDialog:(FBSDKWebDialog *)webDialog didFailWithError:(NSError *)error { if (_webDialog != webDialog) { return; } [self _handleCompletionWithDialogResults:nil error:error]; [FBSDKInternalUtility unregisterTransientObject:self]; } - (void)webDialogDidCancel:(FBSDKWebDialog *)webDialog { if (_webDialog != webDialog) { return; } [_delegate appGroupJoinDialogDidCancel:self]; [FBSDKInternalUtility unregisterTransientObject:self]; } #pragma mark - Helper Methods - (void)_handleCompletionWithDialogResults:(NSDictionary *)results error:(NSError *)error { if (!_delegate) { return; } switch (error.code) { case 0:{ [_delegate appGroupJoinDialog:self didCompleteWithResults:results]; break; } case 4201:{ [_delegate appGroupJoinDialogDidCancel:self]; break; } default:{ [_delegate appGroupJoinDialog:self didFailWithError:error]; break; } } if (error) { return; } else { } } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKAppInviteContent.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /*! @typedef NS_ENUM(NSUInteger, FBSDKAppInviteDestination) @abstract Specifies the privacy of a group. */ typedef NS_ENUM(NSUInteger, FBSDKAppInviteDestination) { /*! Deliver to Facebook. */ FBSDKAppInviteDestinationFacebook = 0, /*! Deliver to Messenger. */ FBSDKAppInviteDestinationMessenger, }; /*! @abstract A model for app invite. */ @interface FBSDKAppInviteContent : NSObject /*! @abstract A URL to a preview image that will be displayed with the app invite @discussion This is optional. If you don't include it a fallback image will be used. */ @property (nonatomic, copy) NSURL *appInvitePreviewImageURL; /*! @abstract An app link target that will be used as a target when the user accept the invite. @discussion This is a requirement. */ @property (nonatomic, copy) NSURL *appLinkURL; /*! @deprecated Use `appInvitePreviewImageURL` instead. */ @property (nonatomic, copy) NSURL *previewImageURL __attribute__ ((deprecated("use appInvitePreviewImageURL instead"))); /*! @abstract Promotional code to be displayed while sending and receiving the invite. @discussion This is optional. This can be between 0 and 10 characters long and can contain alphanumeric characters only. To set a promo code, you need to set promo text. */ @property (nonatomic, copy) NSString *promotionCode; /*! @abstract Promotional text to be displayed while sending and receiving the invite. @discussion This is optional. This can be between 0 and 80 characters long and can contain alphanumeric and spaces only. */ @property (nonatomic, copy) NSString *promotionText; /*! @abstract Destination for the app invite. @discussion This is optional and for declaring destination of the invite. */ @property FBSDKAppInviteDestination destination; /*! @abstract Compares the receiver to another app invite content. @param content The other content @return YES if the receiver's values are equal to the other content's values; otherwise NO */ - (BOOL)isEqualToAppInviteContent:(FBSDKAppInviteContent *)content; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKAppInviteContent.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAppInviteContent.h" #import "FBSDKCoreKit+Internal.h" #define FBSDK_APP_INVITE_CONTENT_APP_LINK_URL_KEY @"appLinkURL" #define FBSDK_APP_INVITE_CONTENT_PREVIEW_IMAGE_KEY @"previewImage" #define FBSDK_APP_INVITE_CONTENT_PROMO_CODE_KEY @"promoCode" #define FBSDK_APP_INVITE_CONTENT_PROMO_TEXT_KEY @"promoText" #define FBSDK_APP_INVITE_CONTENT_DESTINATION_KEY @"destination" @implementation FBSDKAppInviteContent - (NSURL *)previewImageURL { return self.appInvitePreviewImageURL; } - (void)setPreviewImageURL:(NSURL *)previewImageURL { self.appInvitePreviewImageURL = previewImageURL; } #pragma mark - Equality - (NSUInteger)hash { NSUInteger subhashes[] = { [_appLinkURL hash], [_appInvitePreviewImageURL hash], [_promotionCode hash], [_promotionText hash], }; return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKAppInviteContent class]]) { return NO; } return [self isEqualToAppInviteContent:(FBSDKAppInviteContent *)object]; } - (BOOL)isEqualToAppInviteContent:(FBSDKAppInviteContent *)content { return (content && [FBSDKInternalUtility object:_appLinkURL isEqualToObject:content.appLinkURL] && [FBSDKInternalUtility object:_appInvitePreviewImageURL isEqualToObject:content.appInvitePreviewImageURL] && [FBSDKInternalUtility object:_promotionText isEqualToObject:content.promotionText] && [FBSDKInternalUtility object:_promotionCode isEqualToObject:content.promotionText] && _destination == content.destination ); } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [self init])) { _appLinkURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_APP_INVITE_CONTENT_APP_LINK_URL_KEY]; _appInvitePreviewImageURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_APP_INVITE_CONTENT_PREVIEW_IMAGE_KEY]; _promotionCode = [decoder decodeObjectOfClass:[NSString class] forKey: FBSDK_APP_INVITE_CONTENT_PROMO_CODE_KEY]; _promotionText = [decoder decodeObjectOfClass:[NSString class] forKey: FBSDK_APP_INVITE_CONTENT_PROMO_TEXT_KEY]; _destination = [decoder decodeIntegerForKey: FBSDK_APP_INVITE_CONTENT_DESTINATION_KEY]; } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_appLinkURL forKey:FBSDK_APP_INVITE_CONTENT_APP_LINK_URL_KEY]; [encoder encodeObject:_appInvitePreviewImageURL forKey:FBSDK_APP_INVITE_CONTENT_PREVIEW_IMAGE_KEY]; [encoder encodeObject:_promotionCode forKey:FBSDK_APP_INVITE_CONTENT_PROMO_CODE_KEY]; [encoder encodeObject:_promotionText forKey:FBSDK_APP_INVITE_CONTENT_PROMO_TEXT_KEY]; [encoder encodeInt:_destination forKey:FBSDK_APP_INVITE_CONTENT_DESTINATION_KEY]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { FBSDKAppInviteContent *copy = [[FBSDKAppInviteContent alloc] init]; copy->_appLinkURL = [_appLinkURL copy]; copy->_appInvitePreviewImageURL = [_appInvitePreviewImageURL copy]; copy->_promotionText = [_promotionText copy]; copy->_promotionCode = [_promotionCode copy]; copy->_destination = _destination; return copy; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKAppInviteDialog.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import @protocol FBSDKAppInviteDialogDelegate; /*! @abstract A dialog for sending App Invites. */ @interface FBSDKAppInviteDialog : NSObject /*! @abstract Convenience method to show a FBSDKAppInviteDialog @param viewController A UIViewController to present the dialog from. @param content The content for the app invite. @param delegate The receiver's delegate. */ + (instancetype)showFromViewController:(UIViewController *)viewController withContent:(FBSDKAppInviteContent *)content delegate:(id)delegate; /*! @deprecated use showFromViewController:withContent:delegate: instead */ + (instancetype)showWithContent:(FBSDKAppInviteContent *)content delegate:(id)delegate __attribute__ ((deprecated("use showFromViewController:withContent:delegate: instead"))); /*! @abstract A UIViewController to present the dialog from. @discussion If not specified, the top most view controller will be automatically determined as best as possible. */ @property (nonatomic, weak) UIViewController *fromViewController; /*! @abstract The receiver's delegate or nil if it doesn't have a delegate. */ @property (nonatomic, weak) id delegate; /*! @abstract The content for app invite. */ @property (nonatomic, copy) FBSDKAppInviteContent *content; /*! @abstract A Boolean value that indicates whether the receiver can initiate an app invite. @discussion May return NO if the appropriate Facebook app is not installed and is required or an access token is required but not available. This method does not validate the content on the receiver, so this can be checked before building up the content. @see validateWithError: @result YES if the receiver can show the dialog, otherwise NO. */ - (BOOL)canShow; /*! @abstract Begins the app invite from the receiver. @result YES if the receiver was able to show the dialog, otherwise NO. */ - (BOOL)show; /*! @abstract Validates the content on the receiver. @param errorRef If an error occurs, upon return contains an NSError object that describes the problem. @return YES if the content is valid, otherwise NO. */ - (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef; @end /*! @abstract A delegate for FBSDKAppInviteDialog. @discussion The delegate is notified with the results of the app invite as long as the application has permissions to receive the information. For example, if the person is not signed into the containing app, the shower may not be able to distinguish between completion of an app invite and cancellation. */ @protocol FBSDKAppInviteDialogDelegate /*! @abstract Sent to the delegate when the app invite completes without error. @param appInviteDialog The FBSDKAppInviteDialog that completed. @param results The results from the dialog. This may be nil or empty. */ - (void)appInviteDialog:(FBSDKAppInviteDialog *)appInviteDialog didCompleteWithResults:(NSDictionary *)results; /*! @abstract Sent to the delegate when the app invite encounters an error. @param appInviteDialog The FBSDKAppInviteDialog that completed. @param error The error. */ - (void)appInviteDialog:(FBSDKAppInviteDialog *)appInviteDialog didFailWithError:(NSError *)error; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKAppInviteDialog.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKAppInviteDialog.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKShareConstants.h" #import "FBSDKShareDefines.h" #import "FBSDKShareError.h" #import "FBSDKShareUtility.h" @implementation FBSDKAppInviteDialog #define FBSDK_APP_INVITE_METHOD_MIN_VERSION @"20140410" #define FBSDK_APP_INVITE_METHOD_NAME @"appinvites" + (void)initialize { if ([FBSDKAppInviteDialog class] == self) { [FBSDKInternalUtility checkRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_FACEBOOK]; // ensure that we have updated the dialog configs if we haven't already [FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL]; } } #pragma mark - Class Methods + (instancetype)showWithContent:(FBSDKAppInviteContent *)content delegate:(id)delegate { return [self showFromViewController:nil withContent:content delegate:delegate]; } + (instancetype)showFromViewController:(UIViewController *)viewController withContent:(FBSDKAppInviteContent *)content delegate:(id)delegate; { FBSDKAppInviteDialog *appInvite = [[self alloc] init]; appInvite.content = content; appInvite.delegate = delegate; appInvite.fromViewController = viewController; [appInvite show]; return appInvite; } #pragma mark - Public Methods - (BOOL)canShow { return YES; } - (BOOL)show { NSError *error; if (![self canShow]) { error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode message:@"App invite dialog is not available."]; [self _invokeDelegateDidFailWithError:error]; return NO; } if (![self validateWithError:&error]) { [self _invokeDelegateDidFailWithError:error]; return NO; } NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:parameters setObject:self.content.appLinkURL forKey:@"app_link_url"]; [FBSDKInternalUtility dictionary:parameters setObject:self.content.appInvitePreviewImageURL forKey:@"preview_image_url"]; NSString *destination; switch (self.content.destination) { case FBSDKAppInviteDestinationMessenger: destination = @"messenger"; break; case FBSDKAppInviteDestinationFacebook: destination = @"facebook"; break; default: destination = @"facebook"; break; } [FBSDKInternalUtility dictionary:parameters setObject:destination forKey:@"destination"]; if (self.content.promotionText) { NSString *promotionCode = self.content.promotionCode ?: @""; NSDictionary *deeplinkContext = @{@"promo_code" : promotionCode, @"promo_text" : self.content.promotionText}; NSError *jsonError = nil; NSString *deeplinkContextString = [FBSDKInternalUtility JSONStringForObject:deeplinkContext error:&jsonError invalidObjectHandler:NULL]; if (!jsonError) { [FBSDKInternalUtility dictionary:parameters setObject:promotionCode forKey:@"promo_code"]; [FBSDKInternalUtility dictionary:parameters setObject:self.content.promotionText forKey:@"promo_text"]; [FBSDKInternalUtility dictionary:parameters setObject:deeplinkContextString forKey:@"deeplink_context"]; } else { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors formatString:@"Cannot convert deeplink_contex to json:"]; } } FBSDKBridgeAPIRequest *webBridgeRequest = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeWeb scheme:FBSDK_SHARE_JS_DIALOG_SCHEME methodName:FBSDK_APP_INVITE_METHOD_NAME methodVersion:nil parameters:parameters userInfo:nil]; FBSDKBridgeAPICallbackBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) { [self _handleCompletionWithDialogResults:response.responseParameters error:response.error]; }; [self _logDialogShow]; FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration]; BOOL useSafariViewController = [configuration useSafariViewControllerForDialogName:FBSDKDialogConfigurationNameAppInvite]; if ([self _canShowNative]) { FBSDKBridgeAPIRequest *nativeRequest = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeNative scheme:FBSDK_CANOPENURL_FACEBOOK methodName:FBSDK_APP_INVITE_METHOD_NAME methodVersion:FBSDK_APP_INVITE_METHOD_MIN_VERSION parameters:parameters userInfo:nil]; void (^nativeCompletionBlock)(FBSDKBridgeAPIResponse *) = ^(FBSDKBridgeAPIResponse *response) { if (response.error.code == FBSDKAppVersionUnsupportedErrorCode) { [[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:webBridgeRequest useSafariViewController:useSafariViewController fromViewController:self.fromViewController completionBlock:completionBlock]; } else { completionBlock(response); } }; [[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:nativeRequest useSafariViewController:useSafariViewController fromViewController:self.fromViewController completionBlock:nativeCompletionBlock]; } else { [[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:webBridgeRequest useSafariViewController:useSafariViewController fromViewController:self.fromViewController completionBlock:completionBlock]; } return YES; } - (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef { return [FBSDKShareUtility validateAppInviteContent:self.content error:errorRef]; } #pragma mark - Helper Methods - (BOOL)_canShowNative { FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration]; BOOL useNativeDialog = [configuration useNativeDialogForDialogName:FBSDKDialogConfigurationNameAppInvite]; return (useNativeDialog && [FBSDKInternalUtility isFacebookAppInstalled]); } - (void)_handleCompletionWithDialogResults:(NSDictionary *)results error:(NSError *)error { if (error) { [self _invokeDelegateDidFailWithError:error]; } else { [self _invokeDelegateDidCompleteWithResults:results]; } } - (void)_invokeDelegateDidCompleteWithResults:(NSDictionary *)results { NSDictionary * parameters =@{ FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Completed, }; [FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventAppInviteShareDialogResult valueToSum:nil parameters:parameters accessToken:[FBSDKAccessToken currentAccessToken]]; if (!_delegate) { return; } [_delegate appInviteDialog:self didCompleteWithResults:[results copy]]; } - (void)_invokeDelegateDidFailWithError:(NSError *)error { NSDictionary * parameters =@{ FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Failed, FBSDKAppEventParameterDialogErrorMessage : [NSString stringWithFormat:@"%@", error] }; [FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventAppInviteShareDialogResult valueToSum:nil parameters:parameters accessToken:[FBSDKAccessToken currentAccessToken]]; if (!_delegate) { return; } [_delegate appInviteDialog:self didFailWithError:error]; } - (void)_logDialogShow { [FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventAppInviteShareDialogShow valueToSum:nil parameters:nil accessToken:[FBSDKAccessToken currentAccessToken]]; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestContent.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /*! @typedef NS_ENUM(NSUInteger, FBSDKGameRequestActionType) @abstract Additional context about the nature of the request. */ typedef NS_ENUM(NSUInteger, FBSDKGameRequestActionType) { /*! No action type */ FBSDKGameRequestActionTypeNone = 0, /*! Send action type: The user is sending an object to the friends. */ FBSDKGameRequestActionTypeSend, /*! Ask For action type: The user is asking for an object from friends. */ FBSDKGameRequestActionTypeAskFor, /*! Turn action type: It is the turn of the friends to play against the user in a match. (no object) */ FBSDKGameRequestActionTypeTurn, }; /*! @typedef NS_ENUM(NSUInteger, FBSDKGameRequestFilters) @abstract Filter for who can be displayed in the multi-friend selector. */ typedef NS_ENUM(NSUInteger, FBSDKGameRequestFilter) { /*! No filter, all friends can be displayed. */ FBSDKGameRequestFilterNone = 0, /*! Friends using the app can be displayed. */ FBSDKGameRequestFilterAppUsers, /*! Friends not using the app can be displayed. */ FBSDKGameRequestFilterAppNonUsers, }; /*! @abstract A model for a game request. */ @interface FBSDKGameRequestContent : NSObject /*! @abstract Used when defining additional context about the nature of the request. @discussion The parameter 'objectID' is required if the action type is either 'FBSDKGameRequestSendActionType' or 'FBSDKGameRequestAskForActionType'. @seealso objectID */ @property (nonatomic, assign) FBSDKGameRequestActionType actionType; /*! @abstract Compares the receiver to another game request content. @param content The other content @return YES if the receiver's values are equal to the other content's values; otherwise NO */ - (BOOL)isEqualToGameRequestContent:(FBSDKGameRequestContent *)content; /*! @abstract Additional freeform data you may pass for tracking. This will be stored as part of the request objects created. The maximum length is 255 characters. */ @property (nonatomic, copy) NSString *data; /*! @abstract This controls the set of friends someone sees if a multi-friend selector is shown. It is FBSDKGameRequestNoFilter by default, meaning that all friends can be shown. If specify as FBSDKGameRequestAppUsersFilter, only friends who use the app will be shown. On the other hands, use FBSDKGameRequestAppNonUsersFilter to filter only friends who do not use the app. @discussion The parameter name is preserved to be consistent with the counter part on desktop. */ @property (nonatomic, assign) FBSDKGameRequestFilter filters; /*! @abstract A plain-text message to be sent as part of the request. This text will surface in the App Center view of the request, but not on the notification jewel. Required parameter. */ @property (nonatomic, copy) NSString *message; /*! @abstract The Open Graph object ID of the object being sent. @seealso actionType */ @property (nonatomic, copy) NSString *objectID; /*! @abstract An array of user IDs, usernames or invite tokens (NSString) of people to send request. @discussion These may or may not be a friend of the sender. If this is specified by the app, the sender will not have a choice of recipients. If not, the sender will see a multi-friend selector This is equivalent to the "to" parameter when using the web game request dialog. */ @property (nonatomic, copy) NSArray *recipients; /*! @abstract An array of user IDs that will be included in the dialog as the first suggested friends. Cannot be used together with filters. @discussion This is equivalent to the "suggestions" parameter when using the web game request dialog. */ @property (nonatomic, copy) NSArray *recipientSuggestions; /*! @deprecated Use `recipientSuggestions` instead. */ @property (nonatomic, copy) NSArray *suggestions __attribute__ ((deprecated("use recipientSuggestions instead"))); /*! @abstract The title for the dialog. */ @property (nonatomic, copy) NSString *title; /*! @deprecated Use `recipients` instead. */ @property (nonatomic, copy) NSArray *to __attribute__ ((deprecated("use recipients instead"))); @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestContent.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKGameRequestContent.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKShareUtility.h" #define FBSDK_APP_REQUEST_CONTENT_TO_KEY @"to" #define FBSDK_APP_REQUEST_CONTENT_MESSAGE_KEY @"message" #define FBSDK_APP_REQUEST_CONTENT_ACTION_TYPE_KEY @"actionType" #define FBSDK_APP_REQUEST_CONTENT_OBJECT_ID_KEY @"objectID" #define FBSDK_APP_REQUEST_CONTENT_FILTERS_KEY @"filters" #define FBSDK_APP_REQUEST_CONTENT_SUGGESTIONS_KEY @"suggestions" #define FBSDK_APP_REQUEST_CONTENT_DATA_KEY @"data" #define FBSDK_APP_REQUEST_CONTENT_TITLE_KEY @"title" @implementation FBSDKGameRequestContent #pragma mark - Properties -(void)setRecipients:(NSArray *)recipients { [FBSDKShareUtility assertCollection:recipients ofClass:[NSString class] name:@"recipients"]; if (![_recipients isEqual:recipients]) { _recipients = [recipients copy]; } } - (void)setRecipientSuggestions:(NSArray *)recipientSuggestions { [FBSDKShareUtility assertCollection:recipientSuggestions ofClass:[NSString class] name:@"recipientSuggestions"]; if (![_recipientSuggestions isEqual:recipientSuggestions]) { _recipientSuggestions = [recipientSuggestions copy]; } } - (NSArray *)suggestions { return self.recipientSuggestions; } - (void)setSuggestions:(NSArray *)suggestions { self.recipientSuggestions = suggestions; } - (NSArray *)to { return self.recipients; } - (void)setTo:(NSArray *)to { self.recipients = to; } #pragma mark - Equality - (NSUInteger)hash { NSUInteger subhashes[] = { [FBSDKMath hashWithInteger:_actionType], [_data hash], [FBSDKMath hashWithInteger:_filters], [_message hash], [_objectID hash], [_recipientSuggestions hash], [_title hash], [_recipients hash], }; return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKGameRequestContent class]]) { return NO; } return [self isEqualToGameRequestContent:(FBSDKGameRequestContent *)object]; } - (BOOL)isEqualToGameRequestContent:(FBSDKGameRequestContent *)content { return (content && _actionType == content.actionType && _filters == content.filters && [FBSDKInternalUtility object:_data isEqualToObject:content.data] && [FBSDKInternalUtility object:_message isEqualToObject:content.message] && [FBSDKInternalUtility object:_objectID isEqualToObject:content.objectID] && [FBSDKInternalUtility object:_recipientSuggestions isEqualToObject:content.recipientSuggestions] && [FBSDKInternalUtility object:_title isEqualToObject:content.title] && [FBSDKInternalUtility object:_recipients isEqualToObject:content.recipients]); } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [self init])) { _actionType = [decoder decodeIntegerForKey:FBSDK_APP_REQUEST_CONTENT_ACTION_TYPE_KEY]; _data = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_APP_REQUEST_CONTENT_DATA_KEY]; _filters = [decoder decodeIntegerForKey:FBSDK_APP_REQUEST_CONTENT_FILTERS_KEY]; _message = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_APP_REQUEST_CONTENT_MESSAGE_KEY]; _objectID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_APP_REQUEST_CONTENT_OBJECT_ID_KEY]; _recipientSuggestions = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_APP_REQUEST_CONTENT_SUGGESTIONS_KEY]; _title = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_APP_REQUEST_CONTENT_TITLE_KEY]; _recipients = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_APP_REQUEST_CONTENT_TO_KEY]; } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeInteger:_actionType forKey:FBSDK_APP_REQUEST_CONTENT_ACTION_TYPE_KEY]; [encoder encodeObject:_data forKey:FBSDK_APP_REQUEST_CONTENT_DATA_KEY]; [encoder encodeInteger:_filters forKey:FBSDK_APP_REQUEST_CONTENT_FILTERS_KEY]; [encoder encodeObject:_message forKey:FBSDK_APP_REQUEST_CONTENT_MESSAGE_KEY]; [encoder encodeObject:_objectID forKey:FBSDK_APP_REQUEST_CONTENT_OBJECT_ID_KEY]; [encoder encodeObject:_recipientSuggestions forKey:FBSDK_APP_REQUEST_CONTENT_SUGGESTIONS_KEY]; [encoder encodeObject:_title forKey:FBSDK_APP_REQUEST_CONTENT_TITLE_KEY]; [encoder encodeObject:_recipients forKey:FBSDK_APP_REQUEST_CONTENT_TO_KEY]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { FBSDKGameRequestContent *copy = [[FBSDKGameRequestContent alloc] init]; copy->_actionType = _actionType; copy->_data = [_data copy]; copy->_filters = _filters; copy->_message = [_message copy]; copy->_objectID = [_objectID copy]; copy->_recipientSuggestions = [_recipientSuggestions copy]; copy->_title = [_title copy]; copy->_recipients = [_recipients copy]; return copy; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestDialog.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @protocol FBSDKGameRequestDialogDelegate; /*! @abstract A dialog for sending game requests. */ @interface FBSDKGameRequestDialog : NSObject /*! @abstract Convenience method to build up a game request with content and a delegate. @param content The content for the game request. @param delegate The receiver's delegate. */ + (instancetype)showWithContent:(FBSDKGameRequestContent *)content delegate:(id)delegate; /*! @abstract The receiver's delegate or nil if it doesn't have a delegate. */ @property (nonatomic, weak) id delegate; /*! @abstract The content for game request. */ @property (nonatomic, copy) FBSDKGameRequestContent *content; /*! @abstract Specifies whether frictionless requests are enabled. */ @property (nonatomic, assign) BOOL frictionlessRequestsEnabled; /*! @abstract A Boolean value that indicates whether the receiver can initiate a game request. @discussion May return NO if the appropriate Facebook app is not installed and is required or an access token is required but not available. This method does not validate the content on the receiver, so this can be checked before building up the content. @see validateWithError: @result YES if the receiver can share, otherwise NO. */ - (BOOL)canShow; /*! @abstract Begins the game request from the receiver. @result YES if the receiver was able to show the dialog, otherwise NO. */ - (BOOL)show; /*! @abstract Validates the content on the receiver. @param errorRef If an error occurs, upon return contains an NSError object that describes the problem. @return YES if the content is valid, otherwise NO. */ - (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef; @end /*! @abstract A delegate for FBSDKGameRequestDialog. @discussion The delegate is notified with the results of the game request as long as the application has permissions to receive the information. For example, if the person is not signed into the containing app, the shower may not be able to distinguish between completion of a game request and cancellation. */ @protocol FBSDKGameRequestDialogDelegate /*! @abstract Sent to the delegate when the game request completes without error. @param gameRequestDialog The FBSDKGameRequestDialog that completed. @param results The results from the dialog. This may be nil or empty. */ - (void)gameRequestDialog:(FBSDKGameRequestDialog *)gameRequestDialog didCompleteWithResults:(NSDictionary *)results; /*! @abstract Sent to the delegate when the game request encounters an error. @param gameRequestDialog The FBSDKGameRequestDialog that completed. @param error The error. */ - (void)gameRequestDialog:(FBSDKGameRequestDialog *)gameRequestDialog didFailWithError:(NSError *)error; /*! @abstract Sent to the delegate when the game request dialog is cancelled. @param gameRequestDialog The FBSDKGameRequestDialog that completed. */ - (void)gameRequestDialogDidCancel:(FBSDKGameRequestDialog *)gameRequestDialog; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestDialog.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKGameRequestDialog.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKGameRequestFrictionlessRecipientCache.h" #import "FBSDKShareConstants.h" #import "FBSDKShareError.h" #import "FBSDKShareUtility.h" @interface FBSDKGameRequestDialog () @end @implementation FBSDKGameRequestDialog { BOOL _dialogIsFrictionless; FBSDKWebDialog *_webDialog; } #define FBSDK_APP_REQUEST_METHOD_NAME @"apprequests" #pragma mark - Class Methods static FBSDKGameRequestFrictionlessRecipientCache *_recipientCache = nil; + (void)initialize { if (self == [FBSDKGameRequestDialog class]) { _recipientCache = [[FBSDKGameRequestFrictionlessRecipientCache alloc] init]; } } + (instancetype)showWithContent:(FBSDKGameRequestContent *)content delegate:(id)delegate { FBSDKGameRequestDialog *dialog = [[self alloc] init]; dialog.content = content; dialog.delegate = delegate; [dialog show]; return dialog; } #pragma mark - Object Lifecycle - (instancetype)init { if ((self = [super init])) { _webDialog = [[FBSDKWebDialog alloc] init]; _webDialog.delegate = self; _webDialog.name = FBSDK_APP_REQUEST_METHOD_NAME; } return self; } - (void)dealloc { _webDialog.delegate = nil; } #pragma mark - Public Methods - (BOOL)canShow { return YES; } - (BOOL)show { NSError *error; if (![self canShow]) { error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode message:@"Game request dialog is not available."]; [_delegate gameRequestDialog:self didFailWithError:error]; return NO; } if (![self validateWithError:&error]) { [_delegate gameRequestDialog:self didFailWithError:error]; return NO; } FBSDKGameRequestContent *content = self.content; if (error) { return NO; } NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:parameters setObject:[content.recipients componentsJoinedByString:@","] forKey:@"to"]; [FBSDKInternalUtility dictionary:parameters setObject:content.message forKey:@"message"]; [FBSDKInternalUtility dictionary:parameters setObject:[self _actionTypeNameForActionType:content.actionType] forKey:@"action_type"]; [FBSDKInternalUtility dictionary:parameters setObject:content.objectID forKey:@"object_id"]; [FBSDKInternalUtility dictionary:parameters setObject:[self _filtersNameForFilters:content.filters] forKey:@"filters"]; [FBSDKInternalUtility dictionary:parameters setObject:[content.recipientSuggestions componentsJoinedByString:@","] forKey:@"suggestions"]; [FBSDKInternalUtility dictionary:parameters setObject:content.data forKey:@"data"]; [FBSDKInternalUtility dictionary:parameters setObject:content.title forKey:@"title"]; // check if we are sending to a specific set of recipients. if we are and they are all frictionless recipients, we // can perform this action without displaying the web dialog _webDialog.deferVisibility = NO; NSArray *recipients = content.recipients; if (_frictionlessRequestsEnabled && recipients) { // specify these parameters to get the frictionless recipients from the dialog when it is presented parameters[@"frictionless"] = @YES; parameters[@"get_frictionless_recipients"] = @YES; _dialogIsFrictionless = YES; if ([_recipientCache recipientsAreFrictionless:recipients]) { _webDialog.deferVisibility = YES; } } _webDialog.parameters = parameters; [_webDialog show]; [FBSDKInternalUtility registerTransientObject:self]; return YES; } - (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef { return [FBSDKShareUtility validateGameRequestContent:self.content error:errorRef]; } #pragma mark - FBSDKWebDialogDelegate - (void)webDialog:(FBSDKWebDialog *)webDialog didCompleteWithResults:(NSDictionary *)results { if (_webDialog != webDialog) { return; } if (_dialogIsFrictionless && results) { [_recipientCache updateWithResults:results]; } [self _cleanUp]; NSError *error = [FBSDKShareError errorWithCode:[FBSDKTypeUtility unsignedIntegerValue:results[@"error_code"]] message:[FBSDKTypeUtility stringValue:results[@"error_message"]]]; if (!error.code) { // reformat "to[x]" keys into an array. int counter = 0; NSMutableArray *toArray = [NSMutableArray array]; while (true) { NSString *key = [NSString stringWithFormat:@"to[%d]", counter++]; if (results[key]) { [toArray addObject:results[key]]; } else { break; } } if (toArray.count) { NSMutableDictionary *mutableResults = [results mutableCopy]; mutableResults[@"to"] = toArray; results = mutableResults; } } [self _handleCompletionWithDialogResults:results error:error]; [FBSDKInternalUtility unregisterTransientObject:self]; } - (void)webDialog:(FBSDKWebDialog *)webDialog didFailWithError:(NSError *)error { if (_webDialog != webDialog) { return; } [self _cleanUp]; [self _handleCompletionWithDialogResults:nil error:error]; [FBSDKInternalUtility unregisterTransientObject:self]; } - (void)webDialogDidCancel:(FBSDKWebDialog *)webDialog { if (_webDialog != webDialog) { return; } [self _cleanUp]; [_delegate gameRequestDialogDidCancel:self]; [FBSDKInternalUtility unregisterTransientObject:self]; } #pragma mark - Helper Methods - (void)_cleanUp { _dialogIsFrictionless = NO; } - (void)_handleCompletionWithDialogResults:(NSDictionary *)results error:(NSError *)error { if (!_delegate) { return; } switch (error.code) { case 0:{ [_delegate gameRequestDialog:self didCompleteWithResults:results]; break; } case 4201:{ [_delegate gameRequestDialogDidCancel:self]; break; } default:{ [_delegate gameRequestDialog:self didFailWithError:error]; break; } } if (error) { return; } else { } } - (NSString *)_actionTypeNameForActionType:(FBSDKGameRequestActionType)actionType { switch (actionType) { case FBSDKGameRequestActionTypeNone:{ return nil; } case FBSDKGameRequestActionTypeSend:{ return @"send"; } case FBSDKGameRequestActionTypeAskFor:{ return @"askfor"; } case FBSDKGameRequestActionTypeTurn:{ return @"turn"; } default:{ return nil; } } } - (NSString *)_filtersNameForFilters:(FBSDKGameRequestFilter)filters { switch (filters) { case FBSDKGameRequestFilterNone:{ return nil; } case FBSDKGameRequestFilterAppUsers:{ return @"app_users"; } case FBSDKGameRequestFilterAppNonUsers:{ return @"app_non_users"; } default:{ return nil; } } } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKHashtag.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /*! @abstract Represents a single hashtag that can be used with the share dialog. */ @interface FBSDKHashtag : NSObject /*! @abstract Convenience method to build a new hashtag with a string identifier. Equivalent to setting the `stringRepresentation` property. @param hashtagString The hashtag string. */ + (instancetype)hashtagWithString:(NSString *)hashtagString; /*! @abstract The hashtag string. @discussion You are responsible for making sure that `stringRepresentation` is a valid hashtag (a single '#' followed by one or more word characters). Invalid hashtags are ignored when sharing content. You can check validity with the `valid` property. @return The hashtag string. */ @property (nonatomic, readwrite, copy) NSString *stringRepresentation; /*! @abstract Tests if a hashtag is valid. @discussion A valid hashtag matches the regular expression "#\w+": A single '#' followed by one or more word characters. @return YES if the hashtag is valid, NO otherwise. */ @property (nonatomic, readonly, assign, getter=isValid) BOOL valid; /*! @abstract Compares the receiver to another hashtag. @param hashtag The other hashtag @return YES if the receiver is equal to the other hashtag; otherwise NO */ - (BOOL)isEqualToHashtag:(FBSDKHashtag *)hashtag; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKHashtag.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKHashtag.h" #import "FBSDKCoreKit+Internal.h" #define FBSDK_HASHTAG_STRING_KEY @"hashtag" static NSRegularExpression *HashtagRegularExpression() { static NSRegularExpression *hashtagRegularExpression = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ hashtagRegularExpression = [[NSRegularExpression alloc] initWithPattern:@"^#\\w+$" options:0 error:NULL]; }); return hashtagRegularExpression; } @implementation FBSDKHashtag #pragma mark - Class Methods + (instancetype)hashtagWithString:(NSString *)hashtagString { FBSDKHashtag *hashtag = [[self alloc] init]; hashtag.stringRepresentation = hashtagString; return hashtag; } #pragma mark - Properties - (NSString *)description { if (self.valid) { return _stringRepresentation; } else { return [NSString stringWithFormat:@"Invalid hashtag '%@'", _stringRepresentation]; } } - (BOOL)isValid { if (_stringRepresentation == nil) { return NO; } NSRange fullString = NSMakeRange(0, _stringRepresentation.length); NSRegularExpression *hashtagRegularExpression = HashtagRegularExpression(); NSUInteger numberOfMatches = [hashtagRegularExpression numberOfMatchesInString:_stringRepresentation options:0 range:fullString]; return numberOfMatches > 0; } #pragma mark - Equality - (NSUInteger)hash { return [_stringRepresentation hash]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKHashtag class]]) { return NO; } return [self isEqualToHashtag:(FBSDKHashtag *)object]; } - (BOOL)isEqualToHashtag:(FBSDKHashtag *)hashtag { return (hashtag && [FBSDKInternalUtility object:_stringRepresentation isEqualToObject:hashtag.stringRepresentation]); } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)aDecoder { if ((self = [self init])) { _stringRepresentation = [aDecoder decodeObjectOfClass:[NSString class] forKey:FBSDK_HASHTAG_STRING_KEY]; } return self; } - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:_stringRepresentation forKey:FBSDK_HASHTAG_STRING_KEY]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { FBSDKHashtag *copy = [[FBSDKHashtag alloc] init]; copy.stringRepresentation = [_stringRepresentation copy]; return copy; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKLikeButton.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import /*! @abstract A button to like an object. @discussion Tapping the receiver will invoke an API call to the Facebook app through a fast-app-switch that allows the object to be liked. Upon return to the calling app, the view will update with the new state. If the currentAccessToken has "publish_actions" permission and the object is an Open Graph object, then the like can happen seamlessly without the fast-app-switch. */ @interface FBSDKLikeButton : FBSDKButton /*! @abstract If YES, a sound is played when the receiver is toggled. @default YES */ @property (nonatomic, assign, getter = isSoundEnabled) BOOL soundEnabled; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKLikeButton.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLikeButton.h" #import "FBSDKLikeButton+Internal.h" #import "FBSDKCheckmarkIcon.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKLikeActionController.h" #import "FBSDKLikeControl+Internal.h" #define FBSDK_LIKE_BUTTON_ANIMATION_DURATION 0.2 #define FBSDK_LIKE_BUTTON_ANIMATION_SPRING_DAMPING 0.3 #define FBSDK_LIKE_BUTTON_ANIMATION_SPRING_VELOCITY 0.2 @implementation FBSDKLikeButton { BOOL _isExplicitlyDisabled; FBSDKLikeActionController *_likeActionController; NSString *_objectID; FBSDKLikeObjectType _objectType; } #pragma mark - Class Methods + (void)initialize { if ([FBSDKLikeButton class] == self) { // ensure that we have updated the dialog configs if we haven't already [FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL]; } } #pragma mark - Object Lifecycle - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [_likeActionController endContentAccess]; } #pragma mark - Properties - (FBSDKLikeActionController *)likeActionController { [self _ensureLikeActionController:NO]; return _likeActionController; } - (void)setLikeActionController:(FBSDKLikeActionController *)likeActionController { [self _setLikeActionController:likeActionController]; } - (NSString *)objectID { return _objectID; } - (void)setObjectID:(NSString *)objectID { if (![_objectID isEqualToString:objectID]) { _objectID = objectID; [self checkImplicitlyDisabled]; [self _resetLikeActionController]; } } - (FBSDKLikeObjectType)objectType { return _objectType; } - (void)setObjectType:(FBSDKLikeObjectType)objectType { if (_objectType != objectType) { _objectType = objectType; [self _resetLikeActionController]; } } #pragma mark - Layout - (void)layoutSubviews { [self _ensureLikeActionController:YES]; [super layoutSubviews]; } #pragma mark - FBSDKButtonImpressionTracking - (NSDictionary *)analyticsParameters { UIView *superview = self.superview; while (superview && ![superview isKindOfClass:[FBSDKLikeControl class]]) { superview = superview.superview; } if ([superview isKindOfClass:[FBSDKLikeControl class]]) { return ((FBSDKLikeControl *)superview).analyticsParameters; } return @{ @"object_id": (self.objectID ?: [NSNull null]), @"object_type": (NSStringFromFBSDKLikeObjectType(self.objectType) ?: [NSNull null]), @"sound_enabled": @(self.soundEnabled), }; } - (NSString *)impressionTrackingEventName { return FBSDKAppEventNameFBSDKLikeButtonImpression; } - (NSString *)impressionTrackingIdentifier { return self.objectID; } #pragma mark - FBSDKButton - (void)configureButton { self.soundEnabled = YES; NSString *title = NSLocalizedStringWithDefaultValue(@"LikeButton.Like", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Like", @"The label for the FBSDKLikeButton when the object is not currently liked."); NSString *selectedTitle = NSLocalizedStringWithDefaultValue(@"LikeButton.Liked", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Liked", @"The label for the FBSDKLikeButton when the object is currently liked."); UIColor *backgroundColor = [self defaultBackgroundColor]; UIColor *highlightedColor = [self defaultHighlightedColor]; UIColor *selectedColor = [self defaultSelectedColor]; UIColor *selectedHighlightedColor = [UIColor colorWithRed:99.0/255.0 green:119.0/255.0 blue:178.0/255.0 alpha:1.0]; [self configureWithIcon:nil title:title backgroundColor:backgroundColor highlightedColor:highlightedColor selectedTitle:selectedTitle selectedIcon:[[FBSDKCheckmarkIcon alloc] init] selectedColor:selectedColor selectedHighlightedColor:selectedHighlightedColor]; [self addTarget:self action:@selector(_handleTap:) forControlEvents:UIControlEventTouchUpInside]; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(_likeActionControllerDidDisableNotification:) name:FBSDKLikeActionControllerDidDisableNotification object:nil]; [nc addObserver:self selector:@selector(_likeActionControllerDidResetNotification:) name:FBSDKLikeActionControllerDidResetNotification object:nil]; [nc addObserver:self selector:@selector(_likeActionControllerDidUpdateNotification:) name:FBSDKLikeActionControllerDidUpdateNotification object:nil]; } - (BOOL)isImplicitlyDisabled { return !self.objectID || [FBSDKLikeActionController isDisabled]; } #pragma mark - Helper Methods - (void)_ensureLikeActionController:(BOOL)notifyKVO { if (!_likeActionController) { FBSDKLikeActionController *likeActionController = [FBSDKLikeActionController likeActionControllerForObjectID:_objectID objectType:_objectType]; if (notifyKVO) { self.likeActionController = likeActionController; } else { [self _setLikeActionController:likeActionController]; } [likeActionController endContentAccess]; self.selected = _likeActionController.objectIsLiked; } } - (void)_handleTap:(FBSDKLikeButton *)likeButton { [self logTapEventWithEventName:FBSDKAppEventNameFBSDKLikeButtonDidTap parameters:[self analyticsParameters]]; [self _ensureLikeActionController:YES]; [_likeActionController toggleLikeWithSoundEnabled:self.soundEnabled analyticsParameters:[self analyticsParameters] fromViewController:[FBSDKInternalUtility viewControllerForView:self]]; } - (void)_like:(id)sender { [_likeActionController toggleLikeWithSoundEnabled:_soundEnabled analyticsParameters:[self analyticsParameters] fromViewController:[FBSDKInternalUtility viewControllerForView:self]]; } - (void)_likeActionControllerDidDisableNotification:(NSNotification *)notification { [self checkImplicitlyDisabled]; } - (void)_likeActionControllerDidResetNotification:(NSNotification *)notification { [self _resetLikeActionController]; [self _ensureLikeActionController:YES]; } - (void)_likeActionControllerDidUpdateNotification:(NSNotification *)notification { [self _ensureLikeActionController:YES]; FBSDKLikeActionController *likeActionController = (FBSDKLikeActionController *)notification.object; NSString *objectID = likeActionController.objectID; if ([self.objectID isEqualToString:objectID]) { BOOL animated = [notification.userInfo[FBSDKLikeActionControllerAnimatedKey] boolValue]; [self _setSelected:likeActionController.objectIsLiked animated:animated]; } } - (void)_resetLikeActionController { self.likeActionController = nil; [self setNeedsLayout]; } - (void)_setLikeActionController:(FBSDKLikeActionController *)likeActionController { if (_likeActionController != likeActionController) { [_likeActionController endContentAccess]; _likeActionController = likeActionController; [_likeActionController beginContentAccess]; } } - (void)_setSelected:(BOOL)selected animated:(BOOL)animated { if (self.selected != selected) { if (animated) { CFTimeInterval duration = FBSDK_LIKE_BUTTON_ANIMATION_DURATION; UIViewAnimationOptions options = UIViewAnimationOptionBeginFromCurrentState; UIImageView *imageView = self.imageView; imageView.frame = [self imageRectForContentRect:UIEdgeInsetsInsetRect(self.bounds, self.contentEdgeInsets)]; [UIView animateWithDuration:duration delay:0.0 options:options animations:^{ CGPoint iconImageViewCenter = imageView.center; imageView.frame = CGRectMake(iconImageViewCenter.x, iconImageViewCenter.y, 0.0, 0.0); } completion:^(BOOL animateOutFinished) { self.selected = selected; CGPoint iconImageViewCenter = imageView.center; imageView.frame = CGRectMake(iconImageViewCenter.x, iconImageViewCenter.y, 0.0, 0.0); void(^animations)(void) = ^{ imageView.frame = [self imageRectForContentRect:UIEdgeInsetsInsetRect(self.bounds, self.contentEdgeInsets)]; }; if ([UIView respondsToSelector:@selector(animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:)]) { [UIView animateWithDuration:(duration * 2) delay:0.0 usingSpringWithDamping:FBSDK_LIKE_BUTTON_ANIMATION_SPRING_DAMPING initialSpringVelocity:FBSDK_LIKE_BUTTON_ANIMATION_SPRING_VELOCITY options:options animations:animations completion:NULL]; } else { [UIView animateWithDuration:(duration * 2) delay:0.0 options:options animations:animations completion:NULL]; } }]; } else { self.selected = selected; } } } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKLikeControl.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import /*! @typedef NS_ENUM (NSUInteger, FBSDKLikeControlAuxiliaryPosition) @abstract Specifies the position of the auxiliary view relative to the like button. */ typedef NS_ENUM(NSUInteger, FBSDKLikeControlAuxiliaryPosition) { /*! The auxiliary view is inline with the like button. */ FBSDKLikeControlAuxiliaryPositionInline, /*! The auxiliary view is above the like button. */ FBSDKLikeControlAuxiliaryPositionTop, /*! The auxiliary view is below the like button. */ FBSDKLikeControlAuxiliaryPositionBottom, }; /*! @abstract Converts an FBSDKLikeControlAuxiliaryPosition to an NSString. */ FBSDK_EXTERN NSString *NSStringFromFBSDKLikeControlAuxiliaryPosition(FBSDKLikeControlAuxiliaryPosition auxiliaryPosition); /*! @typedef NS_ENUM(NSUInteger, FBSDKLikeControlHorizontalAlignment) @abstract Specifies the horizontal alignment for FBSDKLikeControlStyleStandard with FBSDKLikeControlAuxiliaryPositionTop or FBSDKLikeControlAuxiliaryPositionBottom. */ typedef NS_ENUM(NSUInteger, FBSDKLikeControlHorizontalAlignment) { /*! The subviews are left aligned. */ FBSDKLikeControlHorizontalAlignmentLeft, /*! The subviews are center aligned. */ FBSDKLikeControlHorizontalAlignmentCenter, /*! The subviews are right aligned. */ FBSDKLikeControlHorizontalAlignmentRight, }; /*! @abstract Converts an FBSDKLikeControlHorizontalAlignment to an NSString. */ FBSDK_EXTERN NSString *NSStringFromFBSDKLikeControlHorizontalAlignment(FBSDKLikeControlHorizontalAlignment horizontalAlignment); /*! @typedef NS_ENUM (NSUInteger, FBSDKLikeControlStyle) @abstract Specifies the style of a like control. */ typedef NS_ENUM(NSUInteger, FBSDKLikeControlStyle) { /*! Displays the button and the social sentence. */ FBSDKLikeControlStyleStandard = 0, /*! Displays the button and a box that contains the like count. */ FBSDKLikeControlStyleBoxCount, }; /*! @abstract Converts an FBSDKLikeControlStyle to an NSString. */ FBSDK_EXTERN NSString *NSStringFromFBSDKLikeControlStyle(FBSDKLikeControlStyle style); /*! @class FBSDKLikeControl @abstract UI control to like an object in the Facebook graph. @discussion Taps on the like button within this control will invoke an API call to the Facebook app through a fast-app-switch that allows the user to like the object. Upon return to the calling app, the view will update with the new state and send actions for the UIControlEventValueChanged event. */ @interface FBSDKLikeControl : UIControl /*! @abstract The foreground color to use for the content of the receiver. */ @property (nonatomic, strong) UIColor *foregroundColor; /*! @abstract The position for the auxiliary view for the receiver. @see FBSDKLikeControlAuxiliaryPosition */ @property (nonatomic, assign) FBSDKLikeControlAuxiliaryPosition likeControlAuxiliaryPosition; /*! @abstract The text alignment of the social sentence. @discussion This value is only valid for FBSDKLikeControlStyleStandard with FBSDKLikeControlAuxiliaryPositionTop|Bottom. */ @property (nonatomic, assign) FBSDKLikeControlHorizontalAlignment likeControlHorizontalAlignment; /*! @abstract The style to use for the receiver. @see FBSDKLikeControlStyle */ @property (nonatomic, assign) FBSDKLikeControlStyle likeControlStyle; /*! @abstract The preferred maximum width (in points) for autolayout. @discussion This property affects the size of the receiver when layout constraints are applied to it. During layout, if the text extends beyond the width specified by this property, the additional text is flowed to one or more new lines, thereby increasing the height of the receiver. */ @property (nonatomic, assign) CGFloat preferredMaxLayoutWidth; /*! @abstract If YES, a sound is played when the receiver is toggled. @default YES */ @property (nonatomic, assign, getter = isSoundEnabled) BOOL soundEnabled; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKLikeControl.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLikeControl.h" #import "FBSDKLikeControl+Internal.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKLikeActionController.h" #import "FBSDKLikeBoxView.h" #import "FBSDKLikeButton+Internal.h" #import "FBSDKLikeButton.h" #define kFBLikeControlAnimationDuration 0.2 #define kFBLikeControlSocialSentenceAnimationOffset 10.0 static void *FBSDKLikeControlKVOLikeActionControllerContext = &FBSDKLikeControlKVOLikeActionControllerContext; NSString *NSStringFromFBSDKLikeControlAuxiliaryPosition(FBSDKLikeControlAuxiliaryPosition auxiliaryPosition) { switch (auxiliaryPosition) { case FBSDKLikeControlAuxiliaryPositionBottom: return @"bottom"; case FBSDKLikeControlAuxiliaryPositionInline: return @"inline"; case FBSDKLikeControlAuxiliaryPositionTop: return @"top"; } return nil; } NSString *NSStringFromFBSDKLikeControlHorizontalAlignment(FBSDKLikeControlHorizontalAlignment horizontalAlignment) { switch (horizontalAlignment) { case FBSDKLikeControlHorizontalAlignmentCenter: return @"center"; case FBSDKLikeControlHorizontalAlignmentLeft: return @"left"; case FBSDKLikeControlHorizontalAlignmentRight: return @"right"; } return nil; } NSString *NSStringFromFBSDKLikeControlStyle(FBSDKLikeControlStyle style) { switch (style) { case FBSDKLikeControlStyleBoxCount: return @"box_count"; case FBSDKLikeControlStyleStandard: return @"standard"; } return nil; } typedef struct FBSDKLikeControlLayout { CGSize contentSize; CGRect likeButtonFrame; CGRect auxiliaryViewFrame; } FBSDKLikeControlLayout; typedef CGSize (^fbsdk_like_control_sizing_block_t)(UIView *subview, CGSize constrainedSize); @implementation FBSDKLikeControl { BOOL _isExplicitlyDisabled; FBSDKLikeBoxView *_likeBoxView; FBSDKLikeButton *_likeButton; UIView *_likeButtonContainer; UILabel *_socialSentenceLabel; } #pragma mark - Class Methods + (void)initialize { if ([FBSDKLikeControl class] == self) { // ensure that we have updated the dialog configs if we haven't already [FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL]; } } #pragma mark - Object Lifecycle - (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { [self _initializeContent]; if (CGRectEqualToRect(frame, CGRectZero)) { [self sizeToFit]; } } return self; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [super initWithCoder:decoder])) { [self _initializeContent]; } return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; [_likeButton removeObserver:self forKeyPath:@"likeActionController"]; } #pragma mark - Properties - (void)setBackgroundColor:(UIColor *)backgroundColor { [super setBackgroundColor:backgroundColor]; _likeButtonContainer.backgroundColor = backgroundColor; } - (void)setForegroundColor:(UIColor *)foregroundColor { if (![_foregroundColor isEqual:foregroundColor]) { _foregroundColor = foregroundColor; [_likeButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; _socialSentenceLabel.textColor = foregroundColor; } } - (void)setEnabled:(BOOL)enabled { _isExplicitlyDisabled = !enabled; [self _updateEnabled]; } - (void)setLikeControlAuxiliaryPosition:(FBSDKLikeControlAuxiliaryPosition)likeControlAuxiliaryPosition { if (_likeControlAuxiliaryPosition != likeControlAuxiliaryPosition) { _likeControlAuxiliaryPosition = likeControlAuxiliaryPosition; [self _updateLikeBoxCaretPosition]; [self setNeedsLayout]; [self setNeedsUpdateConstraints]; [self invalidateIntrinsicContentSize]; } } - (void)setLikeControlHorizontalAlignment:(FBSDKLikeControlHorizontalAlignment)likeControlHorizontalAlignment { if (_likeControlHorizontalAlignment != likeControlHorizontalAlignment) { _likeControlHorizontalAlignment = likeControlHorizontalAlignment; [self _updateLikeBoxCaretPosition]; [self setNeedsLayout]; [self setNeedsUpdateConstraints]; [self invalidateIntrinsicContentSize]; } } - (void)setLikeControlStyle:(FBSDKLikeControlStyle)likeControlStyle { if (_likeControlStyle != likeControlStyle) { _likeControlStyle = likeControlStyle; [self _updateLikeBoxCaretPosition]; [self setNeedsLayout]; [self setNeedsUpdateConstraints]; [self invalidateIntrinsicContentSize]; } } - (NSString *)objectID { return _likeButton.objectID; } - (void)setObjectID:(NSString *)objectID { if (![_likeButton.objectID isEqualToString:objectID]) { _likeButton.objectID = objectID; [self _updateEnabled]; [self setNeedsLayout]; } } - (FBSDKLikeObjectType)objectType { return _likeButton.objectType; } - (void)setObjectType:(FBSDKLikeObjectType)objectType { if (_likeButton.objectType != objectType) { _likeButton.objectType = objectType; [self setNeedsLayout]; } } - (void)setOpaque:(BOOL)opaque { [super setOpaque:opaque]; _likeButtonContainer.opaque = opaque; } - (BOOL)isSoundEnabled { return _likeButton.soundEnabled; } - (void)setSoundEnabled:(BOOL)soundEnabled { _likeButton.soundEnabled = soundEnabled; } #pragma mark - Layout - (CGSize)intrinsicContentSize { CGFloat width = self.preferredMaxLayoutWidth; if (width == 0) { width = CGFLOAT_MAX; } CGRect bounds = CGRectMake(0.0, 0.0, width, CGFLOAT_MAX); return [self _layoutWithBounds:bounds subviewSizingBlock:^CGSize(UIView *subview, CGSize constrainedSize) { if ([subview respondsToSelector:@selector(setPreferredMaxLayoutWidth:)]) { [(id)subview setPreferredMaxLayoutWidth:constrainedSize.width]; } return subview.intrinsicContentSize; }].contentSize; } - (void)layoutSubviews { [super layoutSubviews]; NSString *objectID = self.objectID; if (objectID) { FBSDKViewImpressionTracker *impressionTracker = [FBSDKViewImpressionTracker impressionTrackerWithEventName:FBSDKAppEventNameFBSDKLikeControlImpression]; [impressionTracker logImpressionWithIdentifier:objectID parameters:[self analyticsParameters]]; } [self _ensureLikeActionController]; CGRect bounds = self.bounds; CGSize(^sizingBlock)(UIView *, CGSize) = ^CGSize(UIView *subview, CGSize constrainedSize) { return [subview sizeThatFits:constrainedSize]; }; FBSDKLikeControlLayout layout = [self _layoutWithBounds:bounds subviewSizingBlock:sizingBlock]; UIView *auxiliaryView = [self _auxiliaryView]; _likeBoxView.hidden = (_likeBoxView != auxiliaryView); _socialSentenceLabel.hidden = (_socialSentenceLabel != auxiliaryView); _likeButtonContainer.frame = layout.likeButtonFrame; _likeButton.frame = _likeButtonContainer.bounds; auxiliaryView.frame = layout.auxiliaryViewFrame; } - (CGSize)sizeThatFits:(CGSize)size { switch (self.likeControlAuxiliaryPosition) { case FBSDKLikeControlAuxiliaryPositionInline:{ size.height = MAX(size.height, CGRectGetHeight(self.bounds)); break; } case FBSDKLikeControlAuxiliaryPositionTop: case FBSDKLikeControlAuxiliaryPositionBottom:{ size.width = MAX(size.width, CGRectGetWidth(self.bounds)); break; } } CGRect bounds = CGRectMake(0.0, 0.0, size.width, size.height); return [self _layoutWithBounds:bounds subviewSizingBlock:^CGSize(UIView *subview, CGSize constrainedSize) { return [subview sizeThatFits:constrainedSize]; }].contentSize; } #pragma mark - Internal Methods - (NSDictionary *)analyticsParameters { return @{ @"auxiliary_position": NSStringFromFBSDKLikeControlAuxiliaryPosition(self.likeControlAuxiliaryPosition), @"horizontal_alignment": NSStringFromFBSDKLikeControlHorizontalAlignment(self.likeControlHorizontalAlignment), @"object_id": (self.objectID ?: [NSNull null]), @"object_type": (NSStringFromFBSDKLikeObjectType(self.objectType) ?: [NSNull null]), @"sound_enabled": @(self.soundEnabled), @"style": NSStringFromFBSDKLikeControlStyle(self.likeControlStyle), }; } #pragma mark - Helper Methods - (UIView *)_auxiliaryView { [self _ensureLikeActionController]; switch (_likeControlStyle) { case FBSDKLikeControlStyleStandard:{ return (_socialSentenceLabel.text.length == 0 ? nil : _socialSentenceLabel); } case FBSDKLikeControlStyleBoxCount:{ return (_likeButton.likeActionController.likeCountString == nil ? nil : _likeBoxView); } } return nil; } - (CGFloat)_auxiliaryViewPadding { switch (_likeControlStyle) { case FBSDKLikeControlStyleStandard:{ return 8.0; } case FBSDKLikeControlStyleBoxCount:{ return 0.0; } } return 0.0; } - (void)_ensureLikeActionController { FBSDKLikeActionController *likeActionController = _likeButton.likeActionController; if (likeActionController) { _socialSentenceLabel.text = likeActionController.socialSentence; _likeBoxView.text = likeActionController.likeCountString; } } - (void)_handleLikeButtonTap:(FBSDKLikeButton *)likeButton { [self _ensureLikeActionController]; [self sendActionsForControlEvents:UIControlEventTouchUpInside]; } - (void)_initializeContent { self.backgroundColor = [UIColor clearColor]; _foregroundColor = [UIColor blackColor]; _likeButtonContainer = [[UIView alloc] initWithFrame:CGRectZero]; _likeButtonContainer.backgroundColor = self.backgroundColor; _likeButtonContainer.opaque = self.opaque; [self addSubview:_likeButtonContainer]; _likeButton = [[FBSDKLikeButton alloc] initWithFrame:CGRectZero]; [_likeButton addTarget:self action:@selector(_handleLikeButtonTap:) forControlEvents:UIControlEventTouchUpInside]; [_likeButtonContainer addSubview:_likeButton]; _socialSentenceLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _socialSentenceLabel.font = [UIFont systemFontOfSize:11.0]; _socialSentenceLabel.numberOfLines = 2; [self addSubview:_socialSentenceLabel]; _likeBoxView = [[FBSDKLikeBoxView alloc] initWithFrame:CGRectZero]; [self addSubview:_likeBoxView]; // use KVO to monitor changes to the likeActionController instance on FBSDKButton in order to avoid race conditions // between notification observers [_likeButton addObserver:self forKeyPath:@"likeActionController" options:NSKeyValueObservingOptionInitial context:FBSDKLikeControlKVOLikeActionControllerContext]; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(_likeActionControllerDidDisableNotification:) name:FBSDKLikeActionControllerDidDisableNotification object:nil]; [nc addObserver:self selector:@selector(_likeActionControllerDidUpdateNotification:) name:FBSDKLikeActionControllerDidUpdateNotification object:nil]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (context == FBSDKLikeControlKVOLikeActionControllerContext) { [self _likeActionControllerDidUpdateWithAnimated:NO]; } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } static void FBSDKLikeControlApplyHorizontalAlignment(CGRect *frameRef, CGRect bounds, FBSDKLikeControlHorizontalAlignment alignment) { if (frameRef == NULL) { return; } CGRect frame = *frameRef; switch (alignment) { case FBSDKLikeControlHorizontalAlignmentLeft:{ frame.origin.x = CGRectGetMinX(bounds); break; } case FBSDKLikeControlHorizontalAlignmentCenter:{ frame.origin.x = CGRectGetMinX(bounds) + floorf((CGRectGetWidth(bounds) - CGRectGetWidth(frame)) / 2); break; } case FBSDKLikeControlHorizontalAlignmentRight:{ frame.origin.x = CGRectGetMinX(bounds) + CGRectGetWidth(bounds) - CGRectGetWidth(frame); break; } } *frameRef = frame; } static CGFloat FBSDKLikeControlPaddedDistance(CGFloat distance, CGFloat padding, BOOL includeDistance) { return (distance == 0.0 ? 0.0 : (includeDistance ? distance : 0.0) + padding); } static CGSize FBSDKLikeControlCalculateContentSize(FBSDKLikeControlLayout layout) { return CGSizeMake(MAX(CGRectGetMaxX(layout.likeButtonFrame), CGRectGetMaxX(layout.auxiliaryViewFrame)), MAX(CGRectGetMaxY(layout.likeButtonFrame), CGRectGetMaxY(layout.auxiliaryViewFrame))); } - (FBSDKLikeControlLayout)_layoutWithBounds:(CGRect)bounds subviewSizingBlock:(fbsdk_like_control_sizing_block_t)subviewSizingBlock { FBSDKLikeControlLayout layout; CGSize likeButtonSize = subviewSizingBlock(_likeButton, bounds.size); layout.likeButtonFrame = CGRectMake(CGRectGetMinX(bounds), CGRectGetMinY(bounds), likeButtonSize.width, likeButtonSize.height); layout.auxiliaryViewFrame = CGRectZero; UIView *auxiliaryView = [self _auxiliaryView]; CGFloat auxiliaryViewPadding = [self _auxiliaryViewPadding]; CGSize auxiliaryViewSize = CGSizeZero; switch (self.likeControlAuxiliaryPosition) { case FBSDKLikeControlAuxiliaryPositionInline:{ if (auxiliaryView) { auxiliaryViewSize = CGSizeMake((CGRectGetWidth(bounds) - auxiliaryViewPadding - CGRectGetWidth(layout.likeButtonFrame)), CGRectGetHeight(bounds)); auxiliaryViewSize = subviewSizingBlock(auxiliaryView, auxiliaryViewSize); layout.auxiliaryViewFrame = CGRectMake(CGRectGetMinX(bounds), CGRectGetMinY(bounds), auxiliaryViewSize.width, MAX(auxiliaryViewSize.height, CGRectGetHeight(layout.likeButtonFrame))); } // align the views next to each other for sizing FBSDKLikeControlApplyHorizontalAlignment(&layout.likeButtonFrame, bounds, FBSDKLikeControlHorizontalAlignmentLeft); if (auxiliaryView) { layout.auxiliaryViewFrame.origin.x = CGRectGetMaxX(layout.likeButtonFrame) + auxiliaryViewPadding; } // calculate the size before offsetting the horizontal alignment, using the total calculated width layout.contentSize = FBSDKLikeControlCalculateContentSize(layout); // layout the subviews next to each other switch (self.likeControlHorizontalAlignment) { case FBSDKLikeControlHorizontalAlignmentLeft:{ // already done break; } case FBSDKLikeControlHorizontalAlignmentCenter:{ layout.likeButtonFrame.origin.x = floorf((CGRectGetWidth(bounds) - layout.contentSize.width) / 2); if (auxiliaryView) { layout.auxiliaryViewFrame.origin.x = (CGRectGetMaxX(layout.likeButtonFrame) + auxiliaryViewPadding); } break; } case FBSDKLikeControlHorizontalAlignmentRight:{ layout.likeButtonFrame.origin.x = CGRectGetMaxX(bounds) - CGRectGetWidth(layout.likeButtonFrame); if (auxiliaryView) { layout.auxiliaryViewFrame.origin.x = (CGRectGetMinX(layout.likeButtonFrame) - auxiliaryViewPadding - CGRectGetWidth(layout.auxiliaryViewFrame)); } break; } } break; } case FBSDKLikeControlAuxiliaryPositionTop:{ if (auxiliaryView) { auxiliaryViewSize = CGSizeMake(CGRectGetWidth(bounds), (CGRectGetHeight(bounds) - auxiliaryViewPadding - CGRectGetHeight(layout.likeButtonFrame))); auxiliaryViewSize = subviewSizingBlock(auxiliaryView, auxiliaryViewSize); layout.auxiliaryViewFrame = CGRectMake(CGRectGetMinX(bounds), CGRectGetMinY(bounds), MAX(auxiliaryViewSize.width, CGRectGetWidth(layout.likeButtonFrame)), auxiliaryViewSize.height); } layout.likeButtonFrame.origin.y = FBSDKLikeControlPaddedDistance(CGRectGetMaxY(layout.auxiliaryViewFrame), auxiliaryViewPadding, YES); // calculate the size before offsetting the horizontal alignment, using the total calculated width layout.contentSize = FBSDKLikeControlCalculateContentSize(layout); FBSDKLikeControlApplyHorizontalAlignment(&layout.likeButtonFrame, bounds, self.likeControlHorizontalAlignment); FBSDKLikeControlApplyHorizontalAlignment(&layout.auxiliaryViewFrame, bounds, self.likeControlHorizontalAlignment); break; } case FBSDKLikeControlAuxiliaryPositionBottom:{ if (auxiliaryView) { auxiliaryViewSize = CGSizeMake(CGRectGetWidth(bounds), (CGRectGetHeight(bounds) - auxiliaryViewPadding - CGRectGetHeight(layout.likeButtonFrame))); auxiliaryViewSize = subviewSizingBlock(auxiliaryView, auxiliaryViewSize); layout.auxiliaryViewFrame = CGRectMake(CGRectGetMinX(bounds), CGRectGetMaxY(layout.likeButtonFrame) + auxiliaryViewPadding, MAX(auxiliaryViewSize.width, CGRectGetWidth(layout.likeButtonFrame)), auxiliaryViewSize.height); } // calculate the size before offsetting the horizontal alignment, using the total calculated width layout.contentSize = FBSDKLikeControlCalculateContentSize(layout); FBSDKLikeControlApplyHorizontalAlignment(&layout.likeButtonFrame, bounds, self.likeControlHorizontalAlignment); FBSDKLikeControlApplyHorizontalAlignment(&layout.auxiliaryViewFrame, bounds, self.likeControlHorizontalAlignment); break; } } return layout; } - (void)_likeActionControllerDidDisableNotification:(NSNotification *)notification { [self _updateEnabled]; } - (void)_likeActionControllerDidUpdateNotification:(NSNotification *)notification { [self _ensureLikeActionController]; FBSDKLikeActionController *likeActionController = (FBSDKLikeActionController *)notification.object; NSString *objectID = likeActionController.objectID; if ([self.objectID isEqualToString:objectID]) { BOOL animated = [notification.userInfo[FBSDKLikeActionControllerAnimatedKey] boolValue]; [self _likeActionControllerDidUpdateWithAnimated:animated]; } } - (void)_likeActionControllerDidUpdateWithAnimated:(BOOL)animated { FBSDKLikeActionController *likeActionController = _likeButton.likeActionController; NSString *objectID = likeActionController.objectID; if ([self.objectID isEqualToString:objectID]) { _likeBoxView.text = _likeButton.likeActionController.likeCountString; if (animated) { void(^hideView)(UIView *) = ^(UIView *view){ view.alpha = 0.0; CGRect frame = view.frame; frame.origin.y += kFBLikeControlSocialSentenceAnimationOffset; view.frame = frame; }; [UIView animateWithDuration:kFBLikeControlAnimationDuration animations:^{ hideView(_socialSentenceLabel); } completion:^(BOOL finished) { _socialSentenceLabel.text = likeActionController.socialSentence; [self setNeedsLayout]; [self setNeedsUpdateConstraints]; [self invalidateIntrinsicContentSize]; [self layoutIfNeeded]; hideView(_socialSentenceLabel); [UIView animateWithDuration:kFBLikeControlAnimationDuration animations:^{ _socialSentenceLabel.alpha = 1.0; [self setNeedsLayout]; [self layoutIfNeeded]; }]; }]; } else { _socialSentenceLabel.text = likeActionController.socialSentence; [self setNeedsLayout]; [self setNeedsUpdateConstraints]; [self invalidateIntrinsicContentSize]; } [self sendActionsForControlEvents:UIControlEventValueChanged]; } } - (void)_updateEnabled { BOOL enabled = (!_isExplicitlyDisabled && self.objectID && ![FBSDKLikeActionController isDisabled]); BOOL currentEnabled = [self isEnabled]; [super setEnabled:enabled]; if (currentEnabled != enabled) { [self invalidateIntrinsicContentSize]; [self setNeedsLayout]; } } - (void)_updateLikeBoxCaretPosition { if (self.likeControlStyle != FBSDKLikeControlStyleBoxCount) { return; } switch (self.likeControlAuxiliaryPosition) { case FBSDKLikeControlAuxiliaryPositionInline:{ switch (self.likeControlHorizontalAlignment) { case FBSDKLikeControlHorizontalAlignmentLeft: case FBSDKLikeControlHorizontalAlignmentCenter:{ _likeBoxView.caretPosition = FBSDKLikeBoxCaretPositionLeft; break; } case FBSDKLikeControlHorizontalAlignmentRight:{ _likeBoxView.caretPosition = FBSDKLikeBoxCaretPositionRight; break; } } break; } case FBSDKLikeControlAuxiliaryPositionTop:{ _likeBoxView.caretPosition = FBSDKLikeBoxCaretPositionBottom; break; } case FBSDKLikeControlAuxiliaryPositionBottom:{ _likeBoxView.caretPosition = FBSDKLikeBoxCaretPositionTop; break; } } } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKLikeObjectType.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /*! @typedef NS_ENUM (NSUInteger, FBSDKLikeObjectType) @abstract Specifies the type of object referenced by the objectID for likes. */ typedef NS_ENUM(NSUInteger, FBSDKLikeObjectType) { /*! The objectID refers to an unknown object type. */ FBSDKLikeObjectTypeUnknown = 0, /*! The objectID refers to an Open Graph object. */ FBSDKLikeObjectTypeOpenGraph, /*! The objectID refers to an Page object. */ FBSDKLikeObjectTypePage, }; /*! @abstract Converts an FBLikeControlObjectType to an NSString. */ FBSDK_EXTERN NSString *NSStringFromFBSDKLikeObjectType(FBSDKLikeObjectType objectType); ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKLikeObjectType.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLikeObjectType.h" NSString *NSStringFromFBSDKLikeObjectType(FBSDKLikeObjectType objectType) { switch (objectType) { case FBSDKLikeObjectTypeUnknown: return @"unknown"; case FBSDKLikeObjectTypeOpenGraph: return @"open_graph"; case FBSDKLikeObjectTypePage: return @"page"; } return nil; } ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKLiking.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import /*! @abstract The common interface for components that initiate liking. @see FBSDKLikeButton @see FBSDKLikeControl */ @protocol FBSDKLiking /*! @abstract The objectID for the object to like. @discussion This value may be an Open Graph object ID or a string representation of an URL that describes an Open Graph object. The objects may be public objects, like pages, or objects that are defined by your application. */ @property (nonatomic, copy) NSString *objectID; /*! @abstract The type of object referenced by the objectID. @discussion If the objectType is unknown, the control will determine the objectType by querying the server with the objectID. Specifying a value for the objectType is an optimization that should be used if the type is known by the consumer. Consider setting the objectType if it is known when setting the objectID. */ @property (nonatomic, assign) FBSDKLikeObjectType objectType; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKMessageDialog.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /*! @abstract A dialog for sharing content through Messenger. */ @interface FBSDKMessageDialog : NSObject /*! @abstract Convenience method to show a Message Share Dialog with content and a delegate. @param content The content to be shared. @param delegate The receiver's delegate. */ + (instancetype)showWithContent:(id)content delegate:(id)delegate; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKMessageDialog.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKMessageDialog.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKShareConstants.h" #import "FBSDKShareDefines.h" #import "FBSDKShareError.h" #import "FBSDKShareOpenGraphContent.h" #import "FBSDKShareUtility.h" #import "FBSDKShareVideoContent.h" #define FBSDK_MESSAGE_DIALOG_APP_SCHEME @"fb-messenger-api" #define FBSDK_MESSAGE_METHOD_MIN_VERSION @"20140430" @implementation FBSDKMessageDialog #pragma mark - Class Methods + (void)initialize { if ([FBSDKMessageDialog class] == self) { [FBSDKInternalUtility checkRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_MESSENGER]; [FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL]; } } + (instancetype)showWithContent:(id)content delegate:(id)delegate { FBSDKMessageDialog *dialog = [[self alloc] init]; dialog.shareContent = content; dialog.delegate = delegate; [dialog show]; return dialog; } #pragma mark - Properties @synthesize delegate = _delegate; @synthesize shareContent = _shareContent; @synthesize shouldFailOnDataError = _shouldFailOnDataError; #pragma mark - Public Methods - (BOOL)canShow { return [self _canShowNative]; } - (BOOL)show { NSError *error; if (![self canShow]) { error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode message:@"Message dialog is not available."]; [self _invokeDelegateDidFailWithError:error]; return NO; } if (![self validateWithError:&error]) { [self _invokeDelegateDidFailWithError:error]; return NO; } id shareContent = self.shareContent; NSDictionary *parameters = [FBSDKShareUtility parametersForShareContent:shareContent shouldFailOnDataError:self.shouldFailOnDataError]; NSString *methodName = ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]] ? FBSDK_SHARE_OPEN_GRAPH_METHOD_NAME : FBSDK_SHARE_METHOD_NAME); FBSDKBridgeAPIRequest *request; request = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeNative scheme:FBSDK_MESSAGE_DIALOG_APP_SCHEME methodName:methodName methodVersion:FBSDK_MESSAGE_METHOD_MIN_VERSION parameters:parameters userInfo:nil]; FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration]; BOOL useSafariViewController = [configuration useSafariViewControllerForDialogName:FBSDKDialogConfigurationNameMessage]; FBSDKBridgeAPICallbackBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) { [self _handleCompletionWithDialogResults:response.responseParameters response:response]; [FBSDKInternalUtility unregisterTransientObject:self]; }; [[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:request useSafariViewController:useSafariViewController fromViewController:nil completionBlock:completionBlock]; [self _logDialogShow]; [FBSDKInternalUtility registerTransientObject:self]; return YES; } - (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef { id shareContent = self.shareContent; if (!shareContent) { if (errorRef != NULL) { *errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"shareContent" message:nil]; } return NO; } if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { if (![FBSDKShareUtility validateAssetLibraryURLWithShareVideoContent:(FBSDKShareVideoContent *)shareContent name:@"videoURL" error:errorRef]) { return NO; } } return [FBSDKShareUtility validateShareContent:self.shareContent error:errorRef]; } #pragma mark - Helper Methods - (BOOL)_canShowNative { FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration]; BOOL useNativeDialog = [configuration useNativeDialogForDialogName:FBSDKDialogConfigurationNameMessage]; return (useNativeDialog && [FBSDKInternalUtility isMessengerAppInstalled]); } - (void)_handleCompletionWithDialogResults:(NSDictionary *)results response:(FBSDKBridgeAPIResponse *)response { NSString *completionGesture = results[FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY]; if ([completionGesture isEqualToString:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_CANCEL] || response.isCancelled) { [self _invokeDelegateDidCancel]; } else if (response.error) { [self _invokeDelegateDidFailWithError:response.error]; } else { [self _invokeDelegateDidCompleteWithResults:results]; } } - (void)_invokeDelegateDidCancel { NSDictionary * parameters =@{ FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Cancelled, }; [FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventMessengerShareDialogResult valueToSum:nil parameters:parameters accessToken:[FBSDKAccessToken currentAccessToken]]; if (!_delegate) { return; } [_delegate sharerDidCancel:self]; } - (void)_invokeDelegateDidCompleteWithResults:(NSDictionary *)results { NSDictionary * parameters =@{ FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Completed, }; [FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventMessengerShareDialogResult valueToSum:nil parameters:parameters accessToken:[FBSDKAccessToken currentAccessToken]]; if (!_delegate) { return; } [_delegate sharer:self didCompleteWithResults:[results copy]]; } - (void)_invokeDelegateDidFailWithError:(NSError *)error { NSMutableDictionary * parameters = [NSMutableDictionary dictionaryWithObjectsAndKeys:FBSDKAppEventsDialogOutcomeValue_Failed, FBSDKAppEventParameterDialogOutcome, nil]; if (error) { parameters[FBSDKAppEventParameterDialogErrorMessage] = [NSString stringWithFormat:@"%@", error]; } [FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventMessengerShareDialogResult valueToSum:nil parameters:parameters accessToken:[FBSDKAccessToken currentAccessToken]]; if (!_delegate) { return; } [_delegate sharer:self didFailWithError:error]; } - (void)_logDialogShow { NSString *contentType; if([self.shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) { contentType = FBSDKAppEventsDialogShareContentTypeOpenGraph; } else if ([self.shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { contentType = FBSDKAppEventsDialogShareContentTypeStatus; } else if ([self.shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) { contentType = FBSDKAppEventsDialogShareContentTypePhoto; } else if ([self.shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { contentType = FBSDKAppEventsDialogShareContentTypeVideo; } else { contentType = FBSDKAppEventsDialogShareContentTypeUnknown; } NSDictionary *parameters = @{FBSDKAppEventParameterDialogShareContentType : contentType}; [FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventMessengerShareDialogShow valueToSum:nil parameters:parameters accessToken:[FBSDKAccessToken currentAccessToken]]; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKSendButton.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import /*! @abstract A button to send content through Messenger. @discussion Tapping the receiver will invoke the FBSDKShareDialog with the attached shareContent. If the dialog cannot be shown, the button will be disable. */ @interface FBSDKSendButton : FBSDKButton @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKSendButton.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKSendButton.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKMessageDialog.h" #import "FBSDKMessengerIcon.h" @interface FBSDKSendButton () @end @implementation FBSDKSendButton { FBSDKMessageDialog *_dialog; } #pragma mark - Properties - (id)shareContent { return _dialog.shareContent; } - (void)setShareContent:(id)shareContent { _dialog.shareContent = shareContent; [self checkImplicitlyDisabled]; } #pragma mark - FBSDKButtonImpressionTracking - (NSDictionary *)analyticsParameters { return nil; } - (NSString *)impressionTrackingEventName { return FBSDKAppEventNameFBSDKSendButtonImpression; } - (NSString *)impressionTrackingIdentifier { return @"send"; } #pragma mark - FBSDKButton - (void)configureButton { NSString *title = NSLocalizedStringWithDefaultValue(@"SendButton.Send", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Send", @"The label for FBSDKSendButton"); UIColor *backgroundColor = [UIColor colorWithRed:0.0 green:132.0/255.0 blue:1.0 alpha:1.0]; UIColor *highlightedColor = [UIColor colorWithRed:0.0 green:111.0/255.0 blue:1.0 alpha:1.0]; [self configureWithIcon:[[FBSDKMessengerIcon alloc] init] title:title backgroundColor:backgroundColor highlightedColor:highlightedColor]; [self addTarget:self action:@selector(_share:) forControlEvents:UIControlEventTouchUpInside]; _dialog = [[FBSDKMessageDialog alloc] init]; } - (BOOL)isImplicitlyDisabled { return ![_dialog canShow] || ![_dialog validateWithError:NULL]; } #pragma mark - Helper Methods - (void)_share:(id)sender { [self logTapEventWithEventName:FBSDKAppEventNameFBSDKSendButtonDidTap parameters:[self analyticsParameters]]; [_dialog show]; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareAPI.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import /*! @abstract A utility class for sharing through the graph API. Using this class requires an access token that has been granted the "publish_actions" permission. @discussion FBSDKShareAPI network requests are scheduled on the current run loop in the default run loop mode (like NSURLConnection). If you want to use FBSDKShareAPI in a background thread, you must manage the run loop yourself. */ @interface FBSDKShareAPI : NSObject /*! @abstract Convenience method to build up a share API with content and a delegate. @param content The content to be shared. @param delegate The receiver's delegate. */ + (instancetype)shareWithContent:(id)content delegate:(id)delegate; /*! @abstract The message the person has provided through the custom dialog that will accompany the share content. */ @property (nonatomic, copy) NSString *message; /*! @abstract The graph node to which content should be shared. */ @property (nonatomic, copy) NSString *graphNode; /*! @abstract The access token used when performing a share. The access token must have the "publish_actions" permission granted. @discussion Defaults to [FBSDKAccessToken currentAccessToken]. Setting this to nil will revert the access token to [FBSDKAccessToken currentAccessToken]. */ @property (nonatomic, strong) FBSDKAccessToken *accessToken; /*! @abstract A Boolean value that indicates whether the receiver can send the share. @discussion May return NO if the appropriate Facebook app is not installed and is required or an access token is required but not available. This method does not validate the content on the receiver, so this can be checked before building up the content. @see [FBSDKSharing validateWithError:] @result YES if the receiver can send, otherwise NO. */ - (BOOL)canShare; /*! @abstract Creates an User Owned Open Graph object without an action. @param openGraphObject The open graph object to create. @discussion Use this method to create an object alone, when an action is not going to be posted with the object. If the object will be used within an action, just put the object in the action and share that as the shareContent and the object will be created in the process. The delegate will be messaged with the results. Also see https://developers.facebook.com/docs/sharing/opengraph/object-api#objectapi-creatinguser @result YES if the receiver was able to send the request to create the object, otherwise NO. */ - (BOOL)createOpenGraphObject:(FBSDKShareOpenGraphObject *)openGraphObject; /*! @abstract Begins the send from the receiver. @result YES if the receiver was able to send the share, otherwise NO. */ - (BOOL)share; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareAPI.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareAPI.h" #if !TARGET_OS_TV #import #endif #import #import #import "FBSDKCoreKit+Internal.h" #import "FBSDKShareConstants.h" #import "FBSDKShareDefines.h" #import "FBSDKShareError.h" #import "FBSDKShareLinkContent.h" #import "FBSDKShareOpenGraphAction.h" #import "FBSDKShareOpenGraphContent.h" #import "FBSDKShareOpenGraphObject.h" #import "FBSDKSharePhoto.h" #import "FBSDKSharePhotoContent.h" #import "FBSDKShareUtility.h" #import "FBSDKShareVideo.h" #import "FBSDKShareVideoContent.h" #import "FBSDKVideoUploader.h" static NSString *const FBSDKShareAPIDefaultGraphNode = @"me"; static NSString *const FBSDKShareAPIPhotosEdge = @"photos"; static NSString *const FBSDKShareAPIVideosEdge = @"videos"; static NSMutableArray *g_pendingFBSDKShareAPI; @interface FBSDKShareAPI () @end @implementation FBSDKShareAPI { NSFileHandle *_fileHandle; #if !TARGET_OS_TV ALAssetRepresentation *_assetRepresentation; #endif } #pragma mark - Class Methods + (instancetype)shareWithContent:(id)content delegate:(id)delegate { FBSDKShareAPI *API = [[self alloc] init]; API.shareContent = content; API.delegate = delegate; [API share]; return API; } #pragma mark - Properties @synthesize delegate = _delegate; @synthesize shareContent = _shareContent; @synthesize shouldFailOnDataError = _shouldFailOnDataError; @synthesize accessToken = _accessToken; #pragma mark - Object Lifecycle #if !TARGET_OS_TV + (ALAssetsLibrary *)defaultAssetsLibrary { static dispatch_once_t pred = 0; static ALAssetsLibrary *library = nil; dispatch_once(&pred, ^{ library = [[fbsdkdfl_ALAssetsLibraryClass() alloc] init]; }); return library; } #endif + (void)initialize { if (self == [FBSDKShareAPI class]) { g_pendingFBSDKShareAPI = [[NSMutableArray alloc] init]; } } - (instancetype)init { if ((self = [super init])) { _graphNode = FBSDKShareAPIDefaultGraphNode; } return self; } #pragma mark - Public Methods - (BOOL)canShare { return YES; } - (BOOL)createOpenGraphObject:(FBSDKShareOpenGraphObject *)openGraphObject { NSError *error; if (![self canShare]) { NSString *message = @"Share API is not available; verify 'canShare' returns YES"; error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode message:message]; [_delegate sharer:self didFailWithError:error]; return NO; } if (![self _hasPublishActions]) { NSString *message = @"Warning: Access token is missing publish_actions permissions"; [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:message]; } if (!openGraphObject) { error = [FBSDKShareError requiredArgumentErrorWithName:@"openGraphObject" message:nil]; [_delegate sharer:self didFailWithError:error]; return NO; } FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; void(^completionHandler)(id) = ^(NSDictionary *result) { [_delegate sharer:self didCompleteWithResults:result]; }; if (![self _stageOpenGraphObject:openGraphObject connection:connection stagingHandler:NULL completionHandler:completionHandler]) { return NO; } [connection start]; return YES; } - (BOOL)share { NSError *error; if (![self canShare]) { NSString *message = @"Share API is not available; verify 'canShare' returns YES"; error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode message:message]; [_delegate sharer:self didFailWithError:error]; return NO; } if (![self _hasPublishActions]) { NSString *message = @"Warning: Access token is missing publish_actions permissions"; [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:message]; } if (![self validateWithError:&error]) { [_delegate sharer:self didFailWithError:error]; return NO; } id shareContent = self.shareContent; if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { return [self _shareLinkContent:(FBSDKShareLinkContent *)shareContent]; } else if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) { return [self _sharePhotoContent:(FBSDKSharePhotoContent *)shareContent]; } else if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { return [self _shareVideoContent:(FBSDKShareVideoContent *)shareContent]; } else if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) { return [self _shareOpenGraphContent:(FBSDKShareOpenGraphContent *)shareContent]; } else { return NO; } } - (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef { id shareContent = self.shareContent; if (!shareContent) { if (errorRef != NULL) { *errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"shareContent" message:@"Share content cannot be null."]; } return NO; } if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { if (shareContent.peopleIDs.count > 0) { if (errorRef != NULL) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"peopleIDs" value:shareContent.peopleIDs message:@"Cannot specify peopleIDs with FBSDKShareVideoContent."]; } return NO; } if (shareContent.placeID) { if (errorRef != NULL) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"placeID" value:shareContent.placeID message:@"Cannot specify place ID with FBSDKShareVideoContent."]; } return NO; } } if (errorRef != NULL){ *errorRef = nil; } return [FBSDKShareUtility validateShareContent:shareContent error:errorRef]; } - (FBSDKAccessToken *)accessToken { return _accessToken ?: [FBSDKAccessToken currentAccessToken]; } #pragma mark - Helper Methods - (NSString *)_graphPathWithSuffix:(NSString *)suffix, ... NS_REQUIRES_NIL_TERMINATION { NSMutableString *graphPath = [[NSMutableString alloc] initWithString:self.graphNode]; va_list args; va_start(args, suffix); for (NSString *arg = suffix; arg != nil; arg = va_arg(args, NSString *)) { [graphPath appendFormat:@"/%@", arg]; } va_end(args); return graphPath; } - (void)_addCommonParameters:(NSMutableDictionary *)parameters content:(id)content { if (content.peopleIDs.count > 0) { NSString *tags; if ([content isKindOfClass:[FBSDKSharePhotoContent class]]) { NSMutableArray *tagsArray = [[NSMutableArray alloc] init]; for (NSString *peopleID in content.peopleIDs) { [tagsArray addObject:@{ @"tag_uid" : peopleID }]; } NSData *tagsJSON = [NSJSONSerialization dataWithJSONObject:tagsArray options:0 error:nil]; tags = [[NSString alloc] initWithData:tagsJSON encoding:NSUTF8StringEncoding]; } else { tags = [content.peopleIDs componentsJoinedByString:@","]; } [FBSDKInternalUtility dictionary:parameters setObject:tags forKey:@"tags"]; } [FBSDKInternalUtility dictionary:parameters setObject:content.placeID forKey:@"place"]; [FBSDKInternalUtility dictionary:parameters setObject:content.ref forKey:@"ref"]; } - (BOOL)_hasPublishActions { return [self.accessToken.permissions containsObject:@"publish_actions"]; } - (BOOL)_shareLinkContent:(FBSDKShareLinkContent *)linkContent { FBSDKGraphRequestHandler completionHandler = ^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (!_delegate) { return; } if (error) { [_delegate sharer:self didFailWithError:error]; } else { result = [FBSDKTypeUtility dictionaryValue:result]; NSMutableDictionary *shareResults = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:shareResults setObject:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST forKey:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY]; [FBSDKInternalUtility dictionary:shareResults setObject:[FBSDKTypeUtility stringValue:result[@"id"]] forKey:FBSDK_SHARE_RESULT_POST_ID_KEY]; [_delegate sharer:self didCompleteWithResults:shareResults]; } }; NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; [self _addCommonParameters:parameters content:linkContent]; [FBSDKInternalUtility dictionary:parameters setObject:self.message forKey:@"message"]; [FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentURL forKey:@"link"]; [FBSDKInternalUtility dictionary:parameters setObject:linkContent.imageURL forKey:@"picture"]; [FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentTitle forKey:@"name"]; [FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentDescription forKey:@"description"]; [[[FBSDKGraphRequest alloc] initWithGraphPath:[self _graphPathWithSuffix:@"feed", nil] parameters:parameters tokenString:self.accessToken.tokenString version:nil HTTPMethod:@"POST"] startWithCompletionHandler:completionHandler]; return YES; } - (BOOL)_shareOpenGraphContent:(FBSDKShareOpenGraphContent *)openGraphContent { // In order to create a new Open Graph action using a custom object that does not already exist (objectID or URL), you // must first send a request to post the object and then another to post the action. If a local image is supplied // with the object or action, that must be staged first and then referenced by the staging URL that is returned by // that request. FBSDKShareOpenGraphAction *action = openGraphContent.action; FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; void(^stagingHandler)(NSDictionary *) = ^(NSDictionary *stagedContainer) { NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithDictionary:stagedContainer]; [self _addCommonParameters:parameters content:openGraphContent]; [FBSDKInternalUtility dictionary:parameters setObject:self.message forKey:@"message"]; FBSDKGraphRequestHandler requestHandler = ^(FBSDKGraphRequestConnection *requestConnection, id result, NSError *requestError) { if (!_delegate) { return; } if (requestError) { NSError *error = [FBSDKShareError errorWithCode:FBSDKShareOpenGraphErrorCode message:@"Error sharing Open Graph content" underlyingError:requestError]; [_delegate sharer:self didFailWithError:error]; } else if (result) { NSMutableDictionary *shareResults = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:shareResults setObject:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST forKey:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY]; [FBSDKInternalUtility dictionary:shareResults setObject:[FBSDKTypeUtility stringValue:result[@"id"]] forKey:FBSDK_SHARE_RESULT_POST_ID_KEY]; [_delegate sharer:self didCompleteWithResults:shareResults]; } }; NSString *graphPath = [self _graphPathWithSuffix:[FBSDKUtility URLEncode:action.actionType], nil]; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath parameters:parameters tokenString:self.accessToken.tokenString version:nil HTTPMethod:@"POST"]; [self _connection:connection addRequest:request completionHandler:requestHandler]; [connection start]; }; if (![self _stageOpenGraphValueContainer:action connection:connection stagingHandler:stagingHandler]) { return NO; } return YES; } - (BOOL)_sharePhotoContent:(FBSDKSharePhotoContent *)photoContent { NSArray *photos = photoContent.photos; NSMutableArray *requests = [[NSMutableArray alloc] init]; for (FBSDKSharePhoto *photo in photos) { UIImage *image = photo.image; if (!image && [photo.imageURL isFileURL]) { image = [UIImage imageWithContentsOfFile:[photo.imageURL path]]; } if (image) { NSString *graphPath = [self _graphPathWithSuffix:FBSDKShareAPIPhotosEdge, nil]; NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; [self _addCommonParameters:parameters content:photoContent]; NSString *caption = photo.caption ?: self.message; [FBSDKInternalUtility dictionary:parameters setObject:caption forKey:@"caption"]; parameters[@"picture"] = image; [requests addObject:[[FBSDKGraphRequest alloc] initWithGraphPath:graphPath parameters:parameters tokenString:self.accessToken.tokenString version:nil HTTPMethod:@"POST"]]; } } NSUInteger requestCount = [requests count]; NSMutableArray *results = [[NSMutableArray alloc] init]; NSMutableArray *errors = [[NSMutableArray alloc] init]; __block NSUInteger completedCount = 0; FBSDKGraphRequestHandler completionHandler = ^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { result = [FBSDKTypeUtility dictionaryValue:result]; [FBSDKInternalUtility array:results addObject:result]; [FBSDKInternalUtility array:errors addObject:error]; if (++completedCount != requestCount) { return; } if (!_delegate) { return; } if ([errors count]) { [_delegate sharer:self didFailWithError:errors[0]]; } else if ([results count]) { NSArray *individualPhotoIDs = [results valueForKeyPath:@"id"]; // each photo upload will be merged into the same post, so grab the post_id from the first and use that NSMutableDictionary *shareResults = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:shareResults setObject:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST forKey:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY]; NSDictionary *firstResult = [FBSDKTypeUtility dictionaryValue:results[0]]; [FBSDKInternalUtility dictionary:shareResults setObject:[FBSDKTypeUtility stringValue:firstResult[@"post_id"]] forKey:FBSDK_SHARE_RESULT_POST_ID_KEY]; [FBSDKInternalUtility dictionary:shareResults setObject:individualPhotoIDs forKey:FBSDK_SHARE_RESULT_PHOTO_IDS_KEY]; [_delegate sharer:self didCompleteWithResults:shareResults]; } }; for (FBSDKGraphRequest *request in requests) { [request startWithCompletionHandler:completionHandler]; } return YES; } - (BOOL)_shareVideoContent:(FBSDKShareVideoContent *)videoContent { NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; [self _addCommonParameters:parameters content:videoContent]; [FBSDKInternalUtility dictionary:parameters setObject:self.message forKey:@"description"]; if ([self.accessToken.permissions containsObject:@"ads_management"]) { FBSDKSharePhoto *photo = videoContent.previewPhoto; UIImage *image = photo.image; if (!image && [photo.imageURL isFileURL]) { image = [UIImage imageWithContentsOfFile:[photo.imageURL path]]; } [FBSDKInternalUtility dictionary:parameters setObject:image forKey:@"thumb"]; } FBSDKShareVideo *video = videoContent.video; NSURL *videoURL = video.videoURL; if ([videoURL isFileURL]) { NSError *fileError; _fileHandle = [NSFileHandle fileHandleForReadingFromURL:videoURL error:&fileError]; if (!_fileHandle) { [_delegate sharer:self didFailWithError:fileError]; return NO; } if (![self _addToPendingShareAPI]) { return NO; } FBSDKVideoUploader *videoUploader = [[FBSDKVideoUploader alloc] initWithVideoName:[videoURL lastPathComponent] videoSize:(unsigned long)[_fileHandle seekToEndOfFile] parameters:parameters delegate:self]; videoUploader.graphNode = self.graphNode; [videoUploader start]; return YES; } else if (videoURL) { #if TARGET_OS_TV return NO; #else if (![self _addToPendingShareAPI]) { return NO; } [[FBSDKShareAPI defaultAssetsLibrary] assetForURL:videoURL resultBlock:^(ALAsset *asset) { _assetRepresentation = [asset defaultRepresentation]; NSUInteger size = (NSUInteger)_assetRepresentation.size; FBSDKVideoUploader *videoUploader = [[FBSDKVideoUploader alloc] initWithVideoName:[videoURL lastPathComponent] videoSize:size parameters:parameters delegate:self]; videoUploader.graphNode = self.graphNode; [videoUploader start]; } failureBlock:^(NSError *error) { [_delegate sharer:self didFailWithError:error]; }]; return YES; #endif } else { return NO; } } - (BOOL)_addEncodedParametersToDictionary:(NSMutableDictionary *)parameters key:(NSString *)key value:(id)value error:(NSError **)errorRef { if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSNull class]]) { parameters[key] = value; } else if ([value isKindOfClass:[NSArray class]]) { __block BOOL didEncode = YES; [(NSArray *)value enumerateObjectsUsingBlock:^(id subvalue, NSUInteger idx, BOOL *stop) { NSString *subkey = [[NSString alloc] initWithFormat:@"%@[%lu]", key, (unsigned long)idx]; if (![self _addEncodedParametersToDictionary:parameters key:subkey value:subvalue error:errorRef]) { *stop = YES; didEncode = NO; } }]; if (!didEncode) { return NO; } } else if ([value isKindOfClass:[NSDictionary class]]) { __block BOOL didEncode = YES; [(NSDictionary *)value enumerateKeysAndObjectsUsingBlock:^(id subkey, id subvalue, BOOL *stop) { subkey = [[NSString alloc] initWithFormat:@"%@[%@]", key, subkey]; if (![self _addEncodedParametersToDictionary:parameters key:subkey value:subvalue error:errorRef]) { *stop = YES; didEncode = NO; } }]; if (!didEncode) { return NO; } } else { if (errorRef != NULL) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:key value:value message:nil]; } return NO; } if (errorRef != NULL) { *errorRef = nil; } return YES; } - (BOOL)_stageArray:(NSArray *)array connection:(FBSDKGraphRequestConnection *)connection stagingHandler:(void(^)(NSArray *stagedArray))stagingHandler { __block BOOL result = YES; __block NSUInteger pendingCount = 1; NSMutableArray *stagedArray = [[NSMutableArray alloc] initWithArray:array]; void(^itemDidFail)(void) = ^{ if (!result) { return; } result = NO; }; void(^itemDidSucceed)(void) = ^{ if (!result) { return; } if ((--pendingCount == 0) && (stagingHandler != NULL)) { stagingHandler(stagedArray); } }; [array enumerateObjectsUsingBlock:^(id item, NSUInteger idx, BOOL *stop) { pendingCount++; void(^itemHandler)(id) = ^(id stagedValue) { if (stagedValue) { stagedArray[idx] = stagedValue; itemDidSucceed(); } else { NSError *error = [FBSDKShareError invalidArgumentErrorWithName:@"value" value:item message:@"Error staging object."]; [_delegate sharer:self didFailWithError:error]; itemDidFail(); *stop = YES; result = NO; } }; if (![self _stageValue:item connection:connection stagingHandler:itemHandler]) { itemDidFail(); *stop = YES; result = NO; } }]; if (result) { itemDidSucceed(); } return result; } - (BOOL)_stageOpenGraphObject:(FBSDKShareOpenGraphObject *)openGraphObject connection:(FBSDKGraphRequestConnection *)connection stagingHandler:(void(^)(id stagedObject))stagingHandler completionHandler:(void(^)(NSDictionary *result))completionHandler { NSString *type = [FBSDKTypeUtility stringValue:openGraphObject[@"og:type"]]; if (!type) { NSString *message = @"Open Graph objects must contain a og:type value."; NSError *error = [FBSDKShareError requiredArgumentErrorWithName:@"og:type" message:message]; [_delegate sharer:self didFailWithError:error]; return NO; } void(^containerHandler)(NSDictionary *) = ^(NSDictionary *stagedContainer) { NSError *JSONError; NSString *objectString = [FBSDKInternalUtility JSONStringForObject:stagedContainer error:&JSONError invalidObjectHandler:NULL]; if (!objectString) { [_delegate sharer:self didFailWithError:JSONError]; return; } NSString *graphPath = [self _graphPathWithSuffix:@"objects", type, nil]; NSDictionary *parameters = @{ @"object": objectString }; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath parameters:parameters tokenString:self.accessToken.tokenString version:nil HTTPMethod:@"POST"]; FBSDKGraphRequestHandler requestCompletionHandler = ^(FBSDKGraphRequestConnection *requestConnection, id result, NSError *requestError) { if (!_delegate) { return; } if (requestError) { NSString *message = [[NSString alloc] initWithFormat:@"Error creating Open Graph object: %@", requestError.description]; NSError *error = [FBSDKShareError errorWithCode:FBSDKShareOpenGraphErrorCode message:message underlyingError:requestError]; [_delegate sharer:self didFailWithError:error]; } else if (completionHandler != NULL) { completionHandler([FBSDKTypeUtility dictionaryValue:result]); } }; NSString *batchEntryName = [self _connection:connection addRequest:request completionHandler:requestCompletionHandler]; if (stagingHandler != NULL) { stagingHandler([[NSString alloc] initWithFormat:@"{result=%@:$.id}", batchEntryName]); } }; return [self _stageOpenGraphValueContainer:openGraphObject connection:connection stagingHandler:containerHandler]; return YES; } - (BOOL)_stageOpenGraphValueContainer:(id)container connection:(FBSDKGraphRequestConnection *)connection stagingHandler:(void(^)(NSDictionary *stagedContainer))stagingHandler { __block BOOL result = YES; __block NSUInteger pendingCount = 1; NSMutableDictionary *stagedContainer = [[NSMutableDictionary alloc] init]; void(^itemDidFail)(void) = ^{ if (!result) { return; } result = NO; }; void(^itemDidSucceed)(void) = ^{ if (!result) { return; } if ((--pendingCount == 0) && (stagingHandler != NULL)) { stagingHandler(stagedContainer); } }; BOOL isAction = [container isKindOfClass:[FBSDKShareOpenGraphAction class]]; [container enumerateKeysAndObjectsUsingBlock:^(NSString *key, id object, BOOL *stop) { pendingCount++; // The server does not understand custom namespaces remove them until the server is fixed NSString *namespace; key = [FBSDKShareUtility getOpenGraphNameAndNamespaceFromFullName:key namespace:&namespace]; if (namespace && !isAction) { if (!stagedContainer[namespace]) { stagedContainer[namespace] = [[NSMutableDictionary alloc] init]; } } void(^itemHandler)(id) = ^(id stagedValue) { if (stagedValue) { if (isAction) { NSError *error; if (![self _addEncodedParametersToDictionary:stagedContainer key:key value:stagedValue error:&error]) { [_delegate sharer:self didFailWithError:error]; itemDidFail(); return; } } else { NSMutableDictionary *valueContainer = (namespace ? stagedContainer[namespace] : stagedContainer); valueContainer[key] = stagedValue; } } itemDidSucceed(); }; if (![self _stageValue:object connection:connection stagingHandler:itemHandler]) { *stop = YES; result = NO; } }]; if (result) { itemDidSucceed(); } return result; } - (BOOL)_stagePhoto:(FBSDKSharePhoto *)photo connection:(FBSDKGraphRequestConnection *)connection stagingHandler:(void(^)(id stagedPhoto))stagingHandler { if (photo.imageURL) { NSMutableDictionary *stagedPhoto = [[NSMutableDictionary alloc]initWithDictionary: @{ @"url": photo.imageURL.absoluteString, @"user_generated": @(photo.userGenerated), }]; [FBSDKInternalUtility dictionary:stagedPhoto setObject:photo.caption forKey:@"caption"]; if (stagingHandler) { stagingHandler(stagedPhoto); } return YES; } else if (photo.image) { NSString *graphPath = @"/me/staging_resources"; NSDictionary *parameters = @{ @"file": photo.image }; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:graphPath parameters:parameters tokenString:self.accessToken.tokenString version:nil HTTPMethod:@"POST"]; FBSDKGraphRequestHandler completionHandler = ^(FBSDKGraphRequestConnection *requestConnection, id result, NSError *requestError) { NSString *stagedPhotoURLString = [FBSDKTypeUtility stringValue:result[@"uri"]]; if (requestError || !stagedPhotoURLString) { NSError *error = [FBSDKShareError errorWithCode:FBSDKShareOpenGraphErrorCode message:@"Error staging photo" underlyingError:requestError]; [_delegate sharer:self didFailWithError:error]; } else if (stagingHandler) { NSMutableDictionary *stagedPhoto = [[NSMutableDictionary alloc] initWithDictionary: @{ @"url": stagedPhotoURLString, @"user_generated": @(photo.userGenerated), }]; [FBSDKInternalUtility dictionary:stagedPhoto setObject:photo.caption forKey:@"caption"]; stagingHandler(stagedPhoto); } }; [request startWithCompletionHandler:completionHandler]; return YES; } else { NSError *error = [FBSDKShareError invalidArgumentErrorWithName:@"photo" value:photo message:@"Photos must have an imageURL or image."]; [_delegate sharer:self didFailWithError:error]; return NO; } } - (BOOL)_stageValue:(id)value connection:(FBSDKGraphRequestConnection *)connection stagingHandler:(void(^)(id stagedValue))stagingHandler { if ([value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSNumber class]]) { if (stagingHandler != NULL) { stagingHandler(value); } return YES; } else if ([value isKindOfClass:[NSURL class]]) { if (stagingHandler != NULL) { stagingHandler([(NSURL *)value absoluteString]); } return YES; } else if ([value isKindOfClass:[FBSDKSharePhoto class]]) { return [self _stagePhoto:(FBSDKSharePhoto *)value connection:connection stagingHandler:stagingHandler]; } else if ([value isKindOfClass:[FBSDKShareOpenGraphObject class]]) { return [self _stageOpenGraphObject:(FBSDKShareOpenGraphObject *)value connection:connection stagingHandler:stagingHandler completionHandler:NULL]; } else if ([value isKindOfClass:[NSArray class]]) { return [self _stageArray:(NSArray *)value connection:connection stagingHandler:stagingHandler]; } else { NSError *error = [FBSDKShareError invalidArgumentErrorWithName:@"value" value:value message:@"Invalid value type found in Open Graph object."]; [_delegate sharer:self didFailWithError:error]; return NO; } } - (NSString *)_connection:(FBSDKGraphRequestConnection *)connection addRequest:(FBSDKGraphRequest *)request completionHandler:(FBSDKGraphRequestHandler)completionHandler { NSUInteger requestCount = [connection.requests count]; NSString *batchEntryName = [[NSString alloc] initWithFormat:@"request_%lu", (unsigned long)requestCount]; [connection addRequest:request completionHandler:completionHandler batchEntryName:batchEntryName]; return batchEntryName; } - (BOOL)_addToPendingShareAPI { @synchronized(g_pendingFBSDKShareAPI) { if ([g_pendingFBSDKShareAPI containsObject:self]) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors logEntry:@"FBSDKShareAPI did not share video content. Video upload already in progress."]; return NO; } [g_pendingFBSDKShareAPI addObject:self]; return YES; } } - (void)_removeFromPendingShareAPI { @synchronized(g_pendingFBSDKShareAPI) { [g_pendingFBSDKShareAPI removeObject:self]; _fileHandle = nil; #if !TARGET_OS_TV _assetRepresentation = nil; #endif } } #pragma mark - FBSDKVideoUploaderDelegate - (NSData *)videoChunkDataForVideoUploader:(FBSDKVideoUploader *)videoUploader startOffset:(NSUInteger)startOffset endOffset:(NSUInteger)endOffset { NSUInteger chunkSize = endOffset - startOffset; if (_fileHandle) { [_fileHandle seekToFileOffset:startOffset]; NSData *videoChunkData = [_fileHandle readDataOfLength:chunkSize]; if (videoChunkData == nil || videoChunkData.length != chunkSize) { return nil; } return videoChunkData; } #if !TARGET_OS_TV else if (_assetRepresentation) { NSMutableData *data = [NSMutableData dataWithLength:chunkSize]; NSError *error; NSUInteger bufferedLength = [_assetRepresentation getBytes:[data mutableBytes] fromOffset:startOffset length:chunkSize error:&error]; if (bufferedLength != chunkSize || data == nil || error) { return nil; } return data; } #endif return nil; } - (void)videoUploader:(FBSDKVideoUploader *)videoUploader didCompleteWithResults:(NSDictionary *)results { results = [FBSDKTypeUtility dictionaryValue:results]; NSMutableDictionary *shareResults = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:shareResults setObject:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST forKey:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY]; [FBSDKInternalUtility dictionary:shareResults setObject:[FBSDKTypeUtility stringValue:results[FBSDK_SHARE_VIDEO_ID]] forKey:FBSDK_SHARE_VIDEO_ID]; [_delegate sharer:self didCompleteWithResults:shareResults]; [self _removeFromPendingShareAPI]; } - (void)videoUploader:(FBSDKVideoUploader *)videoUploader didFailWithError:(NSError *)error { [_delegate sharer:self didFailWithError:error]; [self _removeFromPendingShareAPI]; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareButton.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import /*! @abstract A button to share content. @discussion Tapping the receiver will invoke the FBSDKShareDialog with the attached shareContent. If the dialog cannot be shown, the button will be disabled. */ @interface FBSDKShareButton : FBSDKButton @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareButton.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareButton.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKShareDialog.h" @implementation FBSDKShareButton { FBSDKShareDialog *_dialog; } #pragma mark - Properties - (id)shareContent { return _dialog.shareContent; } - (void)setShareContent:(id)shareContent { _dialog.shareContent = shareContent; [self checkImplicitlyDisabled]; } #pragma mark - FBSDKButtonImpressionTracking - (NSDictionary *)analyticsParameters { return nil; } - (NSString *)impressionTrackingEventName { return FBSDKAppEventNameFBSDKShareButtonImpression; } - (NSString *)impressionTrackingIdentifier { return @"share"; } #pragma mark - FBSDKButton - (void)configureButton { NSString *title = NSLocalizedStringWithDefaultValue(@"ShareButton.Share", @"FacebookSDK", [FBSDKInternalUtility bundleForStrings], @"Share", @"The label for FBSDKShareButton"); [self configureWithIcon:nil title:title backgroundColor:nil highlightedColor:nil]; [self addTarget:self action:@selector(_share:) forControlEvents:UIControlEventTouchUpInside]; _dialog = [[FBSDKShareDialog alloc] init]; } - (BOOL)isImplicitlyDisabled { return ![_dialog canShow] || ![_dialog validateWithError:NULL]; } #pragma mark - Helper Methods - (void)_share:(id)sender { [self logTapEventWithEventName:FBSDKAppEventNameFBSDKShareButtonDidTap parameters:[self analyticsParameters]]; [_dialog show]; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareConstants.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /*! @abstract The error domain for all errors from FBSDKShareKit. @discussion Error codes from the SDK in the range 200-299 are reserved for this domain. */ FBSDK_EXTERN NSString *const FBSDKShareErrorDomain; /*! @typedef NS_ENUM(NSInteger, FBSDKShareErrorCode) @abstract Error codes for FBSDKShareErrorDomain. */ typedef NS_ENUM(NSInteger, FBSDKShareErrorCode) { /*! @abstract Reserved. */ FBSDKShareReservedErrorCode = 200, /*! @abstract The error code for errors from uploading open graph objects. */ FBSDKShareOpenGraphErrorCode, /*! @abstract The error code for when a sharing dialog is not available. @discussion Use the canShare methods to check for this case before calling show. */ FBSDKShareDialogNotAvailableErrorCode, /*! @The error code for unknown errors. */ FBSDKShareUnknownErrorCode, }; ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareConstants.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareConstants.h" NSString *const FBSDKShareErrorDomain = @"com.facebook.sdk.share"; NSString *const FBSDKShareOpenGraphKeyErrorKey = @"key"; NSString *const FBSDKShareOpenGraphValueErrorKey = @"value"; ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import /*! @abstract A dialog for sharing content on Facebook. */ @interface FBSDKShareDialog : NSObject /*! @abstract Convenience method to show an FBSDKShareDialog with a fromViewController, content and a delegate. @param viewController A UIViewController to present the dialog from, if appropriate. @param content The content to be shared. @param delegate The receiver's delegate. */ + (instancetype)showFromViewController:(UIViewController *)viewController withContent:(id)content delegate:(id)delegate; /*! @abstract A UIViewController to present the dialog from. @discussion If not specified, the top most view controller will be automatically determined as best as possible. */ @property (nonatomic, weak) UIViewController *fromViewController; /*! @abstract The mode with which to display the dialog. @discussion Defaults to FBSDKShareDialogModeAutomatic, which will automatically choose the best available mode. */ @property (nonatomic, assign) FBSDKShareDialogMode mode; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareDialog.h" #import #import "FBSDKCoreKit+Internal.h" #import "FBSDKShareConstants.h" #import "FBSDKShareDefines.h" #import "FBSDKShareError.h" #import "FBSDKShareLinkContent.h" #import "FBSDKShareMediaContent.h" #import "FBSDKShareOpenGraphAction.h" #import "FBSDKShareOpenGraphContent.h" #import "FBSDKShareOpenGraphObject.h" #import "FBSDKSharePhoto.h" #import "FBSDKSharePhotoContent.h" #import "FBSDKShareUtility.h" #import "FBSDKShareVideo.h" #import "FBSDKShareVideoContent.h" #define FBSDK_SHARE_FEED_METHOD_NAME @"feed" #define FBSDK_SHARE_METHOD_MIN_VERSION @"20130410" #define FBSDK_SHARE_METHOD_OG_MIN_VERSION @"20130214" #define FBSDK_SHARE_METHOD_OG_IMAGE_MIN_VERSION @"20130410" #define FBSDK_SHARE_METHOD_PHOTOS_MIN_VERSION @"20140116" #define FBSDK_SHARE_METHOD_VIDEO_MIN_VERSION @"20150313" #define FBSDK_SHARE_METHOD_ATTRIBUTED_SHARE_SHEET_MIN_VERSION @"20150629" #define FBSDK_SHARE_METHOD_QUOTE_MIN_VERSION @"20160328" #define FBSDK_SHARE_METHOD_MMP_MIN_VERSION @"20160328" FBSDK_STATIC_INLINE void FBSDKShareDialogValidateAPISchemeRegisteredForCanOpenUrl() { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ [FBSDKInternalUtility checkRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_FBAPI]; }); } FBSDK_STATIC_INLINE void FBSDKShareDialogValidateShareExtensionSchemeRegisteredForCanOpenUrl() { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ [FBSDKInternalUtility checkRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_SHARE_EXTENSION]; }); } @interface FBSDKShareDialog () @end @implementation FBSDKShareDialog { FBSDKWebDialog *_webDialog; } #pragma mark - Class Methods + (void)initialize { if ([FBSDKShareDialog class] == self) { [FBSDKInternalUtility checkRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_FACEBOOK]; [FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL]; } } + (instancetype)showFromViewController:(UIViewController *)viewController withContent:(id)content delegate:(id)delegate { FBSDKShareDialog *dialog = [[self alloc] init]; dialog.fromViewController = viewController; dialog.shareContent = content; dialog.delegate = delegate; [dialog show]; return dialog; } #pragma mark - Object Lifecycle - (void)dealloc { _webDialog.delegate = nil; } #pragma mark - Properties @synthesize delegate = _delegate; @synthesize shareContent = _shareContent; @synthesize shouldFailOnDataError = _shouldFailOnDataError; #pragma mark - Public Methods - (BOOL)canShow { switch (self.mode) { case FBSDKShareDialogModeAutomatic: case FBSDKShareDialogModeBrowser: case FBSDKShareDialogModeFeedBrowser: case FBSDKShareDialogModeFeedWeb: case FBSDKShareDialogModeWeb:{ return YES; } case FBSDKShareDialogModeNative:{ return [self _canShowNative]; } case FBSDKShareDialogModeShareSheet:{ return [self _canShowShareSheet]; } } } - (BOOL)show { BOOL didShow = NO; NSError *error = nil; if ([self _validateWithError:&error]) { switch (self.mode) { case FBSDKShareDialogModeAutomatic:{ didShow = [self _showAutomatic:&error]; break; } case FBSDKShareDialogModeBrowser:{ didShow = [self _showBrowser:&error]; break; } case FBSDKShareDialogModeFeedBrowser:{ didShow = [self _showFeedBrowser:&error]; break; } case FBSDKShareDialogModeFeedWeb:{ didShow = [self _showFeedWeb:&error]; break; } case FBSDKShareDialogModeNative:{ didShow = [self _showNativeWithCanShowError:&error validationError:&error]; break; } case FBSDKShareDialogModeShareSheet:{ didShow = [self _showShareSheetWithCanShowError:&error validationError:&error]; break; } case FBSDKShareDialogModeWeb:{ didShow = [self _showWeb:&error]; break; } } } if (!didShow) { [self _invokeDelegateDidFailWithError:error]; } else { [self _logDialogShow]; [FBSDKInternalUtility registerTransientObject:self]; } return didShow; } - (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef { return [self _validateWithError:errorRef] && [self _validateFullyCompatibleWithError:errorRef]; } #pragma mark - FBSDKWebDialogDelegate - (void)webDialog:(FBSDKWebDialog *)webDialog didCompleteWithResults:(NSDictionary *)results { if (_webDialog != webDialog) { return; } [self _cleanUpWebDialog]; NSInteger errorCode = [results[@"error_code"] integerValue]; if (errorCode == 4201) { [self _invokeDelegateDidCancel]; } else if (errorCode != 0) { NSError *error = [FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode userInfo:@{ FBSDKGraphRequestErrorGraphErrorCode : @(errorCode) } message:results[@"error_message"] underlyingError:nil]; [self _handleWebResponseParameters:nil error:error]; } else { // not all web dialogs report cancellation, so assume that the share has completed with no additional information [self _handleWebResponseParameters:results error:nil]; } [FBSDKInternalUtility unregisterTransientObject:self]; } - (void)webDialog:(FBSDKWebDialog *)webDialog didFailWithError:(NSError *)error { if (_webDialog != webDialog) { return; } [self _cleanUpWebDialog]; [self _invokeDelegateDidFailWithError:error]; [FBSDKInternalUtility unregisterTransientObject:self]; } - (void)webDialogDidCancel:(FBSDKWebDialog *)webDialog { if (_webDialog != webDialog) { return; } [self _cleanUpWebDialog]; [self _invokeDelegateDidCancel]; [FBSDKInternalUtility unregisterTransientObject:self]; } #pragma mark - Helper Methods -(BOOL)_isDefaultToShareSheet { FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration]; return [configuration.defaultShareMode isEqualToString:@"share_sheet"]; } - (BOOL)_isOpenGraphURLShare:(FBSDKShareOpenGraphContent *)shareContent { __block BOOL hasOGURL = NO; [shareContent.action enumerateKeysAndObjectsUsingBlock:^(NSString *key, id object, BOOL *stop) { if ([object isKindOfClass:[NSURL class]]) { hasOGURL = YES; } }]; return hasOGURL; } -(BOOL)_showAutomatic:(NSError *__autoreleasing *)errorRef { BOOL isDefaultToShareSheet = [self _isDefaultToShareSheet]; BOOL useNativeDialog = [self _useNativeDialog]; return ((isDefaultToShareSheet && [self _showShareSheetWithCanShowError:NULL validationError:errorRef]) || (useNativeDialog && [self _showNativeWithCanShowError:NULL validationError:errorRef]) || (!isDefaultToShareSheet && [self _showShareSheetWithCanShowError:NULL validationError:errorRef]) || [self _showFeedBrowser:errorRef] || [self _showFeedWeb:errorRef] || [self _showBrowser:errorRef] || [self _showWeb:errorRef] || (!useNativeDialog && [self _showNativeWithCanShowError:NULL validationError:errorRef])); } - (void)_loadNativeMethodName:(NSString **)methodNameRef methodVersion:(NSString **)methodVersionRef { if (methodNameRef != NULL) { *methodNameRef = nil; } if (methodVersionRef != NULL) { *methodVersionRef = nil; } id shareContent = self.shareContent; if (!shareContent) { return; } // if there is shareContent on the receiver already, we can check the minimum app version, otherwise we can only check // for an app that can handle the native share dialog NSString *methodName = nil; NSString *methodVersion = nil; if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) { methodName = FBSDK_SHARE_OPEN_GRAPH_METHOD_NAME; BOOL containsMedia = NO; [FBSDKShareUtility testShareContent:shareContent containsMedia:&containsMedia containsPhotos:NULL containsVideos:NULL]; if (containsMedia) { methodVersion = FBSDK_SHARE_METHOD_OG_IMAGE_MIN_VERSION; } else { methodVersion = FBSDK_SHARE_METHOD_OG_MIN_VERSION; } } else { methodName = FBSDK_SHARE_METHOD_NAME; if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) { methodVersion = FBSDK_SHARE_METHOD_PHOTOS_MIN_VERSION; } else if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { methodVersion = FBSDK_SHARE_METHOD_VIDEO_MIN_VERSION; } else { methodVersion = FBSDK_SHARE_METHOD_MIN_VERSION; } } if (methodNameRef != NULL) { *methodNameRef = methodName; } if (methodVersionRef != NULL) { *methodVersionRef = methodVersion; } } - (BOOL)_canShowNative { return [FBSDKInternalUtility isFacebookAppInstalled]; } - (BOOL)_canShowShareSheet { Class composeViewControllerClass = [fbsdkdfl_SLComposeViewControllerClass() class]; if (!composeViewControllerClass) { return NO; } NSString *facebookServiceType = fbsdkdfl_SLServiceTypeFacebook(); if (![composeViewControllerClass isAvailableForServiceType:facebookServiceType]) { return NO; } return YES; } - (BOOL)_canAttributeThroughShareSheet { NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; if (![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) { return NO; } FBSDKShareDialogValidateAPISchemeRegisteredForCanOpenUrl(); NSString *scheme = FBSDK_CANOPENURL_FBAPI; NSString *minimumVersion = FBSDK_SHARE_METHOD_ATTRIBUTED_SHARE_SHEET_MIN_VERSION; NSURLComponents *components = [[NSURLComponents alloc] init]; components.scheme = [scheme stringByAppendingString:minimumVersion]; components.path = @"/"; return ([[UIApplication sharedApplication] canOpenURL:components.URL] || [self _canUseFBShareSheet]); } - (BOOL)_canUseFBShareSheet { NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; if (![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) { return NO; } FBSDKShareDialogValidateShareExtensionSchemeRegisteredForCanOpenUrl(); NSURLComponents *components = [[NSURLComponents alloc] init]; components.scheme = FBSDK_CANOPENURL_SHARE_EXTENSION; components.path = @"/"; return [[UIApplication sharedApplication] canOpenURL:components.URL]; } - (BOOL)_canUseQuoteInShareSheet { return [self _canUseFBShareSheet] && [self _supportsShareSheetMinimumVersion:FBSDK_SHARE_METHOD_QUOTE_MIN_VERSION]; } - (BOOL)_canUseMMPInShareSheet { return [self _canUseFBShareSheet] && [self _supportsShareSheetMinimumVersion:FBSDK_SHARE_METHOD_MMP_MIN_VERSION]; } - (BOOL)_supportsShareSheetMinimumVersion:(NSString *)minimumVersion { NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; if (![FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) { return NO; } FBSDKShareDialogValidateAPISchemeRegisteredForCanOpenUrl(); NSString *scheme = FBSDK_CANOPENURL_FBAPI; NSURLComponents *components = [[NSURLComponents alloc] init]; components.scheme = [scheme stringByAppendingString:minimumVersion]; components.path = @"/"; return [[UIApplication sharedApplication] canOpenURL:components.URL]; } - (void)_cleanUpWebDialog { _webDialog.delegate = nil; _webDialog = nil; } - (NSArray *)_contentImages { NSMutableArray *ret = [NSMutableArray new]; id shareContent = self.shareContent; if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) { [ret addObjectsFromArray:[((FBSDKSharePhotoContent *)shareContent).photos valueForKeyPath:@"@distinctUnionOfObjects.image"]]; } else if ([shareContent isKindOfClass:[FBSDKShareMediaContent class]]) { for (id media in ((FBSDKShareMediaContent *)shareContent).media) { if ([media isKindOfClass:[FBSDKSharePhoto class]]) { UIImage *image = ((FBSDKSharePhoto *)media).image; if (image != nil) { [ret addObject:image]; } } } } return [ret copy]; } - (NSArray *)_contentVideoURLs { NSMutableArray *ret = [NSMutableArray new]; id shareContent = self.shareContent; if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { NSURL *videoURL = ((FBSDKShareVideoContent *)shareContent).video.videoURL; if (videoURL != nil) { [ret addObject:videoURL]; } } else if ([shareContent isKindOfClass:[FBSDKShareMediaContent class]]) { for (id media in ((FBSDKShareMediaContent *)shareContent).media) { if ([media isKindOfClass:[FBSDKShareVideo class]]) { NSURL *videoURL = ((FBSDKShareVideo *)media).videoURL; if (videoURL != nil) { [ret addObject:videoURL]; } } } } return [ret copy]; } - (NSArray *)_contentURLs { NSArray *URLs = nil; id shareContent = self.shareContent; if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { FBSDKShareLinkContent *linkContent = (FBSDKShareLinkContent *)shareContent; URLs = (linkContent.contentURL ? @[linkContent.contentURL] : nil); } else if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) { FBSDKSharePhotoContent *photoContent = (FBSDKSharePhotoContent *)shareContent; URLs = (photoContent.contentURL ? @[photoContent.contentURL] : nil); } return URLs; } - (void)_handleWebResponseParameters:(NSDictionary *)webResponseParameters error:(NSError *)error { if (error) { [self _invokeDelegateDidFailWithError:error]; return; } else { NSString *completionGesture = webResponseParameters[FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY]; if ([completionGesture isEqualToString:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_CANCEL]) { [self _invokeDelegateDidCancel]; } else { // not all web dialogs report cancellation, so assume that the share has completed with no additional information NSMutableDictionary *results = [[NSMutableDictionary alloc] init]; // the web response comes back with a different payload, so we need to translate it [FBSDKInternalUtility dictionary:results setObject:webResponseParameters[FBSDK_SHARE_WEB_PARAM_POST_ID_KEY] forKey:FBSDK_SHARE_RESULT_POST_ID_KEY]; [self _invokeDelegateDidCompleteWithResults:results]; } } } - (BOOL)_photoContentHasAtLeastOneImage:(FBSDKSharePhotoContent *)photoContent { for (FBSDKSharePhoto *photo in photoContent.photos) { if (photo.image != nil) { return YES; } } return NO; } - (BOOL)_showBrowser:(NSError **)errorRef { if (![self _validateShareContentForBrowser:errorRef]) { return NO; } id shareContent = self.shareContent; NSString *methodName; NSDictionary *parameters; if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]] && [self _photoContentHasAtLeastOneImage:(FBSDKSharePhotoContent *)shareContent]) { void(^completion)(BOOL, NSString *, NSDictionary *) = ^(BOOL successfullyBuilt, NSString *cMethodName, NSDictionary *cParameters) { if (successfullyBuilt) { FBSDKBridgeAPICallbackBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) { [self _handleWebResponseParameters:response.responseParameters error:response.error]; [FBSDKInternalUtility unregisterTransientObject:self]; }; FBSDKBridgeAPIRequest *request; request = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeWeb scheme:FBSDK_SHARE_WEB_SCHEME methodName:cMethodName methodVersion:nil parameters:cParameters userInfo:nil]; [[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:request useSafariViewController:[self _useSafariViewController] fromViewController:self.fromViewController completionBlock:completionBlock]; } }; [FBSDKShareUtility buildAsyncWebPhotoContent:shareContent completionHandler:completion]; } else { if (![FBSDKShareUtility buildWebShareContent:shareContent methodName:&methodName parameters:¶meters error:errorRef]) { return NO; } FBSDKBridgeAPICallbackBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) { [self _handleWebResponseParameters:response.responseParameters error:response.error]; [FBSDKInternalUtility unregisterTransientObject:self]; }; FBSDKBridgeAPIRequest *request; request = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeWeb scheme:FBSDK_SHARE_WEB_SCHEME methodName:methodName methodVersion:nil parameters:parameters userInfo:nil]; [[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:request useSafariViewController:[self _useSafariViewController] fromViewController:self.fromViewController completionBlock:completionBlock]; } return YES; } - (BOOL)_showFeedBrowser:(NSError **)errorRef { if (![self _validateShareContentForFeed:errorRef]) { return NO; } id shareContent = self.shareContent; NSDictionary *parameters = [FBSDKShareUtility feedShareDictionaryForContent:shareContent]; FBSDKBridgeAPICallbackBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) { [self _handleWebResponseParameters:response.responseParameters error:response.error]; [FBSDKInternalUtility unregisterTransientObject:self]; }; FBSDKBridgeAPIRequest *request; request = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeWeb scheme:FBSDK_SHARE_WEB_SCHEME methodName:FBSDK_SHARE_FEED_METHOD_NAME methodVersion:nil parameters:parameters userInfo:nil]; [[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:request useSafariViewController:[self _useSafariViewController] fromViewController:self.fromViewController completionBlock:completionBlock]; return YES; } - (BOOL)_showFeedWeb:(NSError **)errorRef { if (![self _validateShareContentForFeed:errorRef]) { return NO; } id shareContent = self.shareContent; NSDictionary *parameters = [FBSDKShareUtility feedShareDictionaryForContent:shareContent]; _webDialog = [FBSDKWebDialog showWithName:FBSDK_SHARE_FEED_METHOD_NAME parameters:parameters delegate:self]; return YES; } - (BOOL)_showNativeWithCanShowError:(NSError **)canShowErrorRef validationError:(NSError **)validationErrorRef { if (![self _canShowNative]) { if (canShowErrorRef != NULL) { *canShowErrorRef = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode message:@"Native share dialog is not available."]; } return NO; } if (![self _validateShareContentForNative:validationErrorRef]) { return NO; } NSString *methodName; NSString *methodVersion; [self _loadNativeMethodName:&methodName methodVersion:&methodVersion]; NSDictionary *parameters = [FBSDKShareUtility parametersForShareContent:self.shareContent shouldFailOnDataError:self.shouldFailOnDataError]; FBSDKBridgeAPIRequest *request; request = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeNative scheme:FBSDK_CANOPENURL_FACEBOOK methodName:methodName methodVersion:methodVersion parameters:parameters userInfo:nil]; FBSDKBridgeAPICallbackBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) { if (response.error.code == FBSDKAppVersionUnsupportedErrorCode) { NSError *fallbackError; if ([self _showShareSheetWithCanShowError:NULL validationError:&fallbackError] || [self _showFeedBrowser:&fallbackError]) { return; } } NSDictionary *responseParameters = response.responseParameters; NSString *completionGesture = responseParameters[FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY]; if ([completionGesture isEqualToString:FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_CANCEL] || response.isCancelled) { [self _invokeDelegateDidCancel]; } else if (response.error) { [self _invokeDelegateDidFailWithError:response.error]; } else { NSMutableDictionary *results = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:results setObject:responseParameters[FBSDK_SHARE_RESULT_POST_ID_KEY] forKey:FBSDK_SHARE_RESULT_POST_ID_KEY]; [self _invokeDelegateDidCompleteWithResults:results]; } [FBSDKInternalUtility unregisterTransientObject:self]; }; [[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:request useSafariViewController:[self _useSafariViewController] fromViewController:self.fromViewController completionBlock:completionBlock]; return YES; } - (BOOL)_showShareSheetWithCanShowError:(NSError **)canShowErrorRef validationError:(NSError **)validationErrorRef { if (![self _canShowShareSheet]) { if (canShowErrorRef != NULL) { *canShowErrorRef = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode message:@"Share sheet is not available."]; } return NO; } if (![self _validateShareContentForShareSheet:validationErrorRef]) { return NO; } UIViewController *fromViewController = self.fromViewController; if (!fromViewController) { if (validationErrorRef != NULL) { *validationErrorRef = [FBSDKShareError requiredArgumentErrorWithName:@"fromViewController" message:nil]; } return NO; } NSArray *images = [self _contentImages]; NSArray *URLs = [self _contentURLs]; NSArray *videoURLs = [self _contentVideoURLs]; Class composeViewControllerClass = [fbsdkdfl_SLComposeViewControllerClass() class]; NSString *facebookServiceType = fbsdkdfl_SLServiceTypeFacebook(); SLComposeViewController *composeViewController; composeViewController = [composeViewControllerClass composeViewControllerForServiceType:facebookServiceType]; if (!composeViewController) { if (canShowErrorRef != NULL) { *canShowErrorRef = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode message:@"Error creating SLComposeViewController."]; } return NO; } NSString *initialText = [self _calculateInitialText]; if (initialText.length > 0) { [composeViewController setInitialText:initialText]; } for (UIImage *image in images) { [composeViewController addImage:image]; } for (NSURL *URL in URLs) { [composeViewController addURL:URL]; } for (NSURL *videoURL in videoURLs) { [composeViewController addURL:videoURL]; } composeViewController.completionHandler = ^(SLComposeViewControllerResult result) { switch (result) { case SLComposeViewControllerResultCancelled:{ [self _invokeDelegateDidCancel]; break; } case SLComposeViewControllerResultDone:{ [self _invokeDelegateDidCompleteWithResults:@{}]; break; } } dispatch_async(dispatch_get_main_queue(), ^{ [FBSDKInternalUtility unregisterTransientObject:self]; }); }; [fromViewController presentViewController:composeViewController animated:YES completion:nil]; return YES; } - (BOOL)_showWeb:(NSError **)errorRef { if (![self _validateShareContentForBrowser:errorRef]) { return NO; } id shareContent = self.shareContent; NSString *methodName; NSDictionary *parameters; if (![FBSDKShareUtility buildWebShareContent:shareContent methodName:&methodName parameters:¶meters error:errorRef]) { return NO; } _webDialog = [FBSDKWebDialog showWithName:methodName parameters:parameters delegate:self]; return YES; } - (BOOL)_useNativeDialog { FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration]; return [configuration useNativeDialogForDialogName:FBSDKDialogConfigurationNameShare]; } - (BOOL)_useSafariViewController { FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration]; return [configuration useSafariViewControllerForDialogName:FBSDKDialogConfigurationNameShare]; } - (BOOL)_validateWithError:(NSError *__autoreleasing *)errorRef { if (errorRef != NULL) { *errorRef = nil; } id shareContent = self.shareContent; if (!shareContent) { if (errorRef != NULL) { *errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"shareContent" message:nil]; } return NO; } if (![FBSDKShareUtility validateShareContent:shareContent error:errorRef]) { return NO; } if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { if (![FBSDKShareUtility validateAssetLibraryURLWithShareVideoContent:(FBSDKShareVideoContent *)shareContent name:@"videoURL" error:errorRef]) { return NO; } } if ([shareContent isKindOfClass:[FBSDKShareMediaContent class]]) { if (![FBSDKShareUtility validateAssetLibraryURLsWithShareMediaContent:(FBSDKShareMediaContent *)shareContent name:@"mediaVideoURL" error:errorRef]) { return NO; } } switch (self.mode) { case FBSDKShareDialogModeAutomatic:{ return ( ([self _canShowNative] && [self _validateShareContentForNative:errorRef]) || ([self _canShowShareSheet] && [self _validateShareContentForShareSheet:errorRef]) || [self _validateShareContentForFeed:errorRef] || [self _validateShareContentForBrowser:errorRef]); } case FBSDKShareDialogModeNative:{ return [self _validateShareContentForNative:errorRef]; } case FBSDKShareDialogModeShareSheet:{ return [self _validateShareContentForShareSheet:errorRef]; } case FBSDKShareDialogModeBrowser: case FBSDKShareDialogModeWeb:{ return [self _validateShareContentForBrowser:errorRef]; } case FBSDKShareDialogModeFeedBrowser: case FBSDKShareDialogModeFeedWeb:{ return [self _validateShareContentForFeed:errorRef]; } } } /** `validateWithError:` can be used by clients of this API to discover if certain features are available for a specific `mode`. However, these features could be optional for said `mode`, in which case `validateWithError:` should return NO but when calling `show`, the dialog must still show. ie: Quotes are only available if FB for iOS v52 or higher is installed. If the client adds a quote to the `ShareLinkContent` object and FB for iOS v52 or higher is not installed, `validateWithError:` will return NO if the `mode` is set to ShareSheet. However, calling `show` will actually show the shareSheet without the Quote. This method exists to enable the behavior described above and should only be called from `validateWithError:`. */ - (BOOL)_validateFullyCompatibleWithError:(NSError *__autoreleasing *)errorRef { id shareContent = self.shareContent; if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { FBSDKShareLinkContent *shareLinkContent = (FBSDKShareLinkContent *)shareContent; if (shareLinkContent.quote.length > 0 && self.mode == FBSDKShareDialogModeShareSheet && ![self _canUseQuoteInShareSheet]) { if ((errorRef != NULL) && !*errorRef) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareLinkContent message:@"Quotes are only supported if Facebook for iOS version 52 and above is installed"]; } return NO; } } else if ([shareContent isKindOfClass:[FBSDKShareMediaContent class]]) { FBSDKShareMediaContent *mediaContent = (FBSDKShareMediaContent *)shareContent; if ([FBSDKShareUtility shareMediaContentContainsPhotosAndVideos:mediaContent] && self.mode == FBSDKShareDialogModeShareSheet && ![self _canUseMMPInShareSheet]) { if ((errorRef != NULL) && !*errorRef) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:@"Multimedia content (photos + videos) is only supported if Facebook for iOS version 52 and above is installed"]; } return NO; } } return YES; } - (BOOL)_validateShareContentForBrowser:(NSError **)errorRef { id shareContent = self.shareContent; BOOL containsMedia; BOOL containsPhotos; [FBSDKShareUtility testShareContent:shareContent containsMedia:&containsMedia containsPhotos:&containsPhotos containsVideos:NULL]; if (containsPhotos) { if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) { if ([FBSDKAccessToken currentAccessToken] != nil) { return YES; } if ((errorRef != NULL) && !*errorRef) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:@"The web share dialog needs a valid access token to stage photos."]; } return NO; } else { if ((errorRef != NULL) && !*errorRef) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:@"Web share dialogs cannot include photos."]; } return NO; } } if (containsMedia) { if ((errorRef != NULL) && !*errorRef) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:@"Web share dialogs cannot include local media."]; } return NO; } return YES; } - (BOOL)_validateShareContentForFeed:(NSError **)errorRef { id shareContent = self.shareContent; if (![shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { if ((errorRef != NULL) && !*errorRef) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:@"Feed share dialogs support FBSDKShareLinkContent."]; } return NO; } return YES; } - (BOOL)_validateShareContentForNative:(NSError **)errorRef { id shareContent = self.shareContent; if ([shareContent isKindOfClass:[FBSDKShareMediaContent class]]) { if ([FBSDKShareUtility shareMediaContentContainsPhotosAndVideos:(FBSDKShareMediaContent *)shareContent]) { if ((errorRef != NULL) && !*errorRef) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:@"Multimedia Content is only available for mode `ShareSheet`"]; } return NO; } } if (![shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { return YES; } return [self _validateVideoURL:((FBSDKShareVideoContent *)shareContent).video.videoURL error:errorRef]; } - (BOOL)_validateShareContentForShareSheet:(NSError **)errorRef { id shareContent = self.shareContent; if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) { if ([self _contentImages].count != 0) { return YES; } else { if ((errorRef != NULL) && !*errorRef) { NSString *message = @"Share photo content must have UIImage photos in order to share with the share sheet"; *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:message]; } return NO; } } else if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { return ([self _canUseFBShareSheet] && [self _validateVideoURL:((FBSDKShareVideoContent *)shareContent).video.videoURL error:errorRef]); } else if ([shareContent isKindOfClass:[FBSDKShareMediaContent class]]) { return ([self _canUseFBShareSheet] && [FBSDKShareUtility validateShareMediaContent:(FBSDKShareMediaContent *)shareContent error:errorRef]); } else if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) { FBSDKShareOpenGraphContent *ogContent = (FBSDKShareOpenGraphContent *)shareContent; BOOL isOGURLShare = [self _isOpenGraphURLShare:ogContent]; BOOL isValidOGShare = (isOGURLShare && [ogContent.action.actionType length] != 0 && [ogContent.previewPropertyName length] != 0); if (!isValidOGShare) { if ((errorRef != NULL) && !*errorRef) { NSString *message = @"Share content must include an URL in the action, an action type, and a preview property name in order to share with the share sheet."; *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:message]; } } return isValidOGShare; } else if (![shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { if ((errorRef != NULL) && !*errorRef) { NSString *message = @"Share content must be FBSDKShareLinkContent or FBSDKShareMediaContent in order to share " @"with the share sheet."; *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:message]; } return NO; } return YES; } - (BOOL)_validateVideoURL:(NSURL *)videoURL error:(NSError **)errorRef { if (videoURL.isFileURL) { if ((errorRef != NULL) && !*errorRef) { NSString *message = @"Only asset file URLs are allowed for videos."; *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"videoURL" value:videoURL message:message]; } return NO; } return YES; } - (void)_invokeDelegateDidCancel { NSDictionary * parameters = @{ FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Cancelled, }; [FBSDKAppEvents logImplicitEvent:FBSDLAppEventNameFBSDKEventShareDialogResult valueToSum:nil parameters:parameters accessToken:[FBSDKAccessToken currentAccessToken]]; [_delegate sharerDidCancel:self]; } - (void)_invokeDelegateDidCompleteWithResults:(NSDictionary *)results { NSDictionary * parameters = @{ FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Completed }; [FBSDKAppEvents logImplicitEvent:FBSDLAppEventNameFBSDKEventShareDialogResult valueToSum:nil parameters:parameters accessToken:[FBSDKAccessToken currentAccessToken]]; [_delegate sharer:self didCompleteWithResults:[results copy]]; } - (void)_invokeDelegateDidFailWithError:(NSError *)error { NSDictionary * parameters = @{ FBSDKAppEventParameterDialogOutcome : FBSDKAppEventsDialogOutcomeValue_Failed, FBSDKAppEventParameterDialogErrorMessage : [NSString stringWithFormat:@"%@", error] }; [FBSDKAppEvents logImplicitEvent:FBSDLAppEventNameFBSDKEventShareDialogResult valueToSum:nil parameters:parameters accessToken:[FBSDKAccessToken currentAccessToken]]; [_delegate sharer:self didFailWithError:error]; } - (void)_logDialogShow { NSString *shareMode = NSStringFromFBSDKShareDialogMode(self.mode); NSString *contentType; if([self.shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) { contentType = FBSDKAppEventsDialogShareContentTypeOpenGraph; } else if ([self.shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { contentType = FBSDKAppEventsDialogShareContentTypeStatus; } else if ([self.shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) { contentType = FBSDKAppEventsDialogShareContentTypePhoto; } else if ([self.shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { contentType = FBSDKAppEventsDialogShareContentTypeVideo; } else { contentType = FBSDKAppEventsDialogShareContentTypeUnknown; } NSDictionary *parameters = @{ FBSDKAppEventParameterDialogMode : shareMode, FBSDKAppEventParameterDialogShareContentType : contentType, }; [FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKEventShareDialogShow valueToSum:nil parameters:parameters accessToken:[FBSDKAccessToken currentAccessToken]]; } - (NSString *)_calculateInitialText { NSString *initialText; if ([self _canAttributeThroughShareSheet]) { NSMutableDictionary *initialTextDictionary = [NSMutableDictionary new]; initialTextDictionary[@"app_id"] = [FBSDKSettings appID]; NSString *hashtag = [FBSDKShareUtility hashtagStringFromHashtag:self.shareContent.hashtag]; if (hashtag != nil) { initialTextDictionary[@"hashtags"] = @[hashtag]; } if ([self.shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { NSString *quote = [(FBSDKShareLinkContent *)self.shareContent quote]; if (quote != nil) { initialTextDictionary[@"quotes"] = @[quote]; } } if ([self.shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) { NSDictionary *ogData = [FBSDKShareUtility parametersForShareContent:self.shareContent shouldFailOnDataError:self.shouldFailOnDataError]; initialTextDictionary[@"og_data"] = ogData; } NSError *error = nil; NSString *jsonString = [FBSDKInternalUtility JSONStringForObject:initialTextDictionary error:&error invalidObjectHandler:NULL]; if (error != nil) { return nil; } NSString *JSONStartDelimiter = @"|"; initialText = [NSString stringWithFormat:@"%@%@%@", [self _calculatePreJSONInitialTextWithHashtag:hashtag], JSONStartDelimiter, jsonString]; } else { NSString *hashtag = [FBSDKShareUtility hashtagStringFromHashtag:self.shareContent.hashtag]; if (hashtag != nil) { initialText = hashtag; } } return initialText; } // Not all versions of the Share Extension support JSON. Adding this text before allows backward compatibility - (NSString *)_calculatePreJSONInitialTextWithHashtag:(NSString *)hashtag { NSMutableString *text = [NSMutableString new]; [text appendString:[NSString stringWithFormat:@"fb-app-id:%@", [FBSDKSettings appID]]]; if (hashtag != nil) { [text appendString:@" "]; [text appendString:hashtag]; } return [text copy]; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialogMode.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /*! @typedef NS_ENUM(NSUInteger, FBSDKShareDialogMode) @abstract Modes for the FBSDKShareDialog. @discussion The automatic mode will progressively check the availability of different modes and open the most appropriate mode for the dialog that is available. */ typedef NS_ENUM(NSUInteger, FBSDKShareDialogMode) { /*! @abstract Acts with the most appropriate mode that is available. */ FBSDKShareDialogModeAutomatic = 0, /*! @Displays the dialog in the main native Facebook app. */ FBSDKShareDialogModeNative, /*! @Displays the dialog in the iOS integrated share sheet. */ FBSDKShareDialogModeShareSheet, /*! @Displays the dialog in Safari. */ FBSDKShareDialogModeBrowser, /*! @Displays the dialog in a UIWebView within the app. */ FBSDKShareDialogModeWeb, /*! @Displays the feed dialog in Safari. */ FBSDKShareDialogModeFeedBrowser, /*! @Displays the feed dialog in a UIWebView within the app. */ FBSDKShareDialogModeFeedWeb, }; /*! @abstract Converts an FBLikeControlObjectType to an NSString. */ FBSDK_EXTERN NSString *NSStringFromFBSDKShareDialogMode(FBSDKShareDialogMode dialogMode); ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareDialogMode.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareDialogMode.h" #import "FBSDKCoreKit+Internal.h" NSString *NSStringFromFBSDKShareDialogMode(FBSDKShareDialogMode dialogMode) { switch (dialogMode) { case FBSDKShareDialogModeAutomatic:{ return FBSDKAppEventsDialogShareModeAutomatic; } case FBSDKShareDialogModeBrowser:{ return FBSDKAppEventsDialogShareModeBrowser; } case FBSDKShareDialogModeNative:{ return FBSDKAppEventsDialogShareModeNative; } case FBSDKShareDialogModeShareSheet:{ return FBSDKAppEventsDialogShareModeShareSheet; } case FBSDKShareDialogModeWeb:{ return FBSDKAppEventsDialogShareModeWeb; } case FBSDKShareDialogModeFeedBrowser: { return FBSDKAppEventsDialogShareModeFeedBrowser; } case FBSDKShareDialogModeFeedWeb:{ return FBSDKAppEventsDialogShareModeFeedWeb; } default:{ return FBSDKAppEventsDialogShareModeUnknown; } } } ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import #import #import #import #import #import #import #import #import #import #import #if !TARGET_OS_TV #import #import #import #import #import #import #import #import #import #import #import #import #import #import #import #import #else #import #import #endif ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareLinkContent.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /*! @abstract A model for status and link content to be shared. */ @interface FBSDKShareLinkContent : NSObject /*! @abstract The description of the link. @discussion If not specified, this field is automatically populated by information scraped from the contentURL, typically the title of the page. This value may be discarded for specially handled links (ex: iTunes URLs). @return The description of the link */ @property (nonatomic, copy) NSString *contentDescription; /*! @abstract The title to display for this link. @discussion This value may be discarded for specially handled links (ex: iTunes URLs). @return The link title */ @property (nonatomic, copy) NSString *contentTitle; /*! @abstract The URL of a picture to attach to this content. @return The network URL of an image */ @property (nonatomic, copy) NSURL *imageURL; /*! @abstract Some quote text of the link. @discussion If specified, the quote text will render with custom styling on top of the link. @return The quote text of a link */ @property (nonatomic, copy) NSString *quote; /*! @abstract Compares the receiver to another link content. @param content The other content @return YES if the receiver's values are equal to the other content's values; otherwise NO */ - (BOOL)isEqualToShareLinkContent:(FBSDKShareLinkContent *)content; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareLinkContent.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareLinkContent+Internal.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKHashtag.h" #import "FBSDKShareUtility.h" #define FBSDK_SHARE_STATUS_CONTENT_CONTENT_DESCRIPTION_KEY @"contentDescription" #define FBSDK_SHARE_STATUS_CONTENT_CONTENT_TITLE_KEY @"contentTitle" #define FBSDK_SHARE_STATUS_CONTENT_CONTENT_URL_KEY @"contentURL" #define FBSDK_SHARE_STATUS_CONTENT_HASHTAG_KEY @"hashtag" #define FBSDK_SHARE_STATUS_CONTENT_IMAGE_URL_KEY @"imageURL" #define FBSDK_SHARE_STATUS_CONTENT_PEOPLE_IDS_KEY @"peopleIDs" #define FBSDK_SHARE_STATUS_CONTENT_PLACE_ID_KEY @"placeID" #define FBSDK_SHARE_STATUS_CONTENT_REF_KEY @"ref" #define FBSDK_SHARE_STATUS_CONTENT_QUOTE_TEXT_KEY @"quote" #define FBSDK_SHARE_STATUS_CONTENT_FEED_PARAMETERS_KEY @"feedParameters" @implementation FBSDKShareLinkContent #pragma mark - Properties @synthesize contentURL = _contentURL; @synthesize hashtag = _hashtag; @synthesize peopleIDs = _peopleIDs; @synthesize placeID = _placeID; @synthesize ref = _ref; @synthesize feedParameters = _feedParameters; @synthesize quote = _quote; - (void)setPeopleIDs:(NSArray *)peopleIDs { [FBSDKShareUtility assertCollection:peopleIDs ofClass:[NSString class] name:@"peopleIDs"]; if (![FBSDKInternalUtility object:_peopleIDs isEqualToObject:peopleIDs]) { _peopleIDs = [peopleIDs copy]; } } - (void)setFeedParameters:(NSDictionary *)feedParameters { if (![_feedParameters isEqualToDictionary:feedParameters]) { _feedParameters = [feedParameters copy]; } } #pragma mark - Equality - (NSUInteger)hash { NSUInteger subhashes[] = { [_contentDescription hash], [_contentURL hash], [_hashtag hash], [_imageURL hash], [_peopleIDs hash], [_placeID hash], [_ref hash], [_contentTitle hash], [_feedParameters hash], [_quote hash], }; return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKShareLinkContent class]]) { return NO; } return [self isEqualToShareLinkContent:(FBSDKShareLinkContent *)object]; } - (BOOL)isEqualToShareLinkContent:(FBSDKShareLinkContent *)content { return (content && [FBSDKInternalUtility object:_contentDescription isEqualToObject:content.contentDescription] && [FBSDKInternalUtility object:_contentTitle isEqualToObject:content.contentTitle] && [FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] && [FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] && [FBSDKInternalUtility object:_feedParameters isEqualToObject:content.feedParameters] && [FBSDKInternalUtility object:_imageURL isEqualToObject:content.imageURL] && [FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] && [FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] && [FBSDKInternalUtility object:_ref isEqualToObject:content.ref]) && [FBSDKInternalUtility object:_quote isEqualToObject:content.quote]; } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [self init])) { _contentDescription = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_STATUS_CONTENT_CONTENT_DESCRIPTION_KEY]; _contentTitle = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_STATUS_CONTENT_CONTENT_TITLE_KEY]; _contentURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_STATUS_CONTENT_CONTENT_URL_KEY]; _feedParameters = [decoder decodeObjectOfClass:[NSDictionary class] forKey:FBSDK_SHARE_STATUS_CONTENT_FEED_PARAMETERS_KEY]; _hashtag = [decoder decodeObjectOfClass:[FBSDKHashtag class] forKey:FBSDK_SHARE_STATUS_CONTENT_HASHTAG_KEY]; _imageURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_STATUS_CONTENT_IMAGE_URL_KEY]; _peopleIDs = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_SHARE_STATUS_CONTENT_PEOPLE_IDS_KEY]; _placeID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_STATUS_CONTENT_PLACE_ID_KEY]; _ref = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_STATUS_CONTENT_REF_KEY]; _quote = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_STATUS_CONTENT_QUOTE_TEXT_KEY]; } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_contentDescription forKey:FBSDK_SHARE_STATUS_CONTENT_CONTENT_DESCRIPTION_KEY]; [encoder encodeObject:_contentTitle forKey:FBSDK_SHARE_STATUS_CONTENT_CONTENT_TITLE_KEY]; [encoder encodeObject:_contentURL forKey:FBSDK_SHARE_STATUS_CONTENT_CONTENT_URL_KEY]; [encoder encodeObject:_feedParameters forKey:FBSDK_SHARE_STATUS_CONTENT_FEED_PARAMETERS_KEY]; [encoder encodeObject:_hashtag forKey:FBSDK_SHARE_STATUS_CONTENT_HASHTAG_KEY]; [encoder encodeObject:_imageURL forKey:FBSDK_SHARE_STATUS_CONTENT_IMAGE_URL_KEY]; [encoder encodeObject:_peopleIDs forKey:FBSDK_SHARE_STATUS_CONTENT_PEOPLE_IDS_KEY]; [encoder encodeObject:_placeID forKey:FBSDK_SHARE_STATUS_CONTENT_PLACE_ID_KEY]; [encoder encodeObject:_ref forKey:FBSDK_SHARE_STATUS_CONTENT_REF_KEY]; [encoder encodeObject:_quote forKey:FBSDK_SHARE_STATUS_CONTENT_QUOTE_TEXT_KEY]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { FBSDKShareLinkContent *copy = [[FBSDKShareLinkContent alloc] init]; copy->_contentDescription = [_contentDescription copy]; copy->_contentTitle = [_contentTitle copy]; copy->_contentURL = [_contentURL copy]; copy->_feedParameters = [_feedParameters copy]; copy->_hashtag = [_hashtag copy]; copy->_imageURL = [_imageURL copy]; copy->_peopleIDs = [_peopleIDs copy]; copy->_placeID = [_placeID copy]; copy->_ref = [_ref copy]; copy->_quote = [_quote copy]; return copy; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareMediaContent.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /*! @abstract A model for media content (photo or video) to be shared. */ @interface FBSDKShareMediaContent : NSObject /*! @abstract Media to be shared. @return Array of the media (FBSDKSharePhoto or FBSDKShareVideo) */ @property (nonatomic, copy) NSArray *media; /*! @abstract Compares the receiver to another media content. @param content The other content @return YES if the receiver's values are equal to the other content's values; otherwise NO */ - (BOOL)isEqualToShareMediaContent:(FBSDKShareMediaContent *)content; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareMediaContent.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareMediaContent.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKHashtag.h" #import "FBSDKSharePhoto.h" #import "FBSDKShareUtility.h" #import "FBSDKShareVideo.h" #define FBSDK_SHARE_MEDIA_CONTENT_CONTENT_URL_KEY @"contentURL" #define FBSDK_SHARE_MEDIA_CONTENT_HASHTAG_KEY @"hashtag" #define FBSDK_SHARE_MEDIA_CONTENT_PEOPLE_IDS_KEY @"peopleIDs" #define FBSDK_SHARE_MEDIA_CONTENT_MEDIA_KEY @"media" #define FBSDK_SHARE_MEDIA_CONTENT_PLACE_ID_KEY @"placeID" #define FBSDK_SHARE_MEDIA_CONTENT_REF_KEY @"ref" @implementation FBSDKShareMediaContent #pragma mark - Properties @synthesize contentURL = _contentURL; @synthesize hashtag = _hashtag; @synthesize peopleIDs = _peopleIDs; @synthesize placeID = _placeID; @synthesize ref = _ref; - (void)setPeopleIDs:(NSArray *)peopleIDs { [FBSDKShareUtility assertCollection:peopleIDs ofClass:[NSString class] name:@"peopleIDs"]; if (![FBSDKInternalUtility object:_peopleIDs isEqualToObject:peopleIDs]) { _peopleIDs = [peopleIDs copy]; } } - (void)setMedia:(NSArray *)media { [FBSDKShareUtility assertCollection:media ofClassStrings:@[NSStringFromClass([FBSDKSharePhoto class]), NSStringFromClass([FBSDKShareVideo class])] name:@"media"]; if (![FBSDKInternalUtility object:_media isEqualToObject:media]) { _media = [media copy]; } } #pragma mark - Equality - (NSUInteger)hash { NSUInteger subhashes[] = { [_contentURL hash], [_hashtag hash], [_peopleIDs hash], [_media hash], [_placeID hash], [_ref hash], }; return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKShareMediaContent class]]) { return NO; } return [self isEqualToShareMediaContent:(FBSDKShareMediaContent *)object]; } - (BOOL)isEqualToShareMediaContent:(FBSDKShareMediaContent *)content { return (content && [FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] && [FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] && [FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] && [FBSDKInternalUtility object:_media isEqualToObject:content.media] && [FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] && [FBSDKInternalUtility object:_ref isEqualToObject:content.ref]); } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [self init])) { _contentURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_MEDIA_CONTENT_CONTENT_URL_KEY]; _hashtag = [decoder decodeObjectOfClass:[FBSDKHashtag class] forKey:FBSDK_SHARE_MEDIA_CONTENT_HASHTAG_KEY]; _peopleIDs = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_SHARE_MEDIA_CONTENT_PEOPLE_IDS_KEY]; NSSet *classes = [NSSet setWithObjects:[NSArray class], [FBSDKSharePhoto class], nil]; _media = [decoder decodeObjectOfClasses:classes forKey:FBSDK_SHARE_MEDIA_CONTENT_MEDIA_KEY]; _placeID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_MEDIA_CONTENT_PLACE_ID_KEY]; _ref = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_MEDIA_CONTENT_REF_KEY]; } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_contentURL forKey:FBSDK_SHARE_MEDIA_CONTENT_CONTENT_URL_KEY]; [encoder encodeObject:_hashtag forKey:FBSDK_SHARE_MEDIA_CONTENT_HASHTAG_KEY]; [encoder encodeObject:_peopleIDs forKey:FBSDK_SHARE_MEDIA_CONTENT_PEOPLE_IDS_KEY]; [encoder encodeObject:_media forKey:FBSDK_SHARE_MEDIA_CONTENT_MEDIA_KEY]; [encoder encodeObject:_placeID forKey:FBSDK_SHARE_MEDIA_CONTENT_PLACE_ID_KEY]; [encoder encodeObject:_ref forKey:FBSDK_SHARE_MEDIA_CONTENT_REF_KEY]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { FBSDKShareMediaContent *copy = [[FBSDKShareMediaContent alloc] init]; copy->_contentURL = [_contentURL copy]; copy->_hashtag = [_hashtag copy]; copy->_peopleIDs = [_peopleIDs copy]; copy->_media = [_media copy]; copy->_placeID = [_placeID copy]; copy->_ref = [_ref copy]; return copy; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphAction.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import /*! @abstract An Open Graph Action for sharing. @discussion The property keys MUST have namespaces specified on them, such as `og:image`. */ @interface FBSDKShareOpenGraphAction : FBSDKShareOpenGraphValueContainer /*! @abstract Convenience method to build a new action and set the object for the specified key. @param actionType The action type of the receiver @param object The Open Graph object represented by this action @param key The key for the object */ + (instancetype)actionWithType:(NSString *)actionType object:(FBSDKShareOpenGraphObject *)object key:(NSString *)key; /*! @abstract Convenience method to build a new action and set the object for the specified key. @param actionType The action type of the receiver @param objectID The ID of an existing Open Graph object @param key The key for the object */ + (instancetype)actionWithType:(NSString *)actionType objectID:(NSString *)objectID key:(NSString *)key; /*! @abstract Convenience method to build a new action and set the object for the specified key. @param actionType The action type of the receiver @param objectURL The URL to a page that defines the Open Graph object with meta tags @param key The key for the object */ + (instancetype)actionWithType:(NSString *)actionType objectURL:(NSURL *)objectURL key:(NSString *)key; /*! @abstract Gets the action type. @return The action type */ @property (nonatomic, copy) NSString *actionType; /*! @abstract Compares the receiver to another Open Graph Action. @param action The other action @return YES if the receiver's values are equal to the other action's values; otherwise NO */ - (BOOL)isEqualToShareOpenGraphAction:(FBSDKShareOpenGraphAction *)action; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphAction.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareOpenGraphAction.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKShareOpenGraphValueContainer+Internal.h" #define FBSDK_SHARE_OPEN_GRAPH_ACTION_TYPE_KEY @"type" @implementation FBSDKShareOpenGraphAction #pragma mark - Class Methods + (instancetype)actionWithType:(NSString *)actionType object:(FBSDKShareOpenGraphObject *)object key:(NSString *)key { FBSDKShareOpenGraphAction *action = [[FBSDKShareOpenGraphAction alloc] init]; action.actionType = actionType; [action setObject:object forKey:key]; return action; } + (instancetype)actionWithType:(NSString *)actionType objectID:(NSString *)objectID key:(NSString *)key { FBSDKShareOpenGraphAction *action = [[FBSDKShareOpenGraphAction alloc] init]; action.actionType = actionType; [action setString:objectID forKey:key]; return action; } + (instancetype)actionWithType:(NSString *)actionType objectURL:(NSURL *)objectURL key:(NSString *)key { FBSDKShareOpenGraphAction *action = [[FBSDKShareOpenGraphAction alloc] init]; action.actionType = actionType; [action setURL:objectURL forKey:key]; return action; } #pragma mark - Equality - (NSUInteger)hash { return [FBSDKMath hashWithInteger:[super hash] andInteger:[_actionType hash]]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKShareOpenGraphAction class]]) { return NO; } return [self isEqualToShareOpenGraphAction:(FBSDKShareOpenGraphAction *)object]; } - (BOOL)isEqualToShareOpenGraphAction:(FBSDKShareOpenGraphAction *)action { return (action && [FBSDKInternalUtility object:_actionType isEqualToObject:action.actionType] && [self isEqualToShareOpenGraphValueContainer:action]); } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [super initWithCoder:decoder])) { _actionType = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_OPEN_GRAPH_ACTION_TYPE_KEY]; } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [super encodeWithCoder:encoder]; [encoder encodeObject:_actionType forKey:FBSDK_SHARE_OPEN_GRAPH_ACTION_TYPE_KEY]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { FBSDKShareOpenGraphAction *copy = [[FBSDKShareOpenGraphAction alloc] init]; copy->_actionType = [_actionType copy]; [copy parseProperties:[self allProperties]]; return copy; } #pragma mark - Internal Methods - (BOOL)requireKeyNamespace { return NO; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphContent.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import /*! @abstract A model for Open Graph content to be shared. */ @interface FBSDKShareOpenGraphContent : NSObject /*! @abstract Open Graph Action to be shared. @return The action */ @property (nonatomic, copy) FBSDKShareOpenGraphAction *action; /*! @abstract Property name that points to the primary Open Graph Object in the action. @discussion The value that this action points to will be use for rendering the preview for the share. @return The property name for the Open Graph Object in the action */ @property (nonatomic, copy) NSString *previewPropertyName; /*! @abstract Compares the receiver to another Open Graph content. @param content The other content @return YES if the receiver's values are equal to the other content's values; otherwise NO */ - (BOOL)isEqualToShareOpenGraphContent:(FBSDKShareOpenGraphContent *)content; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphContent.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareOpenGraphContent.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKHashtag.h" #import "FBSDKSharePhoto.h" #import "FBSDKShareUtility.h" #define FBSDK_SHARE_OPEN_GRAPH_CONTENT_ACTION_KEY @"action" #define FBSDK_SHARE_OPEN_GRAPH_CONTENT_CONTENT_URL_KEY @"contentURL" #define FBSDK_SHARE_OPEN_GRAPH_CONTENT_HASHTAG_KEY @"hashtag" #define FBSDK_SHARE_OPEN_GRAPH_CONTENT_PEOPLE_IDS_KEY @"peopleIDs" #define FBSDK_SHARE_OPEN_GRAPH_CONTENT_PLACE_ID_KEY @"placeID" #define FBSDK_SHARE_OPEN_GRAPH_CONTENT_PREVIEW_PROPERTY_NAME_KEY @"previewPropertyName" #define FBSDK_SHARE_OPEN_GRAPH_CONTENT_REF_KEY @"ref" @implementation FBSDKShareOpenGraphContent #pragma mark - Properties @synthesize contentURL = _contentURL; @synthesize hashtag = _hashtag; @synthesize peopleIDs = _peopleIDs; @synthesize placeID = _placeID; @synthesize ref = _ref; - (void)setPeopleIDs:(NSArray *)peopleIDs { [FBSDKShareUtility assertCollection:peopleIDs ofClass:[NSString class] name:@"peopleIDs"]; if (![FBSDKInternalUtility object:_peopleIDs isEqualToObject:peopleIDs]) { _peopleIDs = [peopleIDs copy]; } } #pragma mark - Equality - (NSUInteger)hash { NSUInteger subhashes[] = { [_action hash], [_contentURL hash], [_hashtag hash], [_peopleIDs hash], [_placeID hash], [_previewPropertyName hash], [_ref hash], }; return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKShareOpenGraphContent class]]) { return NO; } return [self isEqualToShareOpenGraphContent:(FBSDKShareOpenGraphContent *)object]; } - (BOOL)isEqualToShareOpenGraphContent:(FBSDKShareOpenGraphContent *)content { return (content && [FBSDKInternalUtility object:_action isEqualToObject:content.action] && [FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] && [FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] && [FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] && [FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] && [FBSDKInternalUtility object:_previewPropertyName isEqualToObject:content.previewPropertyName] && [FBSDKInternalUtility object:_ref isEqualToObject:content.ref]); } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [super init])) { _action = [decoder decodeObjectOfClass:[FBSDKShareOpenGraphAction class] forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_ACTION_KEY]; _contentURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_CONTENT_URL_KEY]; _hashtag = [decoder decodeObjectOfClass:[FBSDKHashtag class] forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_HASHTAG_KEY]; _peopleIDs = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_PEOPLE_IDS_KEY]; _placeID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_PLACE_ID_KEY]; _previewPropertyName = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_PREVIEW_PROPERTY_NAME_KEY]; _ref = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_REF_KEY]; } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_action forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_ACTION_KEY]; [encoder encodeObject:_contentURL forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_CONTENT_URL_KEY]; [encoder encodeObject:_hashtag forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_HASHTAG_KEY]; [encoder encodeObject:_peopleIDs forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_PEOPLE_IDS_KEY]; [encoder encodeObject:_placeID forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_PLACE_ID_KEY]; [encoder encodeObject:_previewPropertyName forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_PREVIEW_PROPERTY_NAME_KEY]; [encoder encodeObject:_ref forKey:FBSDK_SHARE_OPEN_GRAPH_CONTENT_REF_KEY]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { FBSDKShareOpenGraphContent *copy = [[FBSDKShareOpenGraphContent alloc] init]; copy->_action = [_action copy]; copy->_contentURL = [_contentURL copy]; copy->_hashtag = [_hashtag copy]; copy->_peopleIDs = [_peopleIDs copy]; copy->_placeID = [_placeID copy]; copy->_previewPropertyName = [_previewPropertyName copy]; copy->_ref = [_ref copy]; return copy; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphObject.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import /*! @abstract An Open Graph Object for sharing. @discussion The property keys MUST have namespaces specified on them, such as `og:image`, and `og:type` is required. See https://developers.facebook.com/docs/sharing/opengraph/object-properties for other properties. You can specify nested namespaces inline to define complex properties. For example, the following code will generate a fitness.course object with a location: FBSDKShareOpenGraphObject *course = [FBSDKShareOpenGraphObject objectWithProperties: @{ @"og:type": @"fitness.course", @"og:title": @"Sample course", @"fitness:metrics:location:latitude": @"41.40338", @"fitness:metrics:location:longitude": @"2.17403", }]; */ @interface FBSDKShareOpenGraphObject : FBSDKShareOpenGraphValueContainer /*! @abstract Convenience method to build a new action and set the object for the specified key. @param properties Properties for the Open Graph object, which will be parsed into the proper models */ + (instancetype)objectWithProperties:(NSDictionary *)properties; /*! @abstract Compares the receiver to another Open Graph Object. @param object The other object @return YES if the receiver's values are equal to the other object's values; otherwise NO */ - (BOOL)isEqualToShareOpenGraphObject:(FBSDKShareOpenGraphObject *)object; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphObject.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareOpenGraphObject.h" #import "FBSDKShareOpenGraphValueContainer+Internal.h" #define FBSDK_SHARE_OPEN_GRAPH_OBJECT_DATA_KEY @"data" @implementation FBSDKShareOpenGraphObject #pragma mark - Class Methods + (instancetype)objectWithProperties:(NSDictionary *)properties { FBSDKShareOpenGraphObject *object = [[FBSDKShareOpenGraphObject alloc] init]; [object parseProperties:properties]; return object; } #pragma mark - Equality - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKShareOpenGraphObject class]]) { return NO; } return [self isEqualToShareOpenGraphObject:(FBSDKShareOpenGraphObject *)object]; } - (BOOL)isEqualToShareOpenGraphObject:(FBSDKShareOpenGraphObject *)object { return [self isEqualToShareOpenGraphValueContainer:object]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { FBSDKShareOpenGraphObject *copy = [[FBSDKShareOpenGraphObject alloc] init]; [copy parseProperties:[self allProperties]]; return copy; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphValueContainer.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @class FBSDKShareOpenGraphObject; @class FBSDKSharePhoto; /*! @abstract Protocol defining operations on open graph actions and objects. @discussion The property keys MUST have namespaces specified on them, such as `og:image`. */ @protocol FBSDKShareOpenGraphValueContaining /*! @abstract Gets an NSArray out of the receiver. @param key The key for the value @return The NSArray value or nil */ - (NSArray *)arrayForKey:(NSString *)key; /*! @abstract Applies a given block object to the entries of the receiver. @param block A block object to operate on entries in the receiver */ - (void)enumerateKeysAndObjectsUsingBlock:(void (^)(NSString *key, id object, BOOL *stop))block; /*! @abstract Returns an enumerator object that lets you access each key in the receiver. @return An enumerator object that lets you access each key in the receiver */ - (NSEnumerator *)keyEnumerator; /*! @abstract Gets an NSNumber out of the receiver. @param key The key for the value @return The NSNumber value or nil */ - (NSNumber *)numberForKey:(NSString *)key; /*! @abstract Returns an enumerator object that lets you access each value in the receiver. @return An enumerator object that lets you access each value in the receiver */ - (NSEnumerator *)objectEnumerator; /*! @abstract Gets an FBSDKShareOpenGraphObject out of the receiver. @param key The key for the value @return The FBSDKShareOpenGraphObject value or nil */ - (FBSDKShareOpenGraphObject *)objectForKey:(NSString *)key; /*! @abstract Enables subscript access to the values in the receiver. @param key The key for the value @return The value */ - (id)objectForKeyedSubscript:(NSString *)key; /*! @abstract Parses properties out of a dictionary into the receiver. @param properties The properties to parse. */ - (void)parseProperties:(NSDictionary *)properties; /*! @abstract Gets an FBSDKSharePhoto out of the receiver. @param key The key for the value @return The FBSDKSharePhoto value or nil */ - (FBSDKSharePhoto *)photoForKey:(NSString *)key; /*! @abstract Removes a value from the receiver for the specified key. @param key The key for the value */ - (void)removeObjectForKey:(NSString *)key; /*! @abstract Sets an NSArray on the receiver. @discussion This method will throw if the array contains any values that is not an NSNumber, NSString, NSURL, FBSDKSharePhoto or FBSDKShareOpenGraphObject. @param array The NSArray value @param key The key for the value */ - (void)setArray:(NSArray *)array forKey:(NSString *)key; /*! @abstract Sets an NSNumber on the receiver. @param number The NSNumber value @param key The key for the value */ - (void)setNumber:(NSNumber *)number forKey:(NSString *)key; /*! @abstract Sets an FBSDKShareOpenGraphObject on the receiver. @param object The FBSDKShareOpenGraphObject value @param key The key for the value */ - (void)setObject:(FBSDKShareOpenGraphObject *)object forKey:(NSString *)key; /*! @abstract Sets an FBSDKSharePhoto on the receiver. @param photo The FBSDKSharePhoto value @param key The key for the value */ - (void)setPhoto:(FBSDKSharePhoto *)photo forKey:(NSString *)key; /*! @abstract Sets an NSString on the receiver. @param string The NSString value @param key The key for the value */ - (void)setString:(NSString *)string forKey:(NSString *)key; /*! @abstract Sets an NSURL on the receiver. @param URL The NSURL value @param key The key for the value */ - (void)setURL:(NSURL *)URL forKey:(NSString *)key; /*! @abstract Gets an NSString out of the receiver. @param key The key for the value @return The NSString value or nil */ - (NSString *)stringForKey:(NSString *)key; /*! @abstract Gets an NSURL out of the receiver. @param key The key for the value @return The NSURL value or nil */ - (NSURL *)URLForKey:(NSString *)key; @end /*! @abstract A base class to container Open Graph values. */ @interface FBSDKShareOpenGraphValueContainer : NSObject @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphValueContainer.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareOpenGraphValueContainer.h" #import "FBSDKShareOpenGraphValueContainer+Internal.h" #import #import "FBSDKCoreKit+Internal.h" #import "FBSDKShareOpenGraphObject.h" #import "FBSDKSharePhoto.h" #import "FBSDKShareUtility.h" #define FBSDK_SHARE_OPEN_GRAPH_VALUE_CONTAINER_PROPERTIES_KEY @"properties" @implementation FBSDKShareOpenGraphValueContainer { NSMutableDictionary *_properties; } #pragma mark - Object Lifecycle - (instancetype)init { if ((self = [super init])) { _properties = [[NSMutableDictionary alloc] init]; } return self; } #pragma mark - Public Methods - (NSDictionary *)allData { return [_properties copy]; } - (NSArray *)arrayForKey:(NSString *)key { return [self _valueOfClass:[NSArray class] forKey:key]; } - (void)enumerateKeysAndObjectsUsingBlock:(void (^)(NSString *key, id object, BOOL *stop))block { [_properties enumerateKeysAndObjectsUsingBlock:block]; } - (NSEnumerator *)keyEnumerator { return [_properties keyEnumerator]; } - (NSNumber *)numberForKey:(NSString *)key { return [self _valueOfClass:[NSNumber class] forKey:key]; } - (NSEnumerator *)objectEnumerator { return [_properties objectEnumerator]; } - (FBSDKShareOpenGraphObject *)objectForKey:(NSString *)key { return [self _valueOfClass:[FBSDKShareOpenGraphObject class] forKey:key]; } - (id)objectForKeyedSubscript:(id)key { return [self _valueForKey:key]; } - (void)parseProperties:(NSDictionary *)properties { [FBSDKShareUtility assertOpenGraphValues:properties requireKeyNamespace:[self requireKeyNamespace]]; [_properties addEntriesFromDictionary:[FBSDKShareUtility convertOpenGraphValues:properties]]; } - (FBSDKSharePhoto *)photoForKey:(NSString *)key { return [self _valueOfClass:[FBSDKSharePhoto class] forKey:key]; } - (void)removeObjectForKey:(NSString *)key { [_properties removeObjectForKey:key]; } - (void)setArray:(NSArray *)array forKey:(NSString *)key { [self _setValue:array forKey:key]; } - (void)setNumber:(NSNumber *)number forKey:(NSString *)key { [self _setValue:number forKey:key]; } - (void)setObject:(FBSDKShareOpenGraphObject *)object forKey:(NSString *)key { [self _setValue:object forKey:key]; } - (void)setPhoto:(FBSDKSharePhoto *)photo forKey:(NSString *)key { [self _setValue:photo forKey:key]; } - (void)setString:(NSString *)string forKey:(NSString *)key { [self _setValue:string forKey:key]; } - (void)setURL:(NSURL *)URL forKey:(NSString *)key { [self _setValue:URL forKey:key]; } - (NSString *)stringForKey:(NSString *)key { return [self _valueOfClass:[NSString class] forKey:key]; } - (NSURL *)URLForKey:(NSString *)key { return [self _valueOfClass:[NSURL class] forKey:key]; } - (id)valueForKey:(NSString *)key { return [self _valueForKey:key] ?: [super valueForKey:key]; } #pragma mark - Internal Methods - (NSDictionary *)allProperties { return _properties; } - (BOOL)requireKeyNamespace { return YES; } #pragma mark - Equality - (NSUInteger)hash { return [_properties hash]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKShareOpenGraphValueContainer class]]) { return NO; } return [self isEqualToShareOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)object]; } - (BOOL)isEqualToShareOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)object { return [FBSDKInternalUtility object:_properties isEqualToObject:[object allProperties]]; } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [self init])) { NSSet *classes = [NSSet setWithObjects: [NSArray class], [NSDictionary class], [FBSDKShareOpenGraphObject class], [FBSDKSharePhoto class], nil]; NSDictionary *properties = [decoder decodeObjectOfClasses:classes forKey:FBSDK_SHARE_OPEN_GRAPH_VALUE_CONTAINER_PROPERTIES_KEY]; if ([properties count]) { [self parseProperties:properties]; } } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_properties forKey:FBSDK_SHARE_OPEN_GRAPH_VALUE_CONTAINER_PROPERTIES_KEY]; } #pragma mark - Helper Methods - (void)_setValue:(id)value forKey:(NSString *)key { [FBSDKShareUtility assertOpenGraphKey:key requireNamespace:[self requireKeyNamespace]]; [FBSDKShareUtility assertOpenGraphValue:value]; if (value) { _properties[key] = value; } else { [self removeObjectForKey:key]; } } - (id)_valueForKey:(id)key { key = [FBSDKTypeUtility stringValue:key]; return (key ? [FBSDKTypeUtility objectValue:_properties[key]] : nil); } - (id)_valueOfClass:(__unsafe_unretained Class)cls forKey:(NSString *)key { id value = [self _valueForKey:key]; return ([value isKindOfClass:cls] ? value : nil); } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKSharePhoto.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /*! @abstract A photo for sharing. */ @interface FBSDKSharePhoto : NSObject /*! @abstract Convenience method to build a new photo object with an image. @param image If the photo is resident in memory, this method supplies the data @param userGenerated Specifies whether the photo represented by the receiver was generated by the user or by the application */ + (instancetype)photoWithImage:(UIImage *)image userGenerated:(BOOL)userGenerated; /*! @abstract Convenience method to build a new photo object with an imageURL. @param imageURL The URL to the photo @param userGenerated Specifies whether the photo represented by the receiver was generated by the user or by the application @discussion This method should only be used when adding photo content to open graph stories. For example, if you're trying to share a photo from the web by itself, download the image and use `photoWithImage:userGenerated:` instead. */ + (instancetype)photoWithImageURL:(NSURL *)imageURL userGenerated:(BOOL)userGenerated; /*! @abstract If the photo is resident in memory, this method supplies the data. @return UIImage representation of the photo */ @property (nonatomic, strong) UIImage *image; /*! @abstract The URL to the photo. @return URL that points to a network location or the location of the photo on disk */ @property (nonatomic, copy) NSURL *imageURL; /*! @abstract Specifies whether the photo represented by the receiver was generated by the user or by the application. @return YES if the photo is user-generated, otherwise NO */ @property (nonatomic, assign, getter=isUserGenerated) BOOL userGenerated; /*! @abstract Compares the receiver to another photo. @param photo The other photo @return YES if the receiver's values are equal to the other photo's values; otherwise NO */ - (BOOL)isEqualToSharePhoto:(FBSDKSharePhoto *)photo; /*! @abstract The user generated caption for the photo. Note that the 'caption' must come from * the user, as pre-filled content is forbidden by the Platform Policies (2.3). @return the Photo's caption if exists else returns null. */ @property (nonatomic, copy) NSString *caption; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKSharePhoto.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKSharePhoto.h" #import "FBSDKCoreKit+Internal.h" #define FBSDK_SHARE_PHOTO_IMAGE_KEY @"image" #define FBSDK_SHARE_PHOTO_IMAGE_URL_KEY @"imageURL" #define FBSDK_SHARE_PHOTO_USER_GENERATED_KEY @"userGenerated" #define FBSDK_SHARE_PHOTO_CAPTION_KEY @"caption" @implementation FBSDKSharePhoto #pragma mark - Class Methods + (instancetype)photoWithImage:(UIImage *)image userGenerated:(BOOL)userGenerated { FBSDKSharePhoto *photo = [[self alloc] init]; photo.image = image; photo.userGenerated = userGenerated; return photo; } + (instancetype)photoWithImageURL:(NSURL *)imageURL userGenerated:(BOOL)userGenerated { FBSDKSharePhoto *photo = [[self alloc] init]; photo.imageURL = imageURL; photo.userGenerated = userGenerated; return photo; } #pragma mark - Equality - (NSUInteger)hash { NSUInteger subhashes[] = { [_image hash], [_imageURL hash], [_caption hash], (_userGenerated ? 1u : 0u) }; return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKSharePhoto class]]) { return NO; } return [self isEqualToSharePhoto:(FBSDKSharePhoto *)object]; } - (BOOL)isEqualToSharePhoto:(FBSDKSharePhoto *)photo { return (photo && (_userGenerated == photo.userGenerated) && [FBSDKInternalUtility object:_image isEqualToObject:photo.image] && [FBSDKInternalUtility object:_imageURL isEqualToObject:photo.imageURL] && [FBSDKInternalUtility object:_caption isEqualToObject:photo.caption]); } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [self init])) { _image = [decoder decodeObjectOfClass:[UIImage class] forKey:FBSDK_SHARE_PHOTO_IMAGE_KEY]; _imageURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_PHOTO_IMAGE_URL_KEY]; _userGenerated = [decoder decodeBoolForKey:FBSDK_SHARE_PHOTO_USER_GENERATED_KEY]; _caption = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_PHOTO_CAPTION_KEY]; } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_image forKey:FBSDK_SHARE_PHOTO_IMAGE_KEY]; [encoder encodeObject:_imageURL forKey:FBSDK_SHARE_PHOTO_IMAGE_URL_KEY]; [encoder encodeBool:_userGenerated forKey:FBSDK_SHARE_PHOTO_USER_GENERATED_KEY]; [encoder encodeObject:_caption forKey:FBSDK_SHARE_PHOTO_CAPTION_KEY]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { FBSDKSharePhoto *copy = [[FBSDKSharePhoto alloc] init]; copy->_image = [_image copy]; copy->_imageURL = [_imageURL copy]; copy->_userGenerated = _userGenerated; copy->_caption = [_caption copy]; return copy; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKSharePhotoContent.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /*! @abstract A model for photo content to be shared. */ @interface FBSDKSharePhotoContent : NSObject /*! @abstract Photos to be shared. @return Array of the photos (FBSDKSharePhoto) */ @property (nonatomic, copy) NSArray *photos; /*! @abstract Compares the receiver to another photo content. @param content The other content @return YES if the receiver's values are equal to the other content's values; otherwise NO */ - (BOOL)isEqualToSharePhotoContent:(FBSDKSharePhotoContent *)content; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKSharePhotoContent.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKSharePhotoContent.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKHashtag.h" #import "FBSDKSharePhoto.h" #import "FBSDKShareUtility.h" #define FBSDK_SHARE_PHOTO_CONTENT_CONTENT_URL_KEY @"contentURL" #define FBSDK_SHARE_PHOTO_CONTENT_HASHTAG_KEY @"hashtag" #define FBSDK_SHARE_PHOTO_CONTENT_PEOPLE_IDS_KEY @"peopleIDs" #define FBSDK_SHARE_PHOTO_CONTENT_PHOTOS_KEY @"photos" #define FBSDK_SHARE_PHOTO_CONTENT_PLACE_ID_KEY @"placeID" #define FBSDK_SHARE_PHOTO_CONTENT_REF_KEY @"ref" @implementation FBSDKSharePhotoContent #pragma mark - Properties @synthesize contentURL = _contentURL; @synthesize hashtag = _hashtag; @synthesize peopleIDs = _peopleIDs; @synthesize placeID = _placeID; @synthesize ref = _ref; - (void)setPeopleIDs:(NSArray *)peopleIDs { [FBSDKShareUtility assertCollection:peopleIDs ofClass:[NSString class] name:@"peopleIDs"]; if (![FBSDKInternalUtility object:_peopleIDs isEqualToObject:peopleIDs]) { _peopleIDs = [peopleIDs copy]; } } - (void)setPhotos:(NSArray *)photos { [FBSDKShareUtility assertCollection:photos ofClass:[FBSDKSharePhoto class] name:@"photos"]; if (![FBSDKInternalUtility object:_photos isEqualToObject:photos]) { _photos = [photos copy]; } } #pragma mark - Equality - (NSUInteger)hash { NSUInteger subhashes[] = { [_contentURL hash], [_hashtag hash], [_peopleIDs hash], [_photos hash], [_placeID hash], [_ref hash], }; return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKSharePhotoContent class]]) { return NO; } return [self isEqualToSharePhotoContent:(FBSDKSharePhotoContent *)object]; } - (BOOL)isEqualToSharePhotoContent:(FBSDKSharePhotoContent *)content { return (content && [FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] && [FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] && [FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] && [FBSDKInternalUtility object:_photos isEqualToObject:content.photos] && [FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] && [FBSDKInternalUtility object:_ref isEqualToObject:content.ref]); } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [self init])) { _contentURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_PHOTO_CONTENT_CONTENT_URL_KEY]; _hashtag = [decoder decodeObjectOfClass:[FBSDKHashtag class] forKey:FBSDK_SHARE_PHOTO_CONTENT_HASHTAG_KEY]; _peopleIDs = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_SHARE_PHOTO_CONTENT_PEOPLE_IDS_KEY]; NSSet *classes = [NSSet setWithObjects:[NSArray class], [FBSDKSharePhoto class], nil]; _photos = [decoder decodeObjectOfClasses:classes forKey:FBSDK_SHARE_PHOTO_CONTENT_PHOTOS_KEY]; _placeID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_PHOTO_CONTENT_PLACE_ID_KEY]; _ref = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_PHOTO_CONTENT_REF_KEY]; } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_contentURL forKey:FBSDK_SHARE_PHOTO_CONTENT_CONTENT_URL_KEY]; [encoder encodeObject:_hashtag forKey:FBSDK_SHARE_PHOTO_CONTENT_HASHTAG_KEY]; [encoder encodeObject:_peopleIDs forKey:FBSDK_SHARE_PHOTO_CONTENT_PEOPLE_IDS_KEY]; [encoder encodeObject:_photos forKey:FBSDK_SHARE_PHOTO_CONTENT_PHOTOS_KEY]; [encoder encodeObject:_placeID forKey:FBSDK_SHARE_PHOTO_CONTENT_PLACE_ID_KEY]; [encoder encodeObject:_ref forKey:FBSDK_SHARE_PHOTO_CONTENT_REF_KEY]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { FBSDKSharePhotoContent *copy = [[FBSDKSharePhotoContent alloc] init]; copy->_contentURL = [_contentURL copy]; copy->_hashtag = [_hashtag copy]; copy->_peopleIDs = [_peopleIDs copy]; copy->_photos = [_photos copy]; copy->_placeID = [_placeID copy]; copy->_ref = [_ref copy]; return copy; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareVideo.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @class FBSDKSharePhoto; /*! @abstract A video for sharing. */ @interface FBSDKShareVideo : NSObject /*! @abstract Convenience method to build a new video object with a videoURL. @param videoURL The URL to the video */ + (instancetype)videoWithVideoURL:(NSURL *)videoURL; /*! @abstract Convenience method to build a new video object with a videoURL and a previewPhoto @param videoURL The URL to the video @param previewPhoto The photo that represents the video */ + (instancetype)videoWithVideoURL:(NSURL *)videoURL previewPhoto:(FBSDKSharePhoto *)previewPhoto; /*! @abstract The file URL to the video. @return URL that points to the location of the video on disk */ @property (nonatomic, copy) NSURL *videoURL; /*! @abstract The photo that represents the video. @return The photo */ @property (nonatomic, copy) FBSDKSharePhoto *previewPhoto; /*! @abstract Compares the receiver to another video. @param video The other video @return YES if the receiver's values are equal to the other video's values; otherwise NO */ - (BOOL)isEqualToShareVideo:(FBSDKShareVideo *)video; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareVideo.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareVideo.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKSharePhoto.h" #define FBSDK_SHARE_VIDEO_URL_KEY @"videoURL" #define FBSDK_SHARE_VIDEO_PREVIEW_PHOTO_KEY @"previewPhoto" @implementation FBSDKShareVideo #pragma mark - Class Methods + (instancetype)videoWithVideoURL:(NSURL *)videoURL { FBSDKShareVideo *video = [[FBSDKShareVideo alloc] init]; video.videoURL = videoURL; return video; } + (instancetype)videoWithVideoURL:(NSURL *)videoURL previewPhoto:(FBSDKSharePhoto *)previewPhoto { FBSDKShareVideo *video = [[FBSDKShareVideo alloc] init]; video.videoURL = videoURL; video.previewPhoto = previewPhoto; return video; } #pragma mark - Equality - (NSUInteger)hash { NSUInteger subhashes[] = { [_videoURL hash], [_previewPhoto hash], }; return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKShareVideo class]]) { return NO; } return [self isEqualToShareVideo:(FBSDKShareVideo *)object]; } - (BOOL)isEqualToShareVideo:(FBSDKShareVideo *)video { return (video && [FBSDKInternalUtility object:_videoURL isEqualToObject:video.videoURL] && [FBSDKInternalUtility object:_previewPhoto isEqualToObject:video.previewPhoto]); } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [self init])) { _videoURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_VIDEO_URL_KEY]; _previewPhoto = [decoder decodeObjectOfClass:[FBSDKSharePhoto class] forKey:FBSDK_SHARE_VIDEO_PREVIEW_PHOTO_KEY]; } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_videoURL forKey:FBSDK_SHARE_VIDEO_URL_KEY]; [encoder encodeObject:_previewPhoto forKey:FBSDK_SHARE_VIDEO_PREVIEW_PHOTO_KEY]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { FBSDKShareVideo *copy = [[FBSDKShareVideo alloc] init]; copy->_videoURL = [_videoURL copy]; copy->_previewPhoto = [_previewPhoto copy]; return copy; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareVideoContent.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import /*! @abstract A model for video content to be shared. */ @interface FBSDKShareVideoContent : NSObject /*! @abstract The photo that represents the video. @return The photo */ @property (nonatomic, copy) FBSDKSharePhoto *previewPhoto; /*! @abstract The video to be shared. @return The video */ @property (nonatomic, copy) FBSDKShareVideo *video; /*! @abstract Compares the receiver to another video content. @param content The other content @return YES if the receiver's values are equal to the other content's values; otherwise NO */ - (BOOL)isEqualToShareVideoContent:(FBSDKShareVideoContent *)content; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKShareVideoContent.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareVideoContent.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKHashtag.h" #import "FBSDKShareUtility.h" #define FBSDK_SHARE_VIDEO_CONTENT_CONTENT_URL_KEY @"contentURL" #define FBSDK_SHARE_VIDEO_CONTENT_HASHTAG_KEY @"hashtag" #define FBSDK_SHARE_VIDEO_CONTENT_PEOPLE_IDS_KEY @"peopleIDs" #define FBSDK_SHARE_VIDEO_CONTENT_PLACE_ID_KEY @"placeID" #define FBSDK_SHARE_VIDEO_CONTENT_PREVIEW_PHOTO_KEY @"previewPhoto" #define FBSDK_SHARE_VIDEO_CONTENT_REF_KEY @"ref" #define FBSDK_SHARE_VIDEO_CONTENT_VIDEO_KEY @"video" @implementation FBSDKShareVideoContent #pragma mark - Properties @synthesize contentURL = _contentURL; @synthesize hashtag = _hashtag; @synthesize peopleIDs = _peopleIDs; @synthesize placeID = _placeID; @synthesize ref = _ref; - (void)setPeopleIDs:(NSArray *)peopleIDs { [FBSDKShareUtility assertCollection:peopleIDs ofClass:[NSString class] name:@"peopleIDs"]; if (![FBSDKInternalUtility object:_peopleIDs isEqualToObject:peopleIDs]) { _peopleIDs = [peopleIDs copy]; } } #pragma mark - Equality - (NSUInteger)hash { NSUInteger subhashes[] = { [_contentURL hash], [_hashtag hash], [_peopleIDs hash], [_placeID hash], [_previewPhoto hash], [_ref hash], [_video hash], }; return [FBSDKMath hashWithIntegerArray:subhashes count:sizeof(subhashes) / sizeof(subhashes[0])]; } - (BOOL)isEqual:(id)object { if (self == object) { return YES; } if (![object isKindOfClass:[FBSDKShareVideoContent class]]) { return NO; } return [self isEqualToShareVideoContent:(FBSDKShareVideoContent *)object]; } - (BOOL)isEqualToShareVideoContent:(FBSDKShareVideoContent *)content { return (content && [FBSDKInternalUtility object:_contentURL isEqualToObject:content.contentURL] && [FBSDKInternalUtility object:_hashtag isEqualToObject:content.hashtag] && [FBSDKInternalUtility object:_peopleIDs isEqualToObject:content.peopleIDs] && [FBSDKInternalUtility object:_placeID isEqualToObject:content.placeID] && [FBSDKInternalUtility object:_previewPhoto isEqualToObject:content.previewPhoto] && [FBSDKInternalUtility object:_ref isEqualToObject:content.ref] && [FBSDKInternalUtility object:_video isEqualToObject:content.video]); } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [self init])) { _contentURL = [decoder decodeObjectOfClass:[NSURL class] forKey:FBSDK_SHARE_VIDEO_CONTENT_CONTENT_URL_KEY]; _hashtag = [decoder decodeObjectOfClass:[FBSDKHashtag class] forKey:FBSDK_SHARE_VIDEO_CONTENT_HASHTAG_KEY]; _peopleIDs = [decoder decodeObjectOfClass:[NSArray class] forKey:FBSDK_SHARE_VIDEO_CONTENT_PEOPLE_IDS_KEY]; _placeID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_VIDEO_CONTENT_PLACE_ID_KEY]; _previewPhoto = [decoder decodeObjectOfClass:[FBSDKSharePhoto class] forKey:FBSDK_SHARE_VIDEO_CONTENT_PREVIEW_PHOTO_KEY]; _ref = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_SHARE_VIDEO_CONTENT_REF_KEY]; _video = [decoder decodeObjectOfClass:[FBSDKShareVideo class] forKey:FBSDK_SHARE_VIDEO_CONTENT_VIDEO_KEY]; } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_contentURL forKey:FBSDK_SHARE_VIDEO_CONTENT_CONTENT_URL_KEY]; [encoder encodeObject:_hashtag forKey:FBSDK_SHARE_VIDEO_CONTENT_HASHTAG_KEY]; [encoder encodeObject:_peopleIDs forKey:FBSDK_SHARE_VIDEO_CONTENT_PEOPLE_IDS_KEY]; [encoder encodeObject:_placeID forKey:FBSDK_SHARE_VIDEO_CONTENT_PLACE_ID_KEY]; [encoder encodeObject:_previewPhoto forKey:FBSDK_SHARE_VIDEO_CONTENT_PREVIEW_PHOTO_KEY]; [encoder encodeObject:_ref forKey:FBSDK_SHARE_VIDEO_CONTENT_REF_KEY]; [encoder encodeObject:_video forKey:FBSDK_SHARE_VIDEO_CONTENT_VIDEO_KEY]; } #pragma mark - NSCopying - (id)copyWithZone:(NSZone *)zone { FBSDKShareVideoContent *copy = [[FBSDKShareVideoContent alloc] init]; copy->_contentURL = [_contentURL copy]; copy->_hashtag = [_hashtag copy]; copy->_peopleIDs = [_peopleIDs copy]; copy->_placeID = [_placeID copy]; copy->_previewPhoto = [_previewPhoto copy]; copy->_ref = [_ref copy]; copy->_video = [_video copy]; return copy; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKSharing.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @protocol FBSDKSharingDelegate; /*! @abstract The common interface for components that initiate sharing. @see FBSDKShareDialog @see FBSDKMessageDialog @see FBSDKShareAPI */ @protocol FBSDKSharing /*! @abstract The receiver's delegate or nil if it doesn't have a delegate. */ @property (nonatomic, weak) id delegate; /*! @abstract The content to be shared. */ @property (nonatomic, copy) id shareContent; /*! @abstract A Boolean value that indicates whether the receiver should fail if it finds an error with the share content. @discussion If NO, the sharer will still be displayed without the data that was mis-configured. For example, an invalid placeID specified on the shareContent would produce a data error. */ @property (nonatomic, assign) BOOL shouldFailOnDataError; /*! @abstract Validates the content on the receiver. @param errorRef If an error occurs, upon return contains an NSError object that describes the problem. @return YES if the content is valid, otherwise NO. */ - (BOOL)validateWithError:(NSError **)errorRef; @end /*! @abstract The common interface for dialogs that initiate sharing. */ @protocol FBSDKSharingDialog /*! @abstract A Boolean value that indicates whether the receiver can initiate a share. @discussion May return NO if the appropriate Facebook app is not installed and is required or an access token is required but not available. This method does not validate the content on the receiver, so this can be checked before building up the content. @see [FBSDKSharing validateWithError:] @result YES if the receiver can share, otherwise NO. */ - (BOOL)canShow; /*! @abstract Shows the dialog. @result YES if the receiver was able to begin sharing, otherwise NO. */ - (BOOL)show; @end /*! @abstract A delegate for FBSDKSharing. @discussion The delegate is notified with the results of the sharer as long as the application has permissions to receive the information. For example, if the person is not signed into the containing app, the sharer may not be able to distinguish between completion of a share and cancellation. */ @protocol FBSDKSharingDelegate /*! @abstract Sent to the delegate when the share completes without error or cancellation. @param sharer The FBSDKSharing that completed. @param results The results from the sharer. This may be nil or empty. */ - (void)sharer:(id)sharer didCompleteWithResults:(NSDictionary *)results; /*! @abstract Sent to the delegate when the sharer encounters an error. @param sharer The FBSDKSharing that completed. @param error The error. */ - (void)sharer:(id)sharer didFailWithError:(NSError *)error; /*! @abstract Sent to the delegate when the sharer is cancelled. @param sharer The FBSDKSharing that completed. */ - (void)sharerDidCancel:(id)sharer; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKSharingButton.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import /*! @abstract The common interface for sharing buttons. @see FBSDKSendButton @see FBSDKShareButton */ @protocol FBSDKSharingButton /*! @abstract The content to be shared. */ @property (nonatomic, copy) id shareContent; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/FBSDKSharingContent.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @class FBSDKHashtag; /*! @abstract A base interface for content to be shared. */ @protocol FBSDKSharingContent /*! @abstract URL for the content being shared. @discussion This URL will be checked for all link meta tags for linking in platform specific ways. See documentation for App Links (https://developers.facebook.com/docs/applinks/) @return URL representation of the content link */ @property (nonatomic, copy) NSURL *contentURL; /*! @abstract Hashtag for the content being shared. @return The hashtag for the content being shared. */ @property (nonatomic, copy) FBSDKHashtag *hashtag; /*! @abstract List of IDs for taggable people to tag with this content. @description See documentation for Taggable Friends (https://developers.facebook.com/docs/graph-api/reference/user/taggable_friends) @return Array of IDs for people to tag (NSString) */ @property (nonatomic, copy) NSArray *peopleIDs; /*! @abstract The ID for a place to tag with this content. @return The ID for the place to tag */ @property (nonatomic, copy) NSString *placeID; /*! @abstract A value to be added to the referrer URL when a person follows a link from this shared content on feed. @return The ref for the content. */ @property (nonatomic, copy) NSString *ref; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCheckmarkIcon.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKCoreKit+Internal.h" @interface FBSDKCheckmarkIcon : FBSDKIcon @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCheckmarkIcon.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKCheckmarkIcon.h" @implementation FBSDKCheckmarkIcon - (CGPathRef)pathWithSize:(CGSize)size { CGAffineTransform transformValue = CGAffineTransformMakeScale(size.width / 100.0, size.height / 100.0); CGAffineTransform *transform = &transformValue; CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, transform, 0.0, 50.0); const CGPoint points[] = { CGPointMake(12.0, 38.0), CGPointMake(37.0, 63.0), CGPointMake(87.0, 13.0), CGPointMake(99.0, 25.0), CGPointMake(37.0, 87.0), CGPointMake(0.0, 48.0), }; CGPathAddLines(path, transform, points, sizeof(points) / sizeof(points[0])); CGPathRef result = CGPathCreateCopy(path); CGPathRelease(path); return CFAutorelease(result); } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKGameRequestFrictionlessRecipientCache.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @interface FBSDKGameRequestFrictionlessRecipientCache : NSObject - (BOOL)recipientsAreFrictionless:(id)recipients; - (void)updateWithResults:(NSDictionary *)results; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKGameRequestFrictionlessRecipientCache.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKGameRequestFrictionlessRecipientCache.h" #import #import "FBSDKCoreKit+Internal.h" @implementation FBSDKGameRequestFrictionlessRecipientCache { NSSet *_recipientIDs; } #pragma mark - Object Lifecycle - (instancetype)init { if ((self = [super init])) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_accessTokenDidChangeNotification:) name:FBSDKAccessTokenDidChangeNotification object:nil]; [self _updateCache]; } return self; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } #pragma mark - Public API - (BOOL)recipientsAreFrictionless:(id)recipients { if (!recipients) { return NO; } NSArray *recipientIDArray = [FBSDKTypeUtility arrayValue:recipients]; if (!recipientIDArray && [recipients isKindOfClass:[NSString class]]) { recipientIDArray = [recipients componentsSeparatedByString:@","]; } NSSet *recipientIDs = [[NSSet alloc] initWithArray:recipientIDArray]; return [recipientIDs isSubsetOfSet:_recipientIDs]; } - (void)updateWithResults:(NSDictionary *)results { if ([FBSDKTypeUtility boolValue:results[@"updated_frictionless"]]) { [self _updateCache]; } } #pragma mark - Helper Methods - (void)_accessTokenDidChangeNotification:(NSNotification *)notification { if (![notification.userInfo[FBSDKAccessTokenDidChangeUserID] boolValue]) { return; } _recipientIDs = nil; [self _updateCache]; } - (void)_updateCache { if (![FBSDKAccessToken currentAccessToken]) { _recipientIDs = nil; } FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/apprequestformerrecipients" parameters:@{@"fields":@""} flags:(FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery)]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (!error) { NSArray *items = [FBSDKTypeUtility arrayValue:result[@"data"]]; NSArray *recipientIDs = [items valueForKey:@"recipient_id"]; _recipientIDs = [[NSSet alloc] initWithArray:recipientIDs]; } }]; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionController.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import FBSDK_EXTERN NSString *const FBSDKLikeActionControllerDidDisableNotification; FBSDK_EXTERN NSString *const FBSDKLikeActionControllerDidResetNotification; FBSDK_EXTERN NSString *const FBSDKLikeActionControllerDidUpdateNotification; FBSDK_EXTERN NSString *const FBSDKLikeActionControllerAnimatedKey; @interface FBSDKLikeActionController : NSObject + (BOOL)isDisabled; // this method will call beginContentAccess before returning the instance + (instancetype)likeActionControllerForObjectID:(NSString *)objectID objectType:(FBSDKLikeObjectType)objectType; @property (nonatomic, copy, readonly) NSDate *lastUpdateTime; @property (nonatomic, copy, readonly) NSString *likeCountString; @property (nonatomic, copy, readonly) NSString *objectID; @property (nonatomic, assign, readonly) FBSDKLikeObjectType objectType; @property (nonatomic, assign, readonly) BOOL objectIsLiked; @property (nonatomic, copy, readonly) NSString *socialSentence; - (void)refresh; - (void)toggleLikeWithSoundEnabled:(BOOL)soundEnabled analyticsParameters:(NSDictionary *)analyticsParameters fromViewController:(UIViewController *)fromViewController; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionController.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLikeActionController.h" #import #import #import "FBSDKCoreKit+Internal.h" #import "FBSDKLikeActionControllerCache.h" #import "FBSDKLikeButtonPopWAV.h" #import "FBSDKLikeDialog.h" NSString *const FBSDKLikeActionControllerDidDisableNotification = @"FBSDKLikeActionControllerDidDisableNotification"; NSString *const FBSDKLikeActionControllerDidResetNotification = @"FBSDKLikeActionControllerDidResetNotification"; NSString *const FBSDKLikeActionControllerDidUpdateNotification = @"FBSDKLikeActionControllerDidUpdateNotification"; NSString *const FBSDKLikeActionControllerAnimatedKey = @"animated"; #define FBSDK_LIKE_ACTION_CONTROLLER_ANIMATION_DELAY 0.5 #define FBSDK_LIKE_ACTION_CONTROLLER_SOUND_DELAY 0.15 #define FBSDK_LIKE_ACTION_CONTROLLER_API_VERSION @"v2.1" #define FBSDK_LIKE_ACTION_CONTROLLER_LIKE_PROPERTY_KEY @"like" #define FBSDK_LIKE_ACTION_CONTROLLER_REFRESH_PROPERTY_KEY @"refresh" #define FBSDK_LIKE_ACTION_CONTROLLER_LAST_UPDATE_TIME_KEY @"lastUpdateTime" #define FBSDK_LIKE_ACTION_CONTROLLER_LIKE_COUNT_STRING_WITH_LIKE_KEY @"likeCountStringWithLike" #define FBSDK_LIKE_ACTION_CONTROLLER_LIKE_COUNT_STRING_WITHOUT_LIKE_KEY @"likeCountStringWithoutLike" #define FBSDK_LIKE_ACTION_CONTROLLER_OBJECT_ID_KEY @"objectID" #define FBSDK_LIKE_ACTION_CONTROLLER_OBJECT_IS_LIKED_KEY @"objectIsLiked" #define FBSDK_LIKE_ACTION_CONTROLLER_OBJECT_TYPE_KEY @"objectType" #define FBSDK_LIKE_ACTION_CONTROLLER_SOCIAL_SENTENCE_WITH_LIKE_KEY @"socialSentenceWithLike" #define FBSDK_LIKE_ACTION_CONTROLLER_SOCIAL_SENTENCE_WITHOUT_LIKE_KEY @"socialSentenceWithoutLike" #define FBSDK_LIKE_ACTION_CONTROLLER_UNLIKE_TOKEN_KEY @"unlikeToken" #define FBSDK_LIKE_ACTION_CONTROLLER_VERSION_KEY @"version" #define FBSDK_LIKE_ACTION_CONTROLLER_VERSION 4 typedef NS_ENUM(NSUInteger, FBSDKLikeActionControllerRefreshMode) { FBSDKLikeActionControllerRefreshModeInitial, FBSDKLikeActionControllerRefreshModeForce, }; typedef NS_ENUM(NSUInteger, FBSDKLikeActionControllerRefreshState) { FBSDKLikeActionControllerRefreshStateNone, FBSDKLikeActionControllerRefreshStateActive, FBSDKLikeActionControllerRefreshStateComplete, }; typedef void(^fbsdk_like_action_block)(FBSDKTriStateBOOL objectIsLiked, NSString *likeCountStringWithLike, NSString *likeCountStringWithoutLike, NSString *socialSentenceWithLike, NSString *socialSentenceWithoutLike, NSString *unlikeToken, BOOL likeStateChanged, BOOL animated); typedef void(^fbsdk_like_action_controller_ensure_verified_object_id_completion_block)(NSString *verifiedObjectID); @interface FBSDKLikeActionController () @end @implementation FBSDKLikeActionController { FBSDKAccessToken *_accessToken; NSUInteger _contentAccessCount; BOOL _contentDiscarded; NSMapTable *_dialogToAnalyticsParametersMap; NSMapTable *_dialogToUpdateBlockMap; NSString *_likeCountStringWithLike; NSString *_likeCountStringWithoutLike; BOOL _objectIsLikedIsPending; BOOL _objectIsLikedOnServer; BOOL _objectIsPage; FBSDKLikeActionControllerRefreshState _refreshState; NSString *_socialSentenceWithLike; NSString *_socialSentenceWithoutLike; NSString *_unlikeToken; NSString *_verifiedObjectID; } #pragma mark - Class Methods static BOOL _fbsdkLikeActionControllerDisabled = NO; + (BOOL)isDisabled { return _fbsdkLikeActionControllerDisabled; } static FBSDKLikeActionControllerCache *_cache = nil; + (void)initialize { if (self == [FBSDKLikeActionController class]) { NSString *accessTokenString = [FBSDKAccessToken currentAccessToken].tokenString; if (accessTokenString) { NSURL *fileURL = [self _cacheFileURL]; NSData *data = [[NSData alloc] initWithContentsOfURL:fileURL]; if (data) { NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data]; unarchiver.requiresSecureCoding = YES; @try { _cache = [unarchiver decodeObjectOfClass:[FBSDKLikeActionControllerCache class] forKey:NSKeyedArchiveRootObjectKey]; } @catch (NSException *ex) { // ignore decoding exceptions from previous versions of the archive, etc } if (![_cache.accessTokenString isEqualToString:accessTokenString]) { _cache = nil; } } } if (!_cache) { _cache = [[FBSDKLikeActionControllerCache alloc] initWithAccessTokenString:accessTokenString]; } NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(_accessTokenDidChangeNotification:) name:FBSDKAccessTokenDidChangeNotification object:nil]; [nc addObserver:self selector:@selector(_applicationWillResignActiveNotification:) name:UIApplicationWillResignActiveNotification object:nil]; } } + (void)_accessTokenDidChangeNotification:(NSNotification *)notification { NSString *accessTokenString = [FBSDKAccessToken currentAccessToken].tokenString; if ([accessTokenString isEqualToString:_cache.accessTokenString]) { return; } [_cache resetForAccessTokenString:accessTokenString]; [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKLikeActionControllerDidResetNotification object:nil]; } + (void)_applicationWillResignActiveNotification:(NSNotification *)notification { NSURL *fileURL = [self _cacheFileURL]; if (!fileURL) { return; } NSData *data = [NSKeyedArchiver archivedDataWithRootObject:_cache]; if (data) { [data writeToURL:fileURL atomically:YES]; } else { [[[NSFileManager alloc] init] removeItemAtURL:fileURL error:NULL]; } } + (NSURL *)_cacheFileURL { NSURL *directoryURL = [[[NSFileManager alloc] init] URLForDirectory:NSLibraryDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:NULL]; return [directoryURL URLByAppendingPathComponent:@"com-facebook-sdk-like-data"]; } + (instancetype)likeActionControllerForObjectID:(NSString *)objectID objectType:(FBSDKLikeObjectType)objectType { if (!objectID) { return nil; } @synchronized(self) { FBSDKLikeActionController *controller = _cache[objectID]; FBSDKAccessToken *accessToken = [FBSDKAccessToken currentAccessToken]; if (controller) { [controller beginContentAccess]; } else { controller = [[self alloc] initWithObjectID:objectID objectType:objectType accessToken:accessToken]; _cache[objectID] = controller; } [controller _refreshWithMode:FBSDKLikeActionControllerRefreshModeInitial]; return controller; } } #pragma mark - Object Lifecycle - (instancetype)initWithObjectID:(NSString *)objectID objectType:(FBSDKLikeObjectType)objectType accessToken:(FBSDKAccessToken *)accessToken { if ((self = [super init])) { _objectID = [objectID copy]; _objectType = objectType; _accessToken = [accessToken copy]; [self _configure]; } return self; } - (instancetype)init { return [self initWithObjectID:nil objectType:FBSDKLikeObjectTypeUnknown accessToken:nil]; } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (instancetype)initWithCoder:(NSCoder *)decoder { if ([decoder decodeIntegerForKey:FBSDK_LIKE_ACTION_CONTROLLER_VERSION_KEY] != FBSDK_LIKE_ACTION_CONTROLLER_VERSION) { return nil; } NSString *objectID = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_LIKE_ACTION_CONTROLLER_OBJECT_ID_KEY]; if (!objectID) { return nil; } if ((self = [super init])) { _objectID = [objectID copy]; _accessToken = [FBSDKAccessToken currentAccessToken]; _lastUpdateTime = [[decoder decodeObjectOfClass:[NSDate class] forKey:FBSDK_LIKE_ACTION_CONTROLLER_LAST_UPDATE_TIME_KEY] copy]; _likeCountStringWithLike = [[decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_LIKE_ACTION_CONTROLLER_LIKE_COUNT_STRING_WITH_LIKE_KEY] copy]; _likeCountStringWithoutLike = [[decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_LIKE_ACTION_CONTROLLER_LIKE_COUNT_STRING_WITHOUT_LIKE_KEY] copy]; _objectIsLiked = [decoder decodeBoolForKey:FBSDK_LIKE_ACTION_CONTROLLER_OBJECT_IS_LIKED_KEY]; _objectType = [decoder decodeIntegerForKey:FBSDK_LIKE_ACTION_CONTROLLER_OBJECT_TYPE_KEY]; _socialSentenceWithLike = [[decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_LIKE_ACTION_CONTROLLER_SOCIAL_SENTENCE_WITH_LIKE_KEY] copy]; _socialSentenceWithoutLike = [[decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_LIKE_ACTION_CONTROLLER_SOCIAL_SENTENCE_WITHOUT_LIKE_KEY] copy]; _unlikeToken = [[decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_LIKE_ACTION_CONTROLLER_UNLIKE_TOKEN_KEY] copy]; [self _configure]; } return self; } - (void)encodeWithCoder:(NSCoder *)coder { [coder encodeObject:_lastUpdateTime forKey:FBSDK_LIKE_ACTION_CONTROLLER_LAST_UPDATE_TIME_KEY]; [coder encodeObject:_likeCountStringWithLike forKey:FBSDK_LIKE_ACTION_CONTROLLER_LIKE_COUNT_STRING_WITH_LIKE_KEY]; [coder encodeObject:_likeCountStringWithoutLike forKey:FBSDK_LIKE_ACTION_CONTROLLER_LIKE_COUNT_STRING_WITHOUT_LIKE_KEY]; [coder encodeObject:_objectID forKey:FBSDK_LIKE_ACTION_CONTROLLER_OBJECT_ID_KEY]; [coder encodeBool:_objectIsLiked forKey:FBSDK_LIKE_ACTION_CONTROLLER_OBJECT_IS_LIKED_KEY]; [coder encodeInteger:_objectType forKey:FBSDK_LIKE_ACTION_CONTROLLER_OBJECT_TYPE_KEY]; [coder encodeObject:_socialSentenceWithLike forKey:FBSDK_LIKE_ACTION_CONTROLLER_SOCIAL_SENTENCE_WITH_LIKE_KEY]; [coder encodeObject:_socialSentenceWithoutLike forKey:FBSDK_LIKE_ACTION_CONTROLLER_SOCIAL_SENTENCE_WITHOUT_LIKE_KEY]; [coder encodeObject:_unlikeToken forKey:FBSDK_LIKE_ACTION_CONTROLLER_UNLIKE_TOKEN_KEY]; [coder encodeInteger:FBSDK_LIKE_ACTION_CONTROLLER_VERSION forKey:FBSDK_LIKE_ACTION_CONTROLLER_VERSION_KEY]; } #pragma mark - Properties - (NSString *)likeCountString { return (_objectIsLiked ? _likeCountStringWithLike : _likeCountStringWithoutLike); } - (NSString *)socialSentence { return (_objectIsLiked ? _socialSentenceWithLike : _socialSentenceWithoutLike); } #pragma mark - Public API - (void)refresh { [self _refreshWithMode:FBSDKLikeActionControllerRefreshModeForce]; } - (void)toggleLikeWithSoundEnabled:(BOOL)soundEnabled analyticsParameters:(NSDictionary *)analyticsParameters fromViewController:(UIViewController *)fromViewController { [FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKLikeControlDidTap valueToSum:nil parameters:analyticsParameters accessToken:_accessToken]; [self _setExecuting:YES forKey:FBSDK_LIKE_ACTION_CONTROLLER_LIKE_PROPERTY_KEY]; BOOL useOGLike = [self _useOGLike]; BOOL deferred = !useOGLike; fbsdk_like_action_block updateBlock = ^(FBSDKTriStateBOOL objectIsLiked, NSString *likeCountStringWithLike, NSString *likeCountStringWithoutLike, NSString *socialSentenceWithLike, NSString *socialSentenceWithoutLike, NSString *unlikeToken, BOOL likeStateChanged, BOOL animated){ [self _updateWithObjectIsLiked:objectIsLiked likeCountStringWithLike:likeCountStringWithLike likeCountStringWithoutLike:likeCountStringWithoutLike socialSentenceWithLike:socialSentenceWithLike socialSentenceWithoutLike:socialSentenceWithoutLike unlikeToken:unlikeToken soundEnabled:soundEnabled && likeStateChanged animated:animated && likeStateChanged deferred:deferred]; }; BOOL objectIsLiked = !_objectIsLiked; // optimistically update if using og.like (FAS will defer the update) if (useOGLike) { updateBlock(FBSDKTriStateBOOLFromBOOL(objectIsLiked), _likeCountStringWithLike, _likeCountStringWithoutLike, _socialSentenceWithLike, _socialSentenceWithoutLike, _unlikeToken, YES, YES); if (_objectIsLikedIsPending) { return; } } if (objectIsLiked) { if (useOGLike) { [self _publishLikeWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; } else { [self _presentLikeDialogWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; } } else { if (useOGLike && _unlikeToken) { [self _publishUnlikeWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; } else { [self _presentLikeDialogWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; } } } #pragma mark - NSDiscardableContent - (BOOL)beginContentAccess { _contentDiscarded = NO; _contentAccessCount++; return YES; } - (void)endContentAccess { _contentAccessCount--; } - (void)discardContentIfPossible { if (_contentAccessCount == 0) { _contentDiscarded = YES; } } - (BOOL)isContentDiscarded { return _contentDiscarded; } #pragma mark - FBSDKLikeDialogDelegate - (void)likeDialog:(FBSDKLikeDialog *)likeDialog didCompleteWithResults:(NSDictionary *)results { FBSDKTriStateBOOL objectIsLiked = FBSDKTriStateBOOLFromNSNumber(results[@"object_is_liked"]); NSString *likeCountString = [FBSDKTypeUtility stringValue:results[@"like_count_string"]]; NSString *socialSentence = [FBSDKTypeUtility stringValue:results[@"social_sentence"]]; NSString *unlikeToken = [FBSDKTypeUtility stringValue:results[@"unlike_token"]]; BOOL likeStateChanged = ![[FBSDKTypeUtility stringValue:results[@"completionGesture"]] isEqualToString:@"cancel"]; fbsdk_like_action_block updateBlock = [_dialogToUpdateBlockMap objectForKey:likeDialog]; if (updateBlock != NULL) { // we do not need to specify values for with/without like, since we will fast-app-switch to change // the value updateBlock(objectIsLiked, likeCountString, likeCountString, socialSentence, socialSentence, unlikeToken, likeStateChanged, YES); } [self _setExecuting:NO forKey:FBSDK_LIKE_ACTION_CONTROLLER_LIKE_PROPERTY_KEY]; } - (void)likeDialog:(FBSDKLikeDialog *)likeDialog didFailWithError:(NSError *)error { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorUIControlErrors formatString:@"Like dialog error for %@(%@): %@", _objectID, NSStringFromFBSDKLikeObjectType(_objectType), error]; if ([error.userInfo[@"error_reason"] isEqualToString:@"dialog_disabled"]) { _fbsdkLikeActionControllerDisabled = YES; [FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKLikeControlDidDisable valueToSum:nil parameters:[_dialogToAnalyticsParametersMap objectForKey:likeDialog] accessToken:_accessToken]; [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKLikeActionControllerDidDisableNotification object:self userInfo:nil]; } else { FBSDKLikeActionControllerLogError(@"present_dialog", _objectID, _objectType, _accessToken, error); } [self _setExecuting:NO forKey:FBSDK_LIKE_ACTION_CONTROLLER_LIKE_PROPERTY_KEY]; } #pragma mark - Helper Methods - (void)_configure { NSPointerFunctionsOptions keyOptions = (NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality); NSPointerFunctionsOptions valueOptions = (NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality | NSPointerFunctionsCopyIn); _dialogToAnalyticsParametersMap = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0]; _dialogToUpdateBlockMap = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0]; _contentAccessCount = 1; } static void FBSDKLikeActionControllerLogError(NSString *currentAction, NSString *objectID, FBSDKLikeObjectType objectType, FBSDKAccessToken *accessToken, NSError *error) { NSDictionary *parameters = @{ @"object_id": objectID, @"object_type": NSStringFromFBSDKLikeObjectType(objectType), @"current_action": currentAction, @"error": [error description] ?: @"", }; NSString *eventName = ([FBSDKError errorIsNetworkError:error] ? FBSDKAppEventNameFBSDKLikeControlNetworkUnavailable : FBSDKAppEventNameFBSDKLikeControlError); [FBSDKAppEvents logImplicitEvent:eventName valueToSum:nil parameters:parameters accessToken:accessToken]; } typedef void(^fbsdk_like_action_controller_get_engagement_completion_block)(BOOL success, NSString *likeCountStringWithLike, NSString *likeCountStringWithoutLike, NSString *socialSentenceWithLike, NSString *socialSentenceWithoutLike); static void FBSDKLikeActionControllerAddGetEngagementRequest(FBSDKAccessToken *accessToken, FBSDKGraphRequestConnection *connection, NSString *objectID, FBSDKLikeObjectType objectType, fbsdk_like_action_controller_get_engagement_completion_block completionHandler) { if (completionHandler == NULL) { return; } NSString *fields = @"engagement.fields(count_string_with_like,count_string_without_like,social_sentence_with_like," @"social_sentence_without_like)"; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:objectID parameters:@{ @"fields": fields, @"locale": [NSLocale currentLocale].localeIdentifier } tokenString:accessToken.tokenString HTTPMethod:@"GET" flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; [connection addRequest:request completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id result, NSError *error) { BOOL success = NO; NSString *likeCountStringWithLike = nil; NSString *likeCountStringWithoutLike = nil; NSString *socialSentenceWithLike = nil; NSString *socialSentenceWithoutLike = nil; if (error) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorUIControlErrors formatString:@"Error fetching engagement for %@ (%@): %@", objectID, NSStringFromFBSDKLikeObjectType(objectType), error]; FBSDKLikeActionControllerLogError(@"get_engagement", objectID, objectType, accessToken, error); } else { success = YES; result = [FBSDKTypeUtility dictionaryValue:result]; likeCountStringWithLike = [FBSDKTypeUtility stringValue:[result valueForKeyPath:@"engagement.count_string_with_like"]]; likeCountStringWithoutLike = [FBSDKTypeUtility stringValue:[result valueForKeyPath:@"engagement.count_string_without_like"]]; socialSentenceWithLike = [FBSDKTypeUtility stringValue:[result valueForKeyPath:@"engagement.social_sentence_with_like"]]; socialSentenceWithoutLike = [FBSDKTypeUtility stringValue:[result valueForKeyPath:@"engagement.social_sentence_without_like"]]; } completionHandler(success, likeCountStringWithLike, likeCountStringWithoutLike, socialSentenceWithLike, socialSentenceWithoutLike); }]; } typedef void(^fbsdk_like_action_controller_get_object_id_completion_block)(BOOL success, NSString *verifiedObjectID, BOOL objectIsPage); static void FBSDKLikeActionControllerAddGetObjectIDRequest(FBSDKAccessToken *accessToken, FBSDKGraphRequestConnection *connection, NSString *objectID, fbsdk_like_action_controller_get_object_id_completion_block completionHandler) { if (completionHandler == NULL) { return; } FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"" parameters:@{ @"fields": @"id", @"id": objectID, @"metadata": @"1", @"type": @"og", @"locale": [NSLocale currentLocale].localeIdentifier } tokenString:accessToken.tokenString HTTPMethod:@"GET" flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; [connection addRequest:request completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id result, NSError *error) { result = [FBSDKTypeUtility dictionaryValue:result]; NSString *verifiedObjectID = [FBSDKTypeUtility stringValue:result[@"id"]]; BOOL objectIsPage = [FBSDKTypeUtility boolValue:[result valueForKeyPath:@"metadata.type"]]; completionHandler(verifiedObjectID != nil, verifiedObjectID, objectIsPage); }]; } static void FBSDKLikeActionControllerAddGetObjectIDWithObjectURLRequest(FBSDKAccessToken *accessToken, FBSDKGraphRequestConnection *connection, NSString *objectID, fbsdk_like_action_controller_get_object_id_completion_block completionHandler) { if (completionHandler == NULL) { return; } FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"" parameters:@{ @"fields": @"og_object.fields(id)", @"id": objectID, @"locale": [NSLocale currentLocale].localeIdentifier } tokenString:accessToken.tokenString HTTPMethod:@"GET" flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; [connection addRequest:request completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id result, NSError *error) { result = [FBSDKTypeUtility dictionaryValue:result]; NSString *verifiedObjectID = [FBSDKTypeUtility stringValue:[result valueForKeyPath:@"og_object.id"]]; completionHandler(verifiedObjectID != nil, verifiedObjectID, NO); }]; } typedef void(^fbsdk_like_action_controller_get_og_object_like_completion_block)(BOOL success, FBSDKTriStateBOOL objectIsLiked, NSString *unlikeToken); static void FBSDKLikeActionControllerAddGetOGObjectLikeRequest(FBSDKAccessToken *accessToken, FBSDKGraphRequestConnection *connection, NSString *objectID, FBSDKLikeObjectType objectType, fbsdk_like_action_controller_get_og_object_like_completion_block completionHandler) { if (completionHandler == NULL) { return; } FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/og.likes" parameters:@{ @"fields": @"id,application", @"object": objectID, @"locale": [NSLocale currentLocale].localeIdentifier } tokenString:accessToken.tokenString HTTPMethod:@"GET" flags:FBSDKGraphRequestFlagDoNotInvalidateTokenOnError | FBSDKGraphRequestFlagDisableErrorRecovery]; [connection addRequest:request completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id result, NSError *error) { BOOL success = NO; FBSDKTriStateBOOL objectIsLiked = FBSDKTriStateBOOLValueUnknown; NSString *unlikeToken = nil; if (error) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorUIControlErrors formatString:@"Error fetching like state for %@(%@): %@", objectID, NSStringFromFBSDKLikeObjectType(objectType), error]; FBSDKLikeActionControllerLogError(@"get_og_object_like", objectID, objectType, accessToken, error); } else { success = YES; result = [FBSDKTypeUtility dictionaryValue:result]; NSArray *dataSet = [FBSDKTypeUtility arrayValue:result[@"data"]]; for (NSDictionary *data in dataSet) { objectIsLiked = FBSDKTriStateBOOLValueYES; NSString *applicationID = [FBSDKTypeUtility stringValue:[data valueForKeyPath:@"application.id"]]; if ([accessToken.appID isEqualToString:applicationID]) { unlikeToken = [FBSDKTypeUtility stringValue:data[@"id"]]; break; } } } completionHandler(success, objectIsLiked, unlikeToken); }]; } typedef void(^fbsdk_like_action_controller_publish_like_completion_block)(BOOL success, NSString *unlikeToken); static void FBSDKLikeActionControllerAddPublishLikeRequest(FBSDKAccessToken *accessToken, FBSDKGraphRequestConnection *connection, NSString *objectID, FBSDKLikeObjectType objectType, fbsdk_like_action_controller_publish_like_completion_block completionHandler) { FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/og.likes" parameters:@{ @"object": objectID, @"locale": [NSLocale currentLocale].localeIdentifier } tokenString:accessToken.tokenString version:nil HTTPMethod:@"POST"]; [connection addRequest:request completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id result, NSError *error) { BOOL success = NO; NSString *unlikeToken = nil; if (error) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorUIControlErrors formatString:@"Error liking object %@(%@): %@", objectID, NSStringFromFBSDKLikeObjectType(objectType), error]; FBSDKLikeActionControllerLogError(@"publish_like", objectID, objectType, accessToken, error); } else { success = YES; result = [FBSDKTypeUtility dictionaryValue:result]; unlikeToken = [FBSDKTypeUtility stringValue:result[@"id"]]; } if (completionHandler != NULL) { completionHandler(success, unlikeToken); } }]; } typedef void(^fbsdk_like_action_controller_publish_unlike_completion_block)(BOOL success); static void FBSDKLikeActionControllerAddPublishUnlikeRequest(FBSDKAccessToken *accessToken, FBSDKGraphRequestConnection *connection, NSString *unlikeToken, FBSDKLikeObjectType objectType, fbsdk_like_action_controller_publish_unlike_completion_block completionHandler) { FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:unlikeToken parameters:nil tokenString:accessToken.tokenString version:nil HTTPMethod:@"DELETE"]; [connection addRequest:request completionHandler:^(FBSDKGraphRequestConnection *innerConnection, id result, NSError *error) { BOOL success = NO; if (error) { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorUIControlErrors formatString:@"Error unliking object with unlike token %@(%@): %@", unlikeToken, NSStringFromFBSDKLikeObjectType(objectType), error]; FBSDKLikeActionControllerLogError(@"publish_unlike", unlikeToken, objectType, accessToken, error); } else { success = YES; } if (completionHandler != NULL) { completionHandler(success); } }]; } static void FBSDKLikeActionControllerAddRefreshRequests(FBSDKAccessToken *accessToken, FBSDKGraphRequestConnection *connection, NSString *objectID, FBSDKLikeObjectType objectType, fbsdk_like_action_block completionHandler) { if (completionHandler == NULL) { return; } __block FBSDKTriStateBOOL objectIsLiked = FBSDKTriStateBOOLValueUnknown; __block NSString *likeCountStringWithLike = nil; __block NSString *likeCountStringWithoutLike = nil; __block NSString *socialSentenceWithLike = nil; __block NSString *socialSentenceWithoutLike = nil; __block NSString *unlikeToken = nil; void(^handleResults)(void) = ^{ completionHandler(objectIsLiked, likeCountStringWithLike, likeCountStringWithoutLike, socialSentenceWithLike, socialSentenceWithoutLike, unlikeToken, NO, NO); }; fbsdk_like_action_controller_get_og_object_like_completion_block getLikeStateCompletionBlock = ^(BOOL success, FBSDKTriStateBOOL innerObjectIsLiked, NSString *innerUnlikeToken) { if (success) { objectIsLiked = innerObjectIsLiked; if (innerUnlikeToken) { unlikeToken = [innerUnlikeToken copy]; } } }; FBSDKLikeActionControllerAddGetOGObjectLikeRequest(accessToken, connection, objectID, objectType, getLikeStateCompletionBlock); fbsdk_like_action_controller_get_engagement_completion_block engagementCompletionBlock = ^(BOOL success, NSString *innerLikeCountStringWithLike, NSString *innerLikeCountStringWithoutLike, NSString *innerSocialSentenceWithLike, NSString *innerSocialSentenceWithoutLike) { if (success) { // Don't lose cached state if certain properties were not included likeCountStringWithLike = [innerLikeCountStringWithLike copy]; likeCountStringWithoutLike = [innerLikeCountStringWithoutLike copy]; socialSentenceWithLike = [innerSocialSentenceWithLike copy]; socialSentenceWithoutLike = [innerSocialSentenceWithoutLike copy]; handleResults(); } }; FBSDKLikeActionControllerAddGetEngagementRequest(accessToken, connection, objectID, objectType, engagementCompletionBlock); } - (void)_ensureVerifiedObjectID:(fbsdk_like_action_controller_ensure_verified_object_id_completion_block)completion { if (completion == NULL) { return; } FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; [connection overrideVersionPartWith:FBSDK_LIKE_ACTION_CONTROLLER_API_VERSION]; if ([_objectID rangeOfString:@"://"].location != NSNotFound) { FBSDKLikeActionControllerAddGetObjectIDWithObjectURLRequest(_accessToken, connection, _objectID, ^(BOOL success, NSString *innerVerifiedObjectID, BOOL innerObjectIsPage) { if (success) { _verifiedObjectID = [innerVerifiedObjectID copy]; _objectIsPage = innerObjectIsPage; } }); } FBSDKLikeActionControllerAddGetObjectIDRequest(_accessToken, connection, _objectID, ^(BOOL success, NSString *innerVerifiedObjectID, BOOL innerObjectIsPage) { if (success) { // if this was an URL based request, then we want to use the objectID from that request - this value will just // be an echo of the URL if (!_verifiedObjectID) { _verifiedObjectID = [innerVerifiedObjectID copy]; } _objectIsPage = innerObjectIsPage; } if (_verifiedObjectID) { completion(_verifiedObjectID); } }); [connection start]; } - (void)_presentLikeDialogWithUpdateBlock:(fbsdk_like_action_block)updateBlock analyticsParameters:(NSDictionary *)analyticsParameters fromViewController:(UIViewController *)fromViewController { [FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKLikeControlDidPresentDialog valueToSum:nil parameters:analyticsParameters accessToken:_accessToken]; FBSDKLikeDialog *dialog = [[FBSDKLikeDialog alloc] init]; dialog.objectID = _objectID; dialog.objectType = _objectType; dialog.delegate = self; dialog.fromViewController = fromViewController; [_dialogToUpdateBlockMap setObject:updateBlock forKey:dialog]; [_dialogToAnalyticsParametersMap setObject:analyticsParameters forKey:dialog]; if (![dialog like]) { [self _setExecuting:NO forKey:FBSDK_LIKE_ACTION_CONTROLLER_LIKE_PROPERTY_KEY]; } } - (void)_publishIfNeededWithUpdateBlock:(fbsdk_like_action_block)updateBlock analyticsParameters:(NSDictionary *)analyticsParameters fromViewController:(UIViewController *)fromViewController { BOOL objectIsLiked = _objectIsLiked; if (_objectIsLikedOnServer != objectIsLiked) { if (objectIsLiked) { [self _publishLikeWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; } else { [self _publishUnlikeWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; } } } - (void)_publishLikeWithUpdateBlock:(fbsdk_like_action_block)updateBlock analyticsParameters:(NSDictionary *)analyticsParameters fromViewController:(UIViewController *)fromViewController { _objectIsLikedIsPending = YES; [self _ensureVerifiedObjectID:^(NSString *verifiedObjectID) { FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; [connection overrideVersionPartWith:FBSDK_LIKE_ACTION_CONTROLLER_API_VERSION]; fbsdk_like_action_controller_publish_like_completion_block completionHandler = ^(BOOL success, NSString *unlikeToken) { _objectIsLikedIsPending = NO; if (success) { [FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKLikeControlDidLike valueToSum:nil parameters:analyticsParameters accessToken:_accessToken]; _objectIsLikedOnServer = YES; _unlikeToken = [unlikeToken copy]; if (updateBlock != NULL) { updateBlock(FBSDKTriStateBOOLFromBOOL(self.objectIsLiked), _likeCountStringWithLike, _likeCountStringWithoutLike, _socialSentenceWithLike, _socialSentenceWithoutLike, _unlikeToken, NO, NO); } [self _publishIfNeededWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; } else { [self _presentLikeDialogWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; } }; FBSDKLikeActionControllerAddPublishLikeRequest(_accessToken, connection, verifiedObjectID, _objectType, completionHandler); [connection start]; }]; } - (void)_publishUnlikeWithUpdateBlock:(fbsdk_like_action_block)updateBlock analyticsParameters:(NSDictionary *)analyticsParameters fromViewController:(UIViewController *)fromViewController { _objectIsLikedIsPending = YES; FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; [connection overrideVersionPartWith:FBSDK_LIKE_ACTION_CONTROLLER_API_VERSION]; fbsdk_like_action_controller_publish_unlike_completion_block completionHandler = ^(BOOL success) { _objectIsLikedIsPending = NO; if (success) { [FBSDKAppEvents logImplicitEvent:FBSDKAppEventNameFBSDKLikeControlDidUnlike valueToSum:nil parameters:analyticsParameters accessToken:_accessToken]; _objectIsLikedOnServer = NO; _unlikeToken = nil; if (updateBlock != NULL) { updateBlock(FBSDKTriStateBOOLFromBOOL(self.objectIsLiked), _likeCountStringWithLike, _likeCountStringWithoutLike, _socialSentenceWithLike, _socialSentenceWithoutLike, _unlikeToken, NO, NO); } [self _publishIfNeededWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; } else { [self _presentLikeDialogWithUpdateBlock:updateBlock analyticsParameters:analyticsParameters fromViewController:fromViewController]; } }; FBSDKLikeActionControllerAddPublishUnlikeRequest(_accessToken, connection, _unlikeToken, _objectType, completionHandler); [connection start]; } - (void)_refreshWithMode:(FBSDKLikeActionControllerRefreshMode)mode { switch (mode) { case FBSDKLikeActionControllerRefreshModeForce:{ // if we're already refreshing, skip if (_refreshState == FBSDKLikeActionControllerRefreshStateActive) { return; } break; } case FBSDKLikeActionControllerRefreshModeInitial:{ // if we've already started any refresh, skip this if (_refreshState != FBSDKLikeActionControllerRefreshStateNone) { return; } break; } } // You must be logged in to fetch the like status if (!_accessToken) { return; } [self _setExecuting:YES forKey:FBSDK_LIKE_ACTION_CONTROLLER_REFRESH_PROPERTY_KEY]; _refreshState = FBSDKLikeActionControllerRefreshStateActive; [self _ensureVerifiedObjectID:^(NSString *verifiedObjectID) { FBSDKGraphRequestConnection *connection = [[FBSDKGraphRequestConnection alloc] init]; [connection overrideVersionPartWith:FBSDK_LIKE_ACTION_CONTROLLER_API_VERSION]; FBSDKLikeActionControllerAddRefreshRequests(_accessToken, connection, verifiedObjectID, _objectType, ^(FBSDKTriStateBOOL objectIsLiked, NSString *likeCountStringWithLike, NSString *likeCountStringWithoutLike, NSString *socialSentenceWithLike, NSString *socialSentenceWithoutLike, NSString *unlikeToken, BOOL likeStateChanged, BOOL animated) { [self _updateWithObjectIsLiked:objectIsLiked likeCountStringWithLike:likeCountStringWithLike likeCountStringWithoutLike:likeCountStringWithoutLike socialSentenceWithLike:socialSentenceWithLike socialSentenceWithoutLike:socialSentenceWithoutLike unlikeToken:unlikeToken soundEnabled:NO animated:NO deferred:NO]; [self _setExecuting:NO forKey:FBSDK_LIKE_ACTION_CONTROLLER_REFRESH_PROPERTY_KEY]; _refreshState = FBSDKLikeActionControllerRefreshStateComplete; }); [connection start]; }]; } - (void)_setExecuting:(BOOL)executing forKey:(NSString *)key { static NSMapTable *_executing = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _executing = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsCopyIn valueOptions:NSPointerFunctionsStrongMemory capacity:0]; }); NSString *objectKey = [NSString stringWithFormat: @"%@:%@:%@", _objectID, NSStringFromFBSDKLikeObjectType(_objectType), key]; if (executing) { [self beginContentAccess]; [_executing setObject:self forKey:objectKey]; } else { [_executing removeObjectForKey:objectKey]; [self endContentAccess]; } } - (void)_updateWithObjectIsLiked:(FBSDKTriStateBOOL)objectIsLikedTriState likeCountStringWithLike:(NSString *)likeCountStringWithLike likeCountStringWithoutLike:(NSString *)likeCountStringWithoutLike socialSentenceWithLike:(NSString *)socialSentenceWithLike socialSentenceWithoutLike:(NSString *)socialSentenceWithoutLike unlikeToken:(NSString *)unlikeToken soundEnabled:(BOOL)soundEnabled animated:(BOOL)animated deferred:(BOOL)deferred { if (objectIsLikedTriState != FBSDKTriStateBOOLValueUnknown) { _lastUpdateTime = [NSDate date]; } // This value will not be useable if objectIsLikedTriState is FBSDKTriStateBOOLValueUnknown BOOL objectIsLiked = BOOLFromFBSDKTriStateBOOL(objectIsLikedTriState, NO); // So always check objectIsLikedChanged before using objectIsLiked. // If the new like state is unknown, we don't consider the state to have changed. BOOL objectIsLikedChanged = (objectIsLikedTriState != FBSDKTriStateBOOLValueUnknown) && (self.objectIsLiked != objectIsLiked); if (!objectIsLikedChanged && [FBSDKInternalUtility object:_likeCountStringWithLike isEqualToObject:likeCountStringWithLike] && [FBSDKInternalUtility object:_likeCountStringWithoutLike isEqualToObject:likeCountStringWithoutLike] && [FBSDKInternalUtility object:_socialSentenceWithLike isEqualToObject:socialSentenceWithLike] && [FBSDKInternalUtility object:_socialSentenceWithoutLike isEqualToObject:socialSentenceWithoutLike] && [FBSDKInternalUtility object:_unlikeToken isEqualToObject:unlikeToken]) { // check if the like state changed and only animate if it did return; } void(^updateBlock)(void) = ^{ if (objectIsLikedChanged) { _objectIsLiked = objectIsLiked; } if (likeCountStringWithLike) { _likeCountStringWithLike = [likeCountStringWithLike copy]; } if (likeCountStringWithoutLike) { _likeCountStringWithoutLike = [likeCountStringWithoutLike copy]; } if (socialSentenceWithLike) { _socialSentenceWithLike = [socialSentenceWithLike copy]; } if (socialSentenceWithoutLike) { _socialSentenceWithoutLike = [socialSentenceWithoutLike copy]; } if (unlikeToken) { _unlikeToken = [unlikeToken copy]; } // if only meta data changed, don't play the sound FBSDKLikeButtonPopWAV *likeSound = (objectIsLikedChanged && objectIsLiked && soundEnabled ? [FBSDKLikeButtonPopWAV sharedLoader] : nil); void(^notificationBlock)(void) = ^{ if (likeSound) { dispatch_time_t soundPopTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(FBSDK_LIKE_ACTION_CONTROLLER_SOUND_DELAY * NSEC_PER_SEC)); dispatch_after(soundPopTime, dispatch_get_main_queue(), ^(void){ [likeSound playSound]; }); } NSDictionary *userInfo = @{FBSDKLikeActionControllerAnimatedKey: @(animated)}; [[NSNotificationCenter defaultCenter] postNotificationName:FBSDKLikeActionControllerDidUpdateNotification object:self userInfo:userInfo]; }; notificationBlock(); }; // if only meta data changed, don't defer if (deferred && objectIsLikedChanged) { double delayInSeconds = FBSDK_LIKE_ACTION_CONTROLLER_ANIMATION_DELAY; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), updateBlock); } else { updateBlock(); } } - (BOOL)_useOGLike { return (_accessToken && !_objectIsPage && _verifiedObjectID && [_accessToken.permissions containsObject:@"publish_actions"]); } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionControllerCache.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import @interface FBSDKLikeActionControllerCache : NSObject - (instancetype)initWithAccessTokenString:(NSString *)accessTokenString NS_DESIGNATED_INITIALIZER; @property (nonatomic, copy, readonly) NSString *accessTokenString; - (id)objectForKeyedSubscript:(id)key; - (void)resetForAccessTokenString:(NSString *)accessTokenString; - (void)setObject:(id)object forKeyedSubscript:(id)key; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionControllerCache.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLikeActionControllerCache.h" #import #import "FBSDKLikeActionController.h" // after 1 day, expire the cached states #define FBSDK_LIKE_ACTION_CONTROLLER_CACHE_TIMEOUT 60 * 24 #define FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ACCESS_TOKEN_KEY @"accessTokenString" #define FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ITEMS_KEY @"items" @implementation FBSDKLikeActionControllerCache { NSString *_accessTokenString; NSMutableDictionary *_items; } #pragma mark - Object Lifecycle - (instancetype)initWithAccessTokenString:(NSString *)accessTokenString { if ((self = [super init])) { _accessTokenString = [accessTokenString copy]; _items = [[NSMutableDictionary alloc] init]; } return self; } - (instancetype)init { FBSDK_NOT_DESIGNATED_INITIALIZER(initWithAccessTokenString:); return [self initWithAccessTokenString:nil]; } #pragma mark - NSCoding + (BOOL)supportsSecureCoding { return YES; } - (id)initWithCoder:(NSCoder *)decoder { NSString *accessTokenString = [decoder decodeObjectOfClass:[NSString class] forKey:FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ACCESS_TOKEN_KEY]; if ((self = [self initWithAccessTokenString:accessTokenString])) { NSSet *allowedClasses = [NSSet setWithObjects:[NSDictionary class], [FBSDKLikeActionController class], nil]; NSDictionary *items = [decoder decodeObjectOfClasses:allowedClasses forKey:FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ITEMS_KEY]; _items = [[NSMutableDictionary alloc] initWithDictionary:items]; [self _prune]; } return self; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:_accessTokenString forKey:FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ACCESS_TOKEN_KEY]; [encoder encodeObject:_items forKey:FBSDK_LIKE_ACTION_CONTROLLER_CACHE_ITEMS_KEY]; } #pragma mark - Public Methods - (id)objectForKeyedSubscript:(id)key { return _items[key]; } - (void)resetForAccessTokenString:(NSString *)accessTokenString { _accessTokenString = [accessTokenString copy]; [_items removeAllObjects]; } - (void)setObject:(id)object forKeyedSubscript:(id)key { _items[key] = object; } #pragma mark - Helper Methods - (void)_prune { NSMutableArray *keysToRemove = [[NSMutableArray alloc] init]; [_items enumerateKeysAndObjectsUsingBlock:^(NSString *objectID, FBSDKLikeActionController *likeActionController, BOOL *stop) { NSDate *lastUpdateTime = likeActionController.lastUpdateTime; if (!lastUpdateTime || ([[NSDate date] timeIntervalSinceDate:lastUpdateTime] > FBSDK_LIKE_ACTION_CONTROLLER_CACHE_TIMEOUT)) { [keysToRemove addObject:objectID]; } }]; [_items removeObjectsForKeys:keysToRemove]; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxBorderView.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKLikeBoxView.h" @interface FBSDKLikeBoxBorderView : UIView @property (nonatomic, assign) CGFloat borderCornerRadius; @property (nonatomic, assign) CGFloat borderWidth; @property (nonatomic, assign) FBSDKLikeBoxCaretPosition caretPosition; @property (nonatomic, assign, readonly) UIEdgeInsets contentInsets; @property (nonatomic, strong) UIView *contentView; @property (nonatomic, strong) UIColor *fillColor; @property (nonatomic, strong) UIColor *foregroundColor; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxBorderView.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLikeBoxBorderView.h" #import "FBSDKCoreKit+Internal.h" #define FBSDK_LIKE_BOX_BORDER_CARET_WIDTH 6.0 #define FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT 3.0 #define FBSDK_LIKE_BOX_BORDER_CARET_PADDING 3.0 #define FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING 4.0 @implementation FBSDKLikeBoxBorderView #pragma mark - Object Lifecycle - (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { [self _initializeContent]; } return self; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [super initWithCoder:decoder])) { [self _initializeContent]; } return self; } #pragma mark - Properties - (void)setBackgroundColor:(UIColor *)backgroundColor { if (![self.backgroundColor isEqual:backgroundColor]) { [super setBackgroundColor:backgroundColor]; [self setNeedsDisplay]; } } - (void)setBorderCornerRadius:(CGFloat)borderCornerRadius { if (_borderCornerRadius != borderCornerRadius) { _borderCornerRadius = borderCornerRadius; [self setNeedsDisplay]; } } - (void)setBorderWidth:(CGFloat)borderWidth { if (_borderWidth != borderWidth) { _borderWidth = borderWidth; [self setNeedsDisplay]; [self invalidateIntrinsicContentSize]; } } - (void)setCaretPosition:(FBSDKLikeBoxCaretPosition)caretPosition { if (_caretPosition != caretPosition) { _caretPosition = caretPosition; [self setNeedsLayout]; [self setNeedsDisplay]; [self invalidateIntrinsicContentSize]; } } - (UIEdgeInsets)contentInsets { UIEdgeInsets borderInsets = [self _borderInsets]; return UIEdgeInsetsMake(borderInsets.top + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING, borderInsets.left + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING, borderInsets.bottom + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING, borderInsets.right + FBSDK_LIKE_BOX_BORDER_CONTENT_PADDING); } - (void)setContentView:(UIView *)contentView { if (_contentView != contentView) { [_contentView removeFromSuperview]; _contentView = contentView; [self addSubview:_contentView]; [self setNeedsLayout]; [self invalidateIntrinsicContentSize]; } } - (void)setFillColor:(UIColor *)fillColor { if (![_fillColor isEqual:fillColor]) { _fillColor = fillColor; [self setNeedsDisplay]; } } - (void)setForegroundColor:(UIColor *)foregroundColor { if (![_foregroundColor isEqual:foregroundColor]) { _foregroundColor = foregroundColor; [self setNeedsDisplay]; } } #pragma mark - Layout - (CGSize)intrinsicContentSize { return FBSDKEdgeInsetsOutsetSize(self.contentView.intrinsicContentSize, self.contentInsets); } - (void)layoutSubviews { [super layoutSubviews]; self.contentView.frame = UIEdgeInsetsInsetRect(self.bounds, self.contentInsets); } - (CGSize)sizeThatFits:(CGSize)size { UIEdgeInsets contentInsets = self.contentInsets; size = FBSDKEdgeInsetsInsetSize(size, contentInsets); size = [self.contentView sizeThatFits:size]; size = FBSDKEdgeInsetsOutsetSize(size, contentInsets); return size; } #pragma mark - Drawing - (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSaveGState(context); // read the configuration properties CGRect bounds = self.bounds; CGFloat borderWidth = self.borderWidth; CGFloat borderCornerRadius = self.borderCornerRadius; CGFloat contentScaleFactor = self.contentScaleFactor; // fill the background if (self.backgroundColor) { [self.backgroundColor setFill]; CGContextFillRect(context, bounds); } // configure the colors and lines [self.fillColor setFill]; [self.foregroundColor setStroke]; CGContextSetLineJoin(context, kCGLineJoinRound); CGContextSetLineWidth(context, borderWidth); // get the frame of the box CGRect borderFrame = UIEdgeInsetsInsetRect(bounds, [self _borderInsets]); // define the arcs for the corners const int start = 0; const int tangent = 1; const int end = 2; CGPoint topLeftArc[3] = { CGPointMake(CGRectGetMinX(borderFrame) + borderCornerRadius, CGRectGetMinY(borderFrame)), CGPointMake(CGRectGetMinX(borderFrame), CGRectGetMinY(borderFrame)), CGPointMake(CGRectGetMinX(borderFrame), CGRectGetMinY(borderFrame) + borderCornerRadius), }; CGPoint bottomLeftArc[3] = { CGPointMake(CGRectGetMinX(borderFrame), CGRectGetMaxY(borderFrame) - borderCornerRadius), CGPointMake(CGRectGetMinX(borderFrame), CGRectGetMaxY(borderFrame)), CGPointMake(CGRectGetMinX(borderFrame) + borderCornerRadius, CGRectGetMaxY(borderFrame)), }; CGPoint bottomRightArc[3] = { CGPointMake(CGRectGetMaxX(borderFrame) - borderCornerRadius, CGRectGetMaxY(borderFrame)), CGPointMake(CGRectGetMaxX(borderFrame), CGRectGetMaxY(borderFrame)), CGPointMake(CGRectGetMaxX(borderFrame), CGRectGetMaxY(borderFrame) - borderCornerRadius), }; CGPoint topRightArc[3] = { CGPointMake(CGRectGetMaxX(borderFrame), CGRectGetMinY(borderFrame) + borderCornerRadius), CGPointMake(CGRectGetMaxX(borderFrame), CGRectGetMinY(borderFrame)), CGPointMake(CGRectGetMaxX(borderFrame) - borderCornerRadius, CGRectGetMinY(borderFrame)), }; // start a path on the context CGContextBeginPath(context); // position the caret and decide which lines to draw CGPoint caretPoints[3]; switch (self.caretPosition) { case FBSDKLikeBoxCaretPositionTop: CGContextMoveToPoint(context, topRightArc[end].x, topRightArc[end].y); caretPoints[0] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)), CGRectGetMinY(borderFrame)); caretPoints[1] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame)), CGRectGetMinY(borderFrame) - FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT); caretPoints[2] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)), CGRectGetMinY(borderFrame)); CGContextAddLines(context, caretPoints, sizeof(caretPoints) / sizeof(caretPoints[0])); CGContextAddArcToPoint(context, topLeftArc[tangent].x, topLeftArc[tangent].y, topLeftArc[end].x, topLeftArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, bottomLeftArc[start].x, bottomLeftArc[start].y); CGContextAddArcToPoint(context, bottomLeftArc[tangent].x, bottomLeftArc[tangent].y, bottomLeftArc[end].x, bottomLeftArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, bottomRightArc[start].x, bottomRightArc[start].y); CGContextAddArcToPoint(context, bottomRightArc[tangent].x, bottomRightArc[tangent].y, bottomRightArc[end].x, bottomRightArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, topRightArc[start].x, topRightArc[start].y); CGContextAddArcToPoint(context, topRightArc[tangent].x, topRightArc[tangent].y, topRightArc[end].x, topRightArc[end].y, borderCornerRadius); break; case FBSDKLikeBoxCaretPositionLeft: CGContextMoveToPoint(context, topLeftArc[end].x, topLeftArc[end].y); caretPoints[0] = CGPointMake(CGRectGetMinX(borderFrame), FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2))); caretPoints[1] = CGPointMake(CGRectGetMinX(borderFrame) - FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT, FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame))); caretPoints[2] = CGPointMake(CGRectGetMinX(borderFrame), FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2))); CGContextAddLines(context, caretPoints, sizeof(caretPoints) / sizeof(caretPoints[0])); CGContextAddArcToPoint(context, bottomLeftArc[tangent].x, bottomLeftArc[tangent].y, bottomLeftArc[end].x, bottomLeftArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, bottomRightArc[start].x, bottomRightArc[start].y); CGContextAddArcToPoint(context, bottomRightArc[tangent].x, bottomRightArc[tangent].y, bottomRightArc[end].x, bottomRightArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, topRightArc[start].x, topRightArc[start].y); CGContextAddArcToPoint(context, topRightArc[tangent].x, topRightArc[tangent].y, topRightArc[end].x, topRightArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, topLeftArc[start].x, topLeftArc[start].y); CGContextAddArcToPoint(context, topLeftArc[tangent].x, topLeftArc[tangent].y, topLeftArc[end].x, topLeftArc[end].y, borderCornerRadius); break; case FBSDKLikeBoxCaretPositionBottom: CGContextMoveToPoint(context, bottomLeftArc[end].x, bottomLeftArc[end].y); caretPoints[0] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)), CGRectGetMaxY(borderFrame)); caretPoints[1] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame)), CGRectGetMaxY(borderFrame) + FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT); caretPoints[2] = CGPointMake(FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidX(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2)), CGRectGetMaxY(borderFrame)); CGContextAddLines(context, caretPoints, sizeof(caretPoints) / sizeof(caretPoints[0])); CGContextAddArcToPoint(context, bottomRightArc[tangent].x, bottomRightArc[tangent].y, bottomRightArc[end].x, bottomRightArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, topRightArc[start].x, topRightArc[start].y); CGContextAddArcToPoint(context, topRightArc[tangent].x, topRightArc[tangent].y, topRightArc[end].x, topRightArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, topLeftArc[start].x, topLeftArc[start].y); CGContextAddArcToPoint(context, topLeftArc[tangent].x, topLeftArc[tangent].y, topLeftArc[end].x, topLeftArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, bottomLeftArc[start].x, bottomLeftArc[start].y); CGContextAddArcToPoint(context, bottomLeftArc[tangent].x, bottomLeftArc[tangent].y, bottomLeftArc[end].x, bottomLeftArc[end].y, borderCornerRadius); break; case FBSDKLikeBoxCaretPositionRight: CGContextMoveToPoint(context, bottomRightArc[end].x, bottomRightArc[end].y); caretPoints[0] = CGPointMake(CGRectGetMaxX(borderFrame), FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) + (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2))); caretPoints[1] = CGPointMake(CGRectGetMaxX(borderFrame) + FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT, FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame))); caretPoints[2] = CGPointMake(CGRectGetMaxX(borderFrame), FBSDKPointsForScreenPixels(floorf, contentScaleFactor, CGRectGetMidY(borderFrame) - (FBSDK_LIKE_BOX_BORDER_CARET_WIDTH / 2))); CGContextAddLines(context, caretPoints, sizeof(caretPoints) / sizeof(caretPoints[0])); CGContextAddArcToPoint(context, topRightArc[tangent].x, topRightArc[tangent].y, topRightArc[end].x, topRightArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, topLeftArc[start].x, topLeftArc[start].y); CGContextAddArcToPoint(context, topLeftArc[tangent].x, topLeftArc[tangent].y, topLeftArc[end].x, topLeftArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, bottomLeftArc[start].x, bottomLeftArc[start].y); CGContextAddArcToPoint(context, bottomLeftArc[tangent].x, bottomLeftArc[tangent].y, bottomLeftArc[end].x, bottomLeftArc[end].y, borderCornerRadius); CGContextAddLineToPoint(context, bottomRightArc[start].x, bottomRightArc[start].y); CGContextAddArcToPoint(context, bottomRightArc[tangent].x, bottomRightArc[tangent].y, bottomRightArc[end].x, bottomRightArc[end].y, borderCornerRadius); break; } // close and draw now that we have it all CGContextClosePath(context); CGContextDrawPath(context, kCGPathFillStroke); CGContextRestoreGState(context); } #pragma mark - Helper Methods - (UIEdgeInsets)_borderInsets { // inset the border bounds by 1/2 of the border width, since it is drawn split between inside and outside of the path CGFloat scale = self.contentScaleFactor; CGFloat halfBorderWidth = FBSDKPointsForScreenPixels(ceilf, scale, self.borderWidth / 2); UIEdgeInsets borderInsets = UIEdgeInsetsMake(halfBorderWidth, halfBorderWidth, halfBorderWidth, halfBorderWidth); // adjust the insets for the caret position switch (self.caretPosition) { case FBSDKLikeBoxCaretPositionTop:{ borderInsets.top += FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT + FBSDK_LIKE_BOX_BORDER_CARET_PADDING; break; } case FBSDKLikeBoxCaretPositionLeft:{ borderInsets.left += FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT + FBSDK_LIKE_BOX_BORDER_CARET_PADDING; break; } case FBSDKLikeBoxCaretPositionBottom:{ borderInsets.bottom += FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT + FBSDK_LIKE_BOX_BORDER_CARET_PADDING; break; } case FBSDKLikeBoxCaretPositionRight:{ borderInsets.right += FBSDK_LIKE_BOX_BORDER_CARET_HEIGHT + FBSDK_LIKE_BOX_BORDER_CARET_PADDING; break; } } return borderInsets; } - (void)_initializeContent { self.backgroundColor = [UIColor clearColor]; self.borderCornerRadius = 3.0; self.borderWidth = 1.0; self.contentMode = UIViewContentModeRedraw; self.fillColor = [UIColor whiteColor]; self.foregroundColor = FBSDKUIColorWithRGB(0x6A, 0x71, 0x80); self.opaque = NO; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxView.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import /*! @typedef NS_ENUM(NSUInteger, FBSDKLikeBoxCaretPosition) @abstract Specifies the position of the caret relative to the box. */ typedef NS_ENUM(NSUInteger, FBSDKLikeBoxCaretPosition) { /*! The caret is on the top of the box. */ FBSDKLikeBoxCaretPositionTop, /*! The caret is on the left of the box. */ FBSDKLikeBoxCaretPositionLeft, /*! The caret is on the bottom of the box. */ FBSDKLikeBoxCaretPositionBottom, /*! The caret is on the right of the box. */ FBSDKLikeBoxCaretPositionRight, }; @interface FBSDKLikeBoxView : UIView @property (nonatomic, assign) FBSDKLikeBoxCaretPosition caretPosition; @property (nonatomic, copy) NSString *text; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxView.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLikeBoxView.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKLikeBoxBorderView.h" @implementation FBSDKLikeBoxView { FBSDKLikeBoxBorderView *_borderView; UILabel *_likeCountLabel; } #pragma mark - Object Lifecycle - (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { [self _initializeContent]; } return self; } - (id)initWithCoder:(NSCoder *)decoder { if ((self = [super initWithCoder:decoder])) { [self _initializeContent]; } return self; } #pragma mark - Properties - (void)setCaretPosition:(FBSDKLikeBoxCaretPosition)caretPosition { if (_caretPosition != caretPosition) { _caretPosition = caretPosition; _borderView.caretPosition = _caretPosition; [self setNeedsLayout]; [self invalidateIntrinsicContentSize]; } } - (NSString *)text { return _likeCountLabel.text; } - (void)setText:(NSString *)text { if (![_likeCountLabel.text isEqualToString:text]) { _likeCountLabel.text = text; [self setNeedsLayout]; [self invalidateIntrinsicContentSize]; } } #pragma mark - Layout - (CGSize)intrinsicContentSize { return _borderView.intrinsicContentSize; } - (void)layoutSubviews { [super layoutSubviews]; CGRect bounds = self.bounds; _borderView.frame = bounds; } - (CGSize)sizeThatFits:(CGSize)size { return [_borderView sizeThatFits:size]; } #pragma mark - Helper Methods - (void)_initializeContent { _borderView = [[FBSDKLikeBoxBorderView alloc] initWithFrame:CGRectZero]; [self addSubview:_borderView]; _likeCountLabel = [[UILabel alloc] initWithFrame:CGRectZero]; _likeCountLabel.font = [UIFont systemFontOfSize:11.0]; _likeCountLabel.textAlignment = NSTextAlignmentCenter; _likeCountLabel.textColor = FBSDKUIColorWithRGB(0x6A, 0x71, 0x80); _borderView.contentView = _likeCountLabel; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeButton+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKCoreKit+Internal.h" #import "FBSDKLikeActionController.h" #import "FBSDKLikeButton.h" @interface FBSDKLikeButton () @property (nonatomic, strong, readwrite) FBSDKLikeActionController *likeActionController; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeButtonPopWAV.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKCoreKit+Internal.h" @interface FBSDKLikeButtonPopWAV : FBSDKAudioResourceLoader @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeButtonPopWAV.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLikeButtonPopWAV.h" @implementation FBSDKLikeButtonPopWAV + (NSString *)name { return @"FBSDKLikeButtonPop.wav"; } + (NSData *)data { const Byte bytes[] = { 0x52, 0x49, 0x46, 0x46, 0xfc, 0x57, 0x02, 0x00, 0x57, 0x41, 0x56, 0x45, 0x4a, 0x55, 0x4e, 0x4b, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x65, 0x78, 0x74, 0x5a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x72, 0x6f, 0x20, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x68, 0x72, 0x72, 0x48, 0x37, 0x38, 0x21, 0x54, 0x66, 0x61, 0x61, 0x61, 0x61, 0x47, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x30, 0x31, 0x34, 0x2d, 0x30, 0x31, 0x2d, 0x31, 0x00, 0x31, 0x35, 0x3a, 0x32, 0x38, 0x3a, 0x30, 0x31, 0xf7, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6d, 0x74, 0x20, 0x28, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x80, 0xbb, 0x00, 0x00, 0x00, 0xee, 0x02, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x69, 0x6e, 0x66, 0x10, 0x00, 0x00, 0x00, 0x70, 0xe2, 0xe6, 0xc4, 0xdb, 0x13, 0xcf, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x6c, 0x6d, 0x31, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x80, 0x53, 0x02, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x20, 0x00, 0x20, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x19, 0x00, 0x19, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x14, 0x00, 0x14, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x38, 0x00, 0x38, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x41, 0x00, 0x41, 0x00, 0x42, 0x00, 0x42, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x30, 0x00, 0x30, 0x00, 0x20, 0x00, 0x20, 0x00, 0x13, 0x00, 0x13, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x06, 0x00, 0x06, 0x00, 0x02, 0x00, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x02, 0x00, 0x08, 0x00, 0x08, 0x00, 0x11, 0x00, 0x11, 0x00, 0x17, 0x00, 0x17, 0x00, 0x18, 0x00, 0x18, 0x00, 0x17, 0x00, 0x17, 0x00, 0x14, 0x00, 0x14, 0x00, 0x17, 0x00, 0x17, 0x00, 0x22, 0x00, 0x22, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x21, 0x00, 0x21, 0x00, 0x16, 0x00, 0x16, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x05, 0x00, 0x05, 0x00, 0xfa, 0xff, 0xfa, 0xff, 0xec, 0xff, 0xec, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xba, 0xff, 0xba, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xca, 0xff, 0xca, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xc4, 0xff, 0xc4, 0xff, 0xea, 0xff, 0xea, 0xff, 0x0d, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x10, 0x00, 0xf6, 0xff, 0xf6, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0x17, 0x00, 0x17, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x33, 0x00, 0x33, 0x00, 0x11, 0x00, 0x11, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0x02, 0x00, 0x02, 0x00, 0x17, 0x00, 0x17, 0x00, 0x24, 0x00, 0x24, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x08, 0x00, 0x08, 0x00, 0x06, 0x00, 0x06, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0xf0, 0xff, 0xf0, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0x9b, 0xff, 0x9b, 0xff, 0x41, 0xff, 0x41, 0xff, 0xe7, 0xfe, 0xe7, 0xfe, 0xb8, 0xfe, 0xb8, 0xfe, 0xb2, 0xfe, 0xb2, 0xfe, 0x39, 0xfe, 0x39, 0xfe, 0xb3, 0xfc, 0xb3, 0xfc, 0x5e, 0xfa, 0x5e, 0xfa, 0x25, 0xf8, 0x25, 0xf8, 0x22, 0xf7, 0x22, 0xf7, 0xc1, 0xf7, 0xc1, 0xf7, 0x5e, 0xf9, 0x5e, 0xf9, 0xec, 0xfa, 0xec, 0xfa, 0xb2, 0xfb, 0xb2, 0xfb, 0x96, 0xfb, 0x96, 0xfb, 0x0a, 0xfb, 0x0a, 0xfb, 0x9a, 0xfa, 0x9a, 0xfa, 0x94, 0xfa, 0x94, 0xfa, 0x1b, 0xfb, 0x1b, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0x6f, 0xfc, 0x6f, 0xfc, 0xba, 0xfb, 0xba, 0xfb, 0xbc, 0xf9, 0xbc, 0xf9, 0x08, 0xf7, 0x08, 0xf7, 0xe5, 0xf4, 0xe5, 0xf4, 0x7f, 0xf4, 0x7f, 0xf4, 0xde, 0xf5, 0xde, 0xf5, 0x1e, 0xf8, 0x1e, 0xf8, 0x5a, 0xfa, 0x5a, 0xfa, 0x26, 0xfc, 0x26, 0xfc, 0xca, 0xfd, 0xca, 0xfd, 0xdb, 0xff, 0xdb, 0xff, 0x61, 0x02, 0x61, 0x02, 0xc6, 0x04, 0xc6, 0x04, 0x54, 0x06, 0x54, 0x06, 0xb4, 0x06, 0xb4, 0x06, 0x24, 0x06, 0x24, 0x06, 0x3b, 0x05, 0x3b, 0x05, 0x72, 0x04, 0x72, 0x04, 0x27, 0x04, 0x27, 0x04, 0x8e, 0x04, 0x8e, 0x04, 0x73, 0x05, 0x73, 0x05, 0x7f, 0x06, 0x7f, 0x06, 0x72, 0x07, 0x72, 0x07, 0x28, 0x08, 0x28, 0x08, 0xeb, 0x08, 0xeb, 0x08, 0x57, 0x0a, 0x57, 0x0a, 0x8c, 0x0c, 0x8c, 0x0c, 0x00, 0x0f, 0x00, 0x0f, 0xf6, 0x10, 0xf6, 0x10, 0xf2, 0x11, 0xf2, 0x11, 0x14, 0x12, 0x14, 0x12, 0xfa, 0x11, 0xfa, 0x11, 0x1e, 0x12, 0x1e, 0x12, 0x82, 0x12, 0x82, 0x12, 0xc4, 0x12, 0xc4, 0x12, 0x75, 0x12, 0x75, 0x12, 0x86, 0x11, 0x86, 0x11, 0x35, 0x10, 0x35, 0x10, 0xba, 0x0e, 0xba, 0x0e, 0x62, 0x0d, 0x62, 0x0d, 0x79, 0x0c, 0x79, 0x0c, 0x01, 0x0c, 0x01, 0x0c, 0xcf, 0x0b, 0xcf, 0x0b, 0xa7, 0x0b, 0xa7, 0x0b, 0x27, 0x0b, 0x27, 0x0b, 0x32, 0x0a, 0x32, 0x0a, 0x1d, 0x09, 0x1d, 0x09, 0x35, 0x08, 0x35, 0x08, 0x88, 0x07, 0x88, 0x07, 0xf7, 0x06, 0xf7, 0x06, 0x38, 0x06, 0x38, 0x06, 0x1c, 0x05, 0x1c, 0x05, 0xab, 0x03, 0xab, 0x03, 0xea, 0x01, 0xea, 0x01, 0xd7, 0xff, 0xd7, 0xff, 0x72, 0xfd, 0x72, 0xfd, 0xc3, 0xfa, 0xc3, 0xfa, 0x04, 0xf8, 0x04, 0xf8, 0x88, 0xf5, 0x88, 0xf5, 0x63, 0xf3, 0x63, 0xf3, 0x93, 0xf1, 0x93, 0xf1, 0x18, 0xf0, 0x18, 0xf0, 0xe7, 0xee, 0xe7, 0xee, 0x07, 0xee, 0x07, 0xee, 0x8a, 0xed, 0x8a, 0xed, 0x62, 0xed, 0x62, 0xed, 0x68, 0xed, 0x68, 0xed, 0x87, 0xed, 0x87, 0xed, 0xb5, 0xed, 0xb5, 0xed, 0xde, 0xed, 0xde, 0xed, 0xf0, 0xed, 0xf0, 0xed, 0xe5, 0xed, 0xe5, 0xed, 0xe2, 0xed, 0xe2, 0xed, 0x0a, 0xee, 0x0a, 0xee, 0x63, 0xee, 0x63, 0xee, 0xdb, 0xee, 0xdb, 0xee, 0x47, 0xef, 0x47, 0xef, 0x81, 0xef, 0x81, 0xef, 0xb5, 0xef, 0xb5, 0xef, 0x45, 0xf0, 0x45, 0xf0, 0x7b, 0xf1, 0x7b, 0xf1, 0x6c, 0xf3, 0x6c, 0xf3, 0xf1, 0xf5, 0xf1, 0xf5, 0xbf, 0xf8, 0xbf, 0xf8, 0x86, 0xfb, 0x86, 0xfb, 0x15, 0xfe, 0x15, 0xfe, 0x6c, 0x00, 0x6c, 0x00, 0xb3, 0x02, 0xb3, 0x02, 0x1f, 0x05, 0x1f, 0x05, 0xd0, 0x07, 0xd0, 0x07, 0xad, 0x0a, 0xad, 0x0a, 0x48, 0x0d, 0x48, 0x0d, 0x2a, 0x0f, 0x2a, 0x0f, 0x2c, 0x10, 0x2c, 0x10, 0x83, 0x10, 0x83, 0x10, 0xa3, 0x10, 0xa3, 0x10, 0xf5, 0x10, 0xf5, 0x10, 0x93, 0x11, 0x93, 0x11, 0x47, 0x12, 0x47, 0x12, 0xba, 0x12, 0xba, 0x12, 0xb3, 0x12, 0xb3, 0x12, 0x3d, 0x12, 0x3d, 0x12, 0x9c, 0x11, 0x9c, 0x11, 0x26, 0x11, 0x26, 0x11, 0x20, 0x11, 0x20, 0x11, 0x81, 0x11, 0x81, 0x11, 0xdb, 0x11, 0xdb, 0x11, 0xac, 0x11, 0xac, 0x11, 0x90, 0x10, 0x90, 0x10, 0x86, 0x0e, 0x86, 0x0e, 0x06, 0x0c, 0x06, 0x0c, 0xa0, 0x09, 0xa0, 0x09, 0x8b, 0x07, 0x8b, 0x07, 0x97, 0x05, 0x97, 0x05, 0x5a, 0x03, 0x5a, 0x03, 0x73, 0x00, 0x73, 0x00, 0xe1, 0xfc, 0xe1, 0xfc, 0x09, 0xf9, 0x09, 0xf9, 0x6f, 0xf5, 0x6f, 0xf5, 0x7e, 0xf2, 0x7e, 0xf2, 0x4b, 0xf0, 0x4b, 0xf0, 0x99, 0xee, 0x99, 0xee, 0x07, 0xed, 0x07, 0xed, 0x4f, 0xeb, 0x4f, 0xeb, 0x79, 0xe9, 0x79, 0xe9, 0xd4, 0xe7, 0xd4, 0xe7, 0xcc, 0xe6, 0xcc, 0xe6, 0x81, 0xe6, 0x81, 0xe6, 0xc2, 0xe6, 0xc2, 0xe6, 0x2a, 0xe7, 0x2a, 0xe7, 0x4d, 0xe7, 0x4d, 0xe7, 0x09, 0xe7, 0x09, 0xe7, 0x8b, 0xe6, 0x8b, 0xe6, 0x23, 0xe6, 0x23, 0xe6, 0x17, 0xe6, 0x17, 0xe6, 0x7b, 0xe6, 0x7b, 0xe6, 0x38, 0xe7, 0x38, 0xe7, 0x2b, 0xe8, 0x2b, 0xe8, 0x49, 0xe9, 0x49, 0xe9, 0xa6, 0xea, 0xa6, 0xea, 0x72, 0xec, 0x72, 0xec, 0xc5, 0xee, 0xc5, 0xee, 0x92, 0xf1, 0x92, 0xf1, 0xc2, 0xf4, 0xc2, 0xf4, 0x2b, 0xf8, 0x2b, 0xf8, 0xaa, 0xfb, 0xaa, 0xfb, 0x2d, 0xff, 0x2d, 0xff, 0xa6, 0x02, 0xa6, 0x02, 0xff, 0x05, 0xff, 0x05, 0x23, 0x09, 0x23, 0x09, 0xf9, 0x0b, 0xf9, 0x0b, 0x72, 0x0e, 0x72, 0x0e, 0x92, 0x10, 0x92, 0x10, 0x60, 0x12, 0x60, 0x12, 0xe5, 0x13, 0xe5, 0x13, 0x1b, 0x15, 0x1b, 0x15, 0xf4, 0x15, 0xf4, 0x15, 0x79, 0x16, 0x79, 0x16, 0xc1, 0x16, 0xc1, 0x16, 0xf4, 0x16, 0xf4, 0x16, 0x35, 0x17, 0x35, 0x17, 0x95, 0x17, 0x95, 0x17, 0xfc, 0x17, 0xfc, 0x17, 0x39, 0x18, 0x39, 0x18, 0x1d, 0x18, 0x1d, 0x18, 0x92, 0x17, 0x92, 0x17, 0xa8, 0x16, 0xa8, 0x16, 0x86, 0x15, 0x86, 0x15, 0x41, 0x14, 0x41, 0x14, 0xc8, 0x12, 0xc8, 0x12, 0xeb, 0x10, 0xeb, 0x10, 0x84, 0x0e, 0x84, 0x0e, 0x9e, 0x0b, 0x9e, 0x0b, 0x65, 0x08, 0x65, 0x08, 0x10, 0x05, 0x10, 0x05, 0xc8, 0x01, 0xc8, 0x01, 0x9e, 0xfe, 0x9e, 0xfe, 0x8f, 0xfb, 0x8f, 0xfb, 0x9d, 0xf8, 0x9d, 0xf8, 0xd8, 0xf5, 0xd8, 0xf5, 0x5f, 0xf3, 0x5f, 0xf3, 0x5a, 0xf1, 0x5a, 0xf1, 0xe7, 0xef, 0xe7, 0xef, 0xf7, 0xee, 0xf7, 0xee, 0x62, 0xee, 0x62, 0xee, 0x00, 0xee, 0x00, 0xee, 0xb5, 0xed, 0xb5, 0xed, 0x84, 0xed, 0x84, 0xed, 0x80, 0xed, 0x80, 0xed, 0xb9, 0xed, 0xb9, 0xed, 0x26, 0xee, 0x26, 0xee, 0xa8, 0xee, 0xa8, 0xee, 0x24, 0xef, 0x24, 0xef, 0xa1, 0xef, 0xa1, 0xef, 0x37, 0xf0, 0x37, 0xf0, 0x0d, 0xf1, 0x0d, 0xf1, 0x46, 0xf2, 0x46, 0xf2, 0xe5, 0xf3, 0xe5, 0xf3, 0xd2, 0xf5, 0xd2, 0xf5, 0xf9, 0xf7, 0xf9, 0xf7, 0x59, 0xfa, 0x59, 0xfa, 0xf4, 0xfc, 0xf4, 0xfc, 0xd3, 0xff, 0xd3, 0xff, 0xf3, 0x02, 0xf3, 0x02, 0x35, 0x06, 0x35, 0x06, 0x5f, 0x09, 0x5f, 0x09, 0x36, 0x0c, 0x36, 0x0c, 0x97, 0x0e, 0x97, 0x0e, 0x7b, 0x10, 0x7b, 0x10, 0xf1, 0x11, 0xf1, 0x11, 0x0c, 0x13, 0x0c, 0x13, 0xcf, 0x13, 0xcf, 0x13, 0x2a, 0x14, 0x2a, 0x14, 0x15, 0x14, 0x15, 0x14, 0xa2, 0x13, 0xa2, 0x13, 0xf2, 0x12, 0xf2, 0x12, 0x25, 0x12, 0x25, 0x12, 0x57, 0x11, 0x57, 0x11, 0x81, 0x10, 0x81, 0x10, 0x8b, 0x0f, 0x8b, 0x0f, 0x6e, 0x0e, 0x6e, 0x0e, 0x32, 0x0d, 0x32, 0x0d, 0xe7, 0x0b, 0xe7, 0x0b, 0x9b, 0x0a, 0x9b, 0x0a, 0x4f, 0x09, 0x4f, 0x09, 0xec, 0x07, 0xec, 0x07, 0x50, 0x06, 0x50, 0x06, 0x69, 0x04, 0x69, 0x04, 0x3c, 0x02, 0x3c, 0x02, 0xda, 0xff, 0xda, 0xff, 0x5e, 0xfd, 0x5e, 0xfd, 0xe4, 0xfa, 0xe4, 0xfa, 0x7c, 0xf8, 0x7c, 0xf8, 0x29, 0xf6, 0x29, 0xf6, 0xfc, 0xf3, 0xfc, 0xf3, 0x11, 0xf2, 0x11, 0xf2, 0x88, 0xf0, 0x88, 0xf0, 0x81, 0xef, 0x81, 0xef, 0x01, 0xef, 0x01, 0xef, 0xf0, 0xee, 0xf0, 0xee, 0x2c, 0xef, 0x2c, 0xef, 0xb0, 0xef, 0xb0, 0xef, 0x91, 0xf0, 0x91, 0xf0, 0xe6, 0xf1, 0xe6, 0xf1, 0xa9, 0xf3, 0xa9, 0xf3, 0xb9, 0xf5, 0xb9, 0xf5, 0xde, 0xf7, 0xde, 0xf7, 0xdd, 0xf9, 0xdd, 0xf9, 0x8e, 0xfb, 0x8e, 0xfb, 0xe7, 0xfc, 0xe7, 0xfc, 0xfe, 0xfd, 0xfe, 0xfd, 0xf0, 0xfe, 0xf0, 0xfe, 0xd2, 0xff, 0xd2, 0xff, 0xb0, 0x00, 0xb0, 0x00, 0x89, 0x01, 0x89, 0x01, 0x57, 0x02, 0x57, 0x02, 0x25, 0x03, 0x25, 0x03, 0x1b, 0x04, 0x1b, 0x04, 0x64, 0x05, 0x64, 0x05, 0x0a, 0x07, 0x0a, 0x07, 0xf4, 0x08, 0xf4, 0x08, 0xe4, 0x0a, 0xe4, 0x0a, 0x88, 0x0c, 0x88, 0x0c, 0xbf, 0x0d, 0xbf, 0x0d, 0x7c, 0x0e, 0x7c, 0x0e, 0xd1, 0x0e, 0xd1, 0x0e, 0xca, 0x0e, 0xca, 0x0e, 0x48, 0x0e, 0x48, 0x0e, 0x33, 0x0d, 0x33, 0x0d, 0x8f, 0x0b, 0x8f, 0x0b, 0x74, 0x09, 0x74, 0x09, 0x0f, 0x07, 0x0f, 0x07, 0x97, 0x04, 0x97, 0x04, 0x37, 0x02, 0x37, 0x02, 0x11, 0x00, 0x11, 0x00, 0x42, 0xfe, 0x42, 0xfe, 0xe1, 0xfc, 0xe1, 0xfc, 0xfe, 0xfb, 0xfe, 0xfb, 0x91, 0xfb, 0x91, 0xfb, 0x7d, 0xfb, 0x7d, 0xfb, 0x9b, 0xfb, 0x9b, 0xfb, 0xd4, 0xfb, 0xd4, 0xfb, 0x12, 0xfc, 0x12, 0xfc, 0x39, 0xfc, 0x39, 0xfc, 0x2f, 0xfc, 0x2f, 0xfc, 0xe5, 0xfb, 0xe5, 0xfb, 0x56, 0xfb, 0x56, 0xfb, 0x8f, 0xfa, 0x8f, 0xfa, 0xab, 0xf9, 0xab, 0xf9, 0xc8, 0xf8, 0xc8, 0xf8, 0x02, 0xf8, 0x02, 0xf8, 0x6c, 0xf7, 0x6c, 0xf7, 0x1a, 0xf7, 0x1a, 0xf7, 0x25, 0xf7, 0x25, 0xf7, 0xa0, 0xf7, 0xa0, 0xf7, 0x95, 0xf8, 0x95, 0xf8, 0xf5, 0xf9, 0xf5, 0xf9, 0xa0, 0xfb, 0xa0, 0xfb, 0x76, 0xfd, 0x76, 0xfd, 0x68, 0xff, 0x68, 0xff, 0x62, 0x01, 0x62, 0x01, 0x3d, 0x03, 0x3d, 0x03, 0xbb, 0x04, 0xbb, 0x04, 0xa6, 0x05, 0xa6, 0x05, 0xef, 0x05, 0xef, 0x05, 0xac, 0x05, 0xac, 0x05, 0xfe, 0x04, 0xfe, 0x04, 0x03, 0x04, 0x03, 0x04, 0xc8, 0x02, 0xc8, 0x02, 0x61, 0x01, 0x61, 0x01, 0xf5, 0xff, 0xf5, 0xff, 0xb9, 0xfe, 0xb9, 0xfe, 0xd6, 0xfd, 0xd6, 0xfd, 0x5a, 0xfd, 0x5a, 0xfd, 0x3b, 0xfd, 0x3b, 0xfd, 0x62, 0xfd, 0x62, 0xfd, 0xb8, 0xfd, 0xb8, 0xfd, 0x3a, 0xfe, 0x3a, 0xfe, 0xde, 0xfe, 0xde, 0xfe, 0x87, 0xff, 0x87, 0xff, 0x0c, 0x00, 0x0c, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x33, 0x00, 0x33, 0x00, 0xc8, 0xff, 0xc8, 0xff, 0x1b, 0xff, 0x1b, 0xff, 0x41, 0xfe, 0x41, 0xfe, 0x4a, 0xfd, 0x4a, 0xfd, 0x4b, 0xfc, 0x4b, 0xfc, 0x68, 0xfb, 0x68, 0xfb, 0xd0, 0xfa, 0xd0, 0xfa, 0xb3, 0xfa, 0xb3, 0xfa, 0x2b, 0xfb, 0x2b, 0xfb, 0x38, 0xfc, 0x38, 0xfc, 0xbd, 0xfd, 0xbd, 0xfd, 0x95, 0xff, 0x95, 0xff, 0xa5, 0x01, 0xa5, 0x01, 0xd7, 0x03, 0xd7, 0x03, 0x07, 0x06, 0x07, 0x06, 0x02, 0x08, 0x02, 0x08, 0x9a, 0x09, 0x9a, 0x09, 0xb6, 0x0a, 0xb6, 0x0a, 0x4b, 0x0b, 0x4b, 0x0b, 0x57, 0x0b, 0x57, 0x0b, 0xd9, 0x0a, 0xd9, 0x0a, 0xdb, 0x09, 0xdb, 0x09, 0x7c, 0x08, 0x7c, 0x08, 0xe8, 0x06, 0xe8, 0x06, 0x48, 0x05, 0x48, 0x05, 0xaf, 0x03, 0xaf, 0x03, 0x28, 0x02, 0x28, 0x02, 0xcf, 0x00, 0xcf, 0x00, 0xce, 0xff, 0xce, 0xff, 0x2e, 0xff, 0x2e, 0xff, 0xd1, 0xfe, 0xd1, 0xfe, 0x7c, 0xfe, 0x7c, 0xfe, 0x09, 0xfe, 0x09, 0xfe, 0x76, 0xfd, 0x76, 0xfd, 0xda, 0xfc, 0xda, 0xfc, 0x37, 0xfc, 0x37, 0xfc, 0x68, 0xfb, 0x68, 0xfb, 0x4b, 0xfa, 0x4b, 0xfa, 0xd8, 0xf8, 0xd8, 0xf8, 0x1e, 0xf7, 0x1e, 0xf7, 0x3a, 0xf5, 0x3a, 0xf5, 0x5d, 0xf3, 0x5d, 0xf3, 0xce, 0xf1, 0xce, 0xf1, 0xda, 0xf0, 0xda, 0xf0, 0xba, 0xf0, 0xba, 0xf0, 0x69, 0xf1, 0x69, 0xf1, 0x8d, 0xf2, 0x8d, 0xf2, 0xc6, 0xf3, 0xc6, 0xf3, 0x20, 0xf5, 0x20, 0xf5, 0x11, 0xf7, 0x11, 0xf7, 0xf4, 0xf9, 0xf4, 0xf9, 0x96, 0xfd, 0x96, 0xfd, 0x4d, 0x01, 0x4d, 0x01, 0x79, 0x04, 0x79, 0x04, 0xe9, 0x06, 0xe9, 0x06, 0xd0, 0x08, 0xd0, 0x08, 0x6b, 0x0a, 0x6b, 0x0a, 0xb5, 0x0b, 0xb5, 0x0b, 0x80, 0x0c, 0x80, 0x0c, 0xcb, 0x0c, 0xcb, 0x0c, 0xd4, 0x0c, 0xd4, 0x0c, 0xda, 0x0c, 0xda, 0x0c, 0xdd, 0x0c, 0xdd, 0x0c, 0xae, 0x0c, 0xae, 0x0c, 0x4a, 0x0c, 0x4a, 0x0c, 0xee, 0x0b, 0xee, 0x0b, 0xdf, 0x0b, 0xdf, 0x0b, 0x13, 0x0c, 0x13, 0x0c, 0x26, 0x0c, 0x26, 0x0c, 0xb3, 0x0b, 0xb3, 0x0b, 0xa5, 0x0a, 0xa5, 0x0a, 0x34, 0x09, 0x34, 0x09, 0x7d, 0x07, 0x7d, 0x07, 0x55, 0x05, 0x55, 0x05, 0x7c, 0x02, 0x7c, 0x02, 0xfd, 0xfe, 0xfd, 0xfe, 0x35, 0xfb, 0x35, 0xfb, 0x85, 0xf7, 0x85, 0xf7, 0x10, 0xf4, 0x10, 0xf4, 0xc9, 0xf0, 0xc9, 0xf0, 0xc0, 0xed, 0xc0, 0xed, 0x3b, 0xeb, 0x3b, 0xeb, 0x95, 0xe9, 0x95, 0xe9, 0xf6, 0xe8, 0xf6, 0xe8, 0x3a, 0xe9, 0x3a, 0xe9, 0x2d, 0xea, 0x2d, 0xea, 0xb6, 0xeb, 0xb6, 0xeb, 0xcd, 0xed, 0xcd, 0xed, 0x55, 0xf0, 0x55, 0xf0, 0x13, 0xf3, 0x13, 0xf3, 0xda, 0xf5, 0xda, 0xf5, 0xa6, 0xf8, 0xa6, 0xf8, 0x8d, 0xfb, 0x8d, 0xfb, 0x87, 0xfe, 0x87, 0xfe, 0x5c, 0x01, 0x5c, 0x01, 0xd9, 0x03, 0xd9, 0x03, 0x0b, 0x06, 0x0b, 0x06, 0x38, 0x08, 0x38, 0x08, 0x96, 0x0a, 0x96, 0x0a, 0x14, 0x0d, 0x14, 0x0d, 0x78, 0x0f, 0x78, 0x0f, 0xa7, 0x11, 0xa7, 0x11, 0xae, 0x13, 0xae, 0x13, 0xa2, 0x15, 0xa2, 0x15, 0x72, 0x17, 0x72, 0x17, 0xe1, 0x18, 0xe1, 0x18, 0xae, 0x19, 0xae, 0x19, 0xb8, 0x19, 0xb8, 0x19, 0x03, 0x19, 0x03, 0x19, 0x8f, 0x17, 0x8f, 0x17, 0x4b, 0x15, 0x4b, 0x15, 0x33, 0x12, 0x33, 0x12, 0x68, 0x0e, 0x68, 0x0e, 0x22, 0x0a, 0x22, 0x0a, 0x91, 0x05, 0x91, 0x05, 0xcb, 0x00, 0xcb, 0x00, 0xea, 0xfb, 0xea, 0xfb, 0x1b, 0xf7, 0x1b, 0xf7, 0x9f, 0xf2, 0x9f, 0xf2, 0xa8, 0xee, 0xa8, 0xee, 0x47, 0xeb, 0x47, 0xeb, 0x76, 0xe8, 0x76, 0xe8, 0x3a, 0xe6, 0x3a, 0xe6, 0x9d, 0xe4, 0x9d, 0xe4, 0xaa, 0xe3, 0xaa, 0xe3, 0x51, 0xe3, 0x51, 0xe3, 0x77, 0xe3, 0x77, 0xe3, 0x08, 0xe4, 0x08, 0xe4, 0x02, 0xe5, 0x02, 0xe5, 0x70, 0xe6, 0x70, 0xe6, 0x56, 0xe8, 0x56, 0xe8, 0xb1, 0xea, 0xb1, 0xea, 0x82, 0xed, 0x82, 0xed, 0xd8, 0xf0, 0xd8, 0xf0, 0xba, 0xf4, 0xba, 0xf4, 0x1b, 0xf9, 0x1b, 0xf9, 0xd9, 0xfd, 0xd9, 0xfd, 0xd2, 0x02, 0xd2, 0x02, 0xec, 0x07, 0xec, 0x07, 0x05, 0x0d, 0x05, 0x0d, 0xec, 0x11, 0xec, 0x11, 0x6c, 0x16, 0x6c, 0x16, 0x59, 0x1a, 0x59, 0x1a, 0x93, 0x1d, 0x93, 0x1d, 0x03, 0x20, 0x03, 0x20, 0x96, 0x21, 0x96, 0x21, 0x38, 0x22, 0x38, 0x22, 0xd9, 0x21, 0xd9, 0x21, 0x7f, 0x20, 0x7f, 0x20, 0x44, 0x1e, 0x44, 0x1e, 0x51, 0x1b, 0x51, 0x1b, 0xcf, 0x17, 0xcf, 0x17, 0xe0, 0x13, 0xe0, 0x13, 0xa4, 0x0f, 0xa4, 0x0f, 0x34, 0x0b, 0x34, 0x0b, 0xa9, 0x06, 0xa9, 0x06, 0x13, 0x02, 0x13, 0x02, 0x89, 0xfd, 0x89, 0xfd, 0x21, 0xf9, 0x21, 0xf9, 0xea, 0xf4, 0xea, 0xf4, 0xe9, 0xf0, 0xe9, 0xf0, 0x20, 0xed, 0x20, 0xed, 0x97, 0xe9, 0x97, 0xe9, 0x60, 0xe6, 0x60, 0xe6, 0x9f, 0xe3, 0x9f, 0xe3, 0x70, 0xe1, 0x70, 0xe1, 0xe6, 0xdf, 0xe6, 0xdf, 0x10, 0xdf, 0x10, 0xdf, 0x03, 0xdf, 0x03, 0xdf, 0xd2, 0xdf, 0xd2, 0xdf, 0x85, 0xe1, 0x85, 0xe1, 0x1d, 0xe4, 0x1d, 0xe4, 0x94, 0xe7, 0x94, 0xe7, 0xd8, 0xeb, 0xd8, 0xeb, 0xd0, 0xf0, 0xd0, 0xf0, 0x51, 0xf6, 0x51, 0xf6, 0x25, 0xfc, 0x25, 0xfc, 0x0f, 0x02, 0x0f, 0x02, 0xdb, 0x07, 0xdb, 0x07, 0x5c, 0x0d, 0x5c, 0x0d, 0x6c, 0x12, 0x6c, 0x12, 0xe0, 0x16, 0xe0, 0x16, 0x99, 0x1a, 0x99, 0x1a, 0x81, 0x1d, 0x81, 0x1d, 0x95, 0x1f, 0x95, 0x1f, 0xd7, 0x20, 0xd7, 0x20, 0x48, 0x21, 0x48, 0x21, 0xee, 0x20, 0xee, 0x20, 0xd3, 0x1f, 0xd3, 0x1f, 0x0d, 0x1e, 0x0d, 0x1e, 0xae, 0x1b, 0xae, 0x1b, 0xc5, 0x18, 0xc5, 0x18, 0x5c, 0x15, 0x5c, 0x15, 0x7b, 0x11, 0x7b, 0x11, 0x31, 0x0d, 0x31, 0x0d, 0x92, 0x08, 0x92, 0x08, 0xb2, 0x03, 0xb2, 0x03, 0xa4, 0xfe, 0xa4, 0xfe, 0x80, 0xf9, 0x80, 0xf9, 0x67, 0xf4, 0x67, 0xf4, 0x7f, 0xef, 0x7f, 0xef, 0xef, 0xea, 0xef, 0xea, 0xe2, 0xe6, 0xe2, 0xe6, 0x78, 0xe3, 0x78, 0xe3, 0xd2, 0xe0, 0xd2, 0xe0, 0x0f, 0xdf, 0x0f, 0xdf, 0x40, 0xde, 0x40, 0xde, 0x65, 0xde, 0x65, 0xde, 0x73, 0xdf, 0x73, 0xdf, 0x5c, 0xe1, 0x5c, 0xe1, 0x09, 0xe4, 0x09, 0xe4, 0x62, 0xe7, 0x62, 0xe7, 0x4f, 0xeb, 0x4f, 0xeb, 0xab, 0xef, 0xab, 0xef, 0x53, 0xf4, 0x53, 0xf4, 0x29, 0xf9, 0x29, 0xf9, 0x0e, 0xfe, 0x0e, 0xfe, 0xe3, 0x02, 0xe3, 0x02, 0x8a, 0x07, 0x8a, 0x07, 0xe8, 0x0b, 0xe8, 0x0b, 0xeb, 0x0f, 0xeb, 0x0f, 0x7b, 0x13, 0x7b, 0x13, 0x89, 0x16, 0x89, 0x16, 0x09, 0x19, 0x09, 0x19, 0xf3, 0x1a, 0xf3, 0x1a, 0x3a, 0x1c, 0x3a, 0x1c, 0xcb, 0x1c, 0xcb, 0x1c, 0x9b, 0x1c, 0x9b, 0x1c, 0xa8, 0x1b, 0xa8, 0x1b, 0xf8, 0x19, 0xf8, 0x19, 0x99, 0x17, 0x99, 0x17, 0x9d, 0x14, 0x9d, 0x14, 0x15, 0x11, 0x15, 0x11, 0x13, 0x0d, 0x13, 0x0d, 0xac, 0x08, 0xac, 0x08, 0x09, 0x04, 0x09, 0x04, 0x55, 0xff, 0x55, 0xff, 0xb8, 0xfa, 0xb8, 0xfa, 0x59, 0xf6, 0x59, 0xf6, 0x5a, 0xf2, 0x5a, 0xf2, 0xd4, 0xee, 0xd4, 0xee, 0xe1, 0xeb, 0xe1, 0xeb, 0x95, 0xe9, 0x95, 0xe9, 0xfb, 0xe7, 0xfb, 0xe7, 0x1d, 0xe7, 0x1d, 0xe7, 0x01, 0xe7, 0x01, 0xe7, 0xa4, 0xe7, 0xa4, 0xe7, 0xf6, 0xe8, 0xf6, 0xe8, 0xe1, 0xea, 0xe1, 0xea, 0x50, 0xed, 0x50, 0xed, 0x2d, 0xf0, 0x2d, 0xf0, 0x5e, 0xf3, 0x5e, 0xf3, 0xc7, 0xf6, 0xc7, 0xf6, 0x4d, 0xfa, 0x4d, 0xfa, 0xd9, 0xfd, 0xd9, 0xfd, 0x55, 0x01, 0x55, 0x01, 0xb0, 0x04, 0xb0, 0x04, 0xdd, 0x07, 0xdd, 0x07, 0xc8, 0x0a, 0xc8, 0x0a, 0x5f, 0x0d, 0x5f, 0x0d, 0x94, 0x0f, 0x94, 0x0f, 0x5d, 0x11, 0x5d, 0x11, 0xa4, 0x12, 0xa4, 0x12, 0x5c, 0x13, 0x5c, 0x13, 0x7c, 0x13, 0x7c, 0x13, 0x0a, 0x13, 0x0a, 0x13, 0x0e, 0x12, 0x0e, 0x12, 0x93, 0x10, 0x93, 0x10, 0xa2, 0x0e, 0xa2, 0x0e, 0x3f, 0x0c, 0x3f, 0x0c, 0x75, 0x09, 0x75, 0x09, 0x5d, 0x06, 0x5d, 0x06, 0x19, 0x03, 0x19, 0x03, 0xc4, 0xff, 0xc4, 0xff, 0x7b, 0xfc, 0x7b, 0xfc, 0x5f, 0xf9, 0x5f, 0xf9, 0x8b, 0xf6, 0x8b, 0xf6, 0x1b, 0xf4, 0x1b, 0xf4, 0x1f, 0xf2, 0x1f, 0xf2, 0xa2, 0xf0, 0xa2, 0xf0, 0xa4, 0xef, 0xa4, 0xef, 0x27, 0xef, 0x27, 0xef, 0x31, 0xef, 0x31, 0xef, 0xbd, 0xef, 0xbd, 0xef, 0xbf, 0xf0, 0xbf, 0xf0, 0x29, 0xf2, 0x29, 0xf2, 0xf1, 0xf3, 0xf1, 0xf3, 0x0a, 0xf6, 0x0a, 0xf6, 0x66, 0xf8, 0x66, 0xf8, 0xf4, 0xfa, 0xf4, 0xfa, 0x9d, 0xfd, 0x9d, 0xfd, 0x49, 0x00, 0x49, 0x00, 0xe7, 0x02, 0xe7, 0x02, 0x65, 0x05, 0x65, 0x05, 0xb2, 0x07, 0xb2, 0x07, 0xbb, 0x09, 0xbb, 0x09, 0x75, 0x0b, 0x75, 0x0b, 0xd7, 0x0c, 0xd7, 0x0c, 0xda, 0x0d, 0xda, 0x0d, 0x78, 0x0e, 0x78, 0x0e, 0xa9, 0x0e, 0xa9, 0x0e, 0x6d, 0x0e, 0x6d, 0x0e, 0xc4, 0x0d, 0xc4, 0x0d, 0xb6, 0x0c, 0xb6, 0x0c, 0x4e, 0x0b, 0x4e, 0x0b, 0xa2, 0x09, 0xa2, 0x09, 0xba, 0x07, 0xba, 0x07, 0xa8, 0x05, 0xa8, 0x05, 0x82, 0x03, 0x82, 0x03, 0x5c, 0x01, 0x5c, 0x01, 0x41, 0xff, 0x41, 0xff, 0x3e, 0xfd, 0x3e, 0xfd, 0x65, 0xfb, 0x65, 0xfb, 0xc6, 0xf9, 0xc6, 0xf9, 0x69, 0xf8, 0x69, 0xf8, 0x55, 0xf7, 0x55, 0xf7, 0x8f, 0xf6, 0x8f, 0xf6, 0x15, 0xf6, 0x15, 0xf6, 0xea, 0xf5, 0xea, 0xf5, 0x17, 0xf6, 0x17, 0xf6, 0x99, 0xf6, 0x99, 0xf6, 0x6f, 0xf7, 0x6f, 0xf7, 0x8a, 0xf8, 0x8a, 0xf8, 0xe0, 0xf9, 0xe0, 0xf9, 0x58, 0xfb, 0x58, 0xfb, 0xe7, 0xfc, 0xe7, 0xfc, 0x86, 0xfe, 0x86, 0xfe, 0x2a, 0x00, 0x2a, 0x00, 0xc3, 0x01, 0xc3, 0x01, 0x44, 0x03, 0x44, 0x03, 0x9e, 0x04, 0x9e, 0x04, 0xc3, 0x05, 0xc3, 0x05, 0xaf, 0x06, 0xaf, 0x06, 0x5b, 0x07, 0x5b, 0x07, 0xbe, 0x07, 0xbe, 0x07, 0xd5, 0x07, 0xd5, 0x07, 0xa1, 0x07, 0xa1, 0x07, 0x25, 0x07, 0x25, 0x07, 0x6c, 0x06, 0x6c, 0x06, 0x84, 0x05, 0x84, 0x05, 0x7d, 0x04, 0x7d, 0x04, 0x5d, 0x03, 0x5d, 0x03, 0x2b, 0x02, 0x2b, 0x02, 0xf3, 0x00, 0xf3, 0x00, 0xbd, 0xff, 0xbd, 0xff, 0x91, 0xfe, 0x91, 0xfe, 0x7b, 0xfd, 0x7b, 0xfd, 0x86, 0xfc, 0x86, 0xfc, 0xbb, 0xfb, 0xbb, 0xfb, 0x23, 0xfb, 0x23, 0xfb, 0xc1, 0xfa, 0xc1, 0xfa, 0x8b, 0xfa, 0x8b, 0xfa, 0x76, 0xfa, 0x76, 0xfa, 0x7f, 0xfa, 0x7f, 0xfa, 0xad, 0xfa, 0xad, 0xfa, 0x09, 0xfb, 0x09, 0xfb, 0x94, 0xfb, 0x94, 0xfb, 0x47, 0xfc, 0x47, 0xfc, 0x0c, 0xfd, 0x0c, 0xfd, 0xd4, 0xfd, 0xd4, 0xfd, 0xa0, 0xfe, 0xa0, 0xfe, 0x74, 0xff, 0x74, 0xff, 0x56, 0x00, 0x56, 0x00, 0x3b, 0x01, 0x3b, 0x01, 0x13, 0x02, 0x13, 0x02, 0xcc, 0x02, 0xcc, 0x02, 0x5e, 0x03, 0x5e, 0x03, 0xce, 0x03, 0xce, 0x03, 0x17, 0x04, 0x17, 0x04, 0x36, 0x04, 0x36, 0x04, 0x26, 0x04, 0x26, 0x04, 0xec, 0x03, 0xec, 0x03, 0x95, 0x03, 0x95, 0x03, 0x28, 0x03, 0x28, 0x03, 0xab, 0x02, 0xab, 0x02, 0x23, 0x02, 0x23, 0x02, 0x8c, 0x01, 0x8c, 0x01, 0xe8, 0x00, 0xe8, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x85, 0xff, 0x85, 0xff, 0xca, 0xfe, 0xca, 0xfe, 0x0d, 0xfe, 0x0d, 0xfe, 0x59, 0xfd, 0x59, 0xfd, 0xb7, 0xfc, 0xb7, 0xfc, 0x2b, 0xfc, 0x2b, 0xfc, 0xbc, 0xfb, 0xbc, 0xfb, 0x6d, 0xfb, 0x6d, 0xfb, 0x44, 0xfb, 0x44, 0xfb, 0x53, 0xfb, 0x53, 0xfb, 0xa7, 0xfb, 0xa7, 0xfb, 0x3f, 0xfc, 0x3f, 0xfc, 0x0e, 0xfd, 0x0e, 0xfd, 0x00, 0xfe, 0x00, 0xfe, 0xfd, 0xfe, 0xfd, 0xfe, 0xf6, 0xff, 0xf6, 0xff, 0xe0, 0x00, 0xe0, 0x00, 0xb2, 0x01, 0xb2, 0x01, 0x58, 0x02, 0x58, 0x02, 0xbd, 0x02, 0xbd, 0x02, 0xd5, 0x02, 0xd5, 0x02, 0xa5, 0x02, 0xa5, 0x02, 0x3a, 0x02, 0x3a, 0x02, 0xa4, 0x01, 0xa4, 0x01, 0xff, 0x00, 0xff, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0xd6, 0xff, 0xd6, 0xff, 0x73, 0xff, 0x73, 0xff, 0x35, 0xff, 0x35, 0xff, 0x12, 0xff, 0x12, 0xff, 0x01, 0xff, 0x01, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0x12, 0xff, 0x12, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x71, 0xff, 0x71, 0xff, 0x94, 0xff, 0x94, 0xff, 0x91, 0xff, 0x91, 0xff, 0x67, 0xff, 0x67, 0xff, 0x2d, 0xff, 0x2d, 0xff, 0x03, 0xff, 0x03, 0xff, 0xfb, 0xfe, 0xfb, 0xfe, 0x12, 0xff, 0x12, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x70, 0xff, 0x70, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0x40, 0x00, 0x40, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xa0, 0x01, 0xa0, 0x01, 0x7b, 0x02, 0x7b, 0x02, 0xfc, 0x02, 0xfc, 0x02, 0xe0, 0x02, 0xe0, 0x02, 0x47, 0x02, 0x47, 0x02, 0xa9, 0x01, 0xa9, 0x01, 0x87, 0x01, 0x87, 0x01, 0x0b, 0x02, 0x0b, 0x02, 0xe2, 0x02, 0xe2, 0x02, 0x6c, 0x03, 0x6c, 0x03, 0x3d, 0x03, 0x3d, 0x03, 0x5e, 0x02, 0x5e, 0x02, 0x39, 0x01, 0x39, 0x01, 0x4e, 0x00, 0x4e, 0x00, 0xee, 0xff, 0xee, 0xff, 0x19, 0x00, 0x19, 0x00, 0x87, 0x00, 0x87, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x5b, 0xff, 0x5b, 0xff, 0xdf, 0xfd, 0xdf, 0xfd, 0x9c, 0xfc, 0x9c, 0xfc, 0x1e, 0xfc, 0x1e, 0xfc, 0x7e, 0xfc, 0x7e, 0xfc, 0x5d, 0xfd, 0x5d, 0xfd, 0x24, 0xfe, 0x24, 0xfe, 0x69, 0xfe, 0x69, 0xfe, 0x2b, 0xfe, 0x2b, 0xfe, 0xcb, 0xfd, 0xcb, 0xfd, 0xb2, 0xfd, 0xb2, 0xfd, 0x0b, 0xfe, 0x0b, 0xfe, 0xbb, 0xfe, 0xbb, 0xfe, 0x8b, 0xff, 0x8b, 0xff, 0x4c, 0x00, 0x4c, 0x00, 0xdc, 0x00, 0xdc, 0x00, 0x27, 0x01, 0x27, 0x01, 0x35, 0x01, 0x35, 0x01, 0x27, 0x01, 0x27, 0x01, 0x27, 0x01, 0x27, 0x01, 0x41, 0x01, 0x41, 0x01, 0x5f, 0x01, 0x5f, 0x01, 0x5f, 0x01, 0x5f, 0x01, 0x39, 0x01, 0x39, 0x01, 0xfd, 0x00, 0xfd, 0x00, 0xba, 0x00, 0xba, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x03, 0x00, 0x03, 0x00, 0x7b, 0xff, 0x7b, 0xff, 0xf2, 0xfe, 0xf2, 0xfe, 0x9e, 0xfe, 0x9e, 0xfe, 0x97, 0xfe, 0x97, 0xfe, 0xc5, 0xfe, 0xc5, 0xfe, 0xf3, 0xfe, 0xf3, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xe8, 0xfe, 0xe8, 0xfe, 0xd2, 0xfe, 0xd2, 0xfe, 0xdd, 0xfe, 0xdd, 0xfe, 0x12, 0xff, 0x12, 0xff, 0x68, 0xff, 0x68, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0x5a, 0x00, 0x5a, 0x00, 0xde, 0x00, 0xde, 0x00, 0x4d, 0x01, 0x4d, 0x01, 0x97, 0x01, 0x97, 0x01, 0xc2, 0x01, 0xc2, 0x01, 0xe9, 0x01, 0xe9, 0x01, 0x22, 0x02, 0x22, 0x02, 0x69, 0x02, 0x69, 0x02, 0xad, 0x02, 0xad, 0x02, 0xda, 0x02, 0xda, 0x02, 0xe2, 0x02, 0xe2, 0x02, 0xbc, 0x02, 0xbc, 0x02, 0x61, 0x02, 0x61, 0x02, 0xd1, 0x01, 0xd1, 0x01, 0x1c, 0x01, 0x1c, 0x01, 0x65, 0x00, 0x65, 0x00, 0xcf, 0xff, 0xcf, 0xff, 0x62, 0xff, 0x62, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0xbb, 0xfe, 0xbb, 0xfe, 0x5c, 0xfe, 0x5c, 0xfe, 0xf8, 0xfd, 0xf8, 0xfd, 0xa6, 0xfd, 0xa6, 0xfd, 0x7b, 0xfd, 0x7b, 0xfd, 0x7c, 0xfd, 0x7c, 0xfd, 0xa6, 0xfd, 0xa6, 0xfd, 0xf2, 0xfd, 0xf2, 0xfd, 0x5b, 0xfe, 0x5b, 0xfe, 0xd1, 0xfe, 0xd1, 0xfe, 0x41, 0xff, 0x41, 0xff, 0x98, 0xff, 0x98, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0x01, 0x00, 0x01, 0x00, 0x28, 0x00, 0x28, 0x00, 0x53, 0x00, 0x53, 0x00, 0x86, 0x00, 0x86, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xef, 0x00, 0xef, 0x00, 0x0f, 0x01, 0x0f, 0x01, 0x12, 0x01, 0x12, 0x01, 0xff, 0x00, 0xff, 0x00, 0xe8, 0x00, 0xe8, 0x00, 0xda, 0x00, 0xda, 0x00, 0xd5, 0x00, 0xd5, 0x00, 0xcf, 0x00, 0xcf, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0x63, 0x00, 0x63, 0x00, 0x14, 0x00, 0x14, 0x00, 0xb2, 0xff, 0xb2, 0xff, 0x42, 0xff, 0x42, 0xff, 0xca, 0xfe, 0xca, 0xfe, 0x58, 0xfe, 0x58, 0xfe, 0xfa, 0xfd, 0xfa, 0xfd, 0xae, 0xfd, 0xae, 0xfd, 0x6b, 0xfd, 0x6b, 0xfd, 0x33, 0xfd, 0x33, 0xfd, 0x11, 0xfd, 0x11, 0xfd, 0x1a, 0xfd, 0x1a, 0xfd, 0x50, 0xfd, 0x50, 0xfd, 0xac, 0xfd, 0xac, 0xfd, 0x22, 0xfe, 0x22, 0xfe, 0xa9, 0xfe, 0xa9, 0xfe, 0x3d, 0xff, 0x3d, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0x73, 0x00, 0x73, 0x00, 0x03, 0x01, 0x03, 0x01, 0x85, 0x01, 0x85, 0x01, 0xfd, 0x01, 0xfd, 0x01, 0x6f, 0x02, 0x6f, 0x02, 0xd6, 0x02, 0xd6, 0x02, 0x24, 0x03, 0x24, 0x03, 0x4c, 0x03, 0x4c, 0x03, 0x48, 0x03, 0x48, 0x03, 0x23, 0x03, 0x23, 0x03, 0xe5, 0x02, 0xe5, 0x02, 0x94, 0x02, 0x94, 0x02, 0x34, 0x02, 0x34, 0x02, 0xcf, 0x01, 0xcf, 0x01, 0x6a, 0x01, 0x6a, 0x01, 0x04, 0x01, 0x04, 0x01, 0x9b, 0x00, 0x9b, 0x00, 0x29, 0x00, 0x29, 0x00, 0xb2, 0xff, 0xb2, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0xde, 0xfe, 0xde, 0xfe, 0x94, 0xfe, 0x94, 0xfe, 0x5a, 0xfe, 0x5a, 0xfe, 0x20, 0xfe, 0x20, 0xfe, 0xe7, 0xfd, 0xe7, 0xfd, 0xb7, 0xfd, 0xb7, 0xfd, 0x9d, 0xfd, 0x9d, 0xfd, 0x9f, 0xfd, 0x9f, 0xfd, 0xb4, 0xfd, 0xb4, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0x04, 0xfe, 0x04, 0xfe, 0x40, 0xfe, 0x40, 0xfe, 0x8d, 0xfe, 0x8d, 0xfe, 0xec, 0xfe, 0xec, 0xfe, 0x5a, 0xff, 0x5a, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0x4a, 0x00, 0x4a, 0x00, 0xb9, 0x00, 0xb9, 0x00, 0x12, 0x01, 0x12, 0x01, 0x4f, 0x01, 0x4f, 0x01, 0x6c, 0x01, 0x6c, 0x01, 0x6f, 0x01, 0x6f, 0x01, 0x63, 0x01, 0x63, 0x01, 0x54, 0x01, 0x54, 0x01, 0x45, 0x01, 0x45, 0x01, 0x2f, 0x01, 0x2f, 0x01, 0x11, 0x01, 0x11, 0x01, 0xec, 0x00, 0xec, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x44, 0x00, 0x44, 0x00, 0x30, 0x00, 0x30, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0xfc, 0xff, 0xfc, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0x96, 0xff, 0x96, 0xff, 0x68, 0xff, 0x68, 0xff, 0x3a, 0xff, 0x3a, 0xff, 0x12, 0xff, 0x12, 0xff, 0xf5, 0xfe, 0xf5, 0xfe, 0xe8, 0xfe, 0xe8, 0xfe, 0xea, 0xfe, 0xea, 0xfe, 0xf4, 0xfe, 0xf4, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0x0d, 0xff, 0x0d, 0xff, 0x27, 0xff, 0x27, 0xff, 0x58, 0xff, 0x58, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0x4f, 0x00, 0x4f, 0x00, 0x98, 0x00, 0x98, 0x00, 0xd8, 0x00, 0xd8, 0x00, 0x14, 0x01, 0x14, 0x01, 0x50, 0x01, 0x50, 0x01, 0x8e, 0x01, 0x8e, 0x01, 0xcb, 0x01, 0xcb, 0x01, 0x02, 0x02, 0x02, 0x02, 0x2e, 0x02, 0x2e, 0x02, 0x4a, 0x02, 0x4a, 0x02, 0x53, 0x02, 0x53, 0x02, 0x45, 0x02, 0x45, 0x02, 0x27, 0x02, 0x27, 0x02, 0xfc, 0x01, 0xfc, 0x01, 0xc9, 0x01, 0xc9, 0x01, 0x8d, 0x01, 0x8d, 0x01, 0x43, 0x01, 0x43, 0x01, 0xe9, 0x00, 0xe9, 0x00, 0x82, 0x00, 0x82, 0x00, 0x16, 0x00, 0x16, 0x00, 0xad, 0xff, 0xad, 0xff, 0x49, 0xff, 0x49, 0xff, 0xeb, 0xfe, 0xeb, 0xfe, 0x94, 0xfe, 0x94, 0xfe, 0x47, 0xfe, 0x47, 0xfe, 0x04, 0xfe, 0x04, 0xfe, 0xcb, 0xfd, 0xcb, 0xfd, 0x9e, 0xfd, 0x9e, 0xfd, 0x81, 0xfd, 0x81, 0xfd, 0x76, 0xfd, 0x76, 0xfd, 0x80, 0xfd, 0x80, 0xfd, 0x98, 0xfd, 0x98, 0xfd, 0xb9, 0xfd, 0xb9, 0xfd, 0xdf, 0xfd, 0xdf, 0xfd, 0x08, 0xfe, 0x08, 0xfe, 0x36, 0xfe, 0x36, 0xfe, 0x6f, 0xfe, 0x6f, 0xfe, 0xb0, 0xfe, 0xb0, 0xfe, 0xf4, 0xfe, 0xf4, 0xfe, 0x35, 0xff, 0x35, 0xff, 0x70, 0xff, 0x70, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0x27, 0x00, 0x27, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0xbb, 0x00, 0xbb, 0x00, 0x06, 0x01, 0x06, 0x01, 0x4b, 0x01, 0x4b, 0x01, 0x8c, 0x01, 0x8c, 0x01, 0xcc, 0x01, 0xcc, 0x01, 0x0c, 0x02, 0x0c, 0x02, 0x42, 0x02, 0x42, 0x02, 0x6e, 0x02, 0x6e, 0x02, 0x8f, 0x02, 0x8f, 0x02, 0x9e, 0x02, 0x9e, 0x02, 0x95, 0x02, 0x95, 0x02, 0x72, 0x02, 0x72, 0x02, 0x3e, 0x02, 0x3e, 0x02, 0x00, 0x02, 0x00, 0x02, 0xbe, 0x01, 0xbe, 0x01, 0x7e, 0x01, 0x7e, 0x01, 0x40, 0x01, 0x40, 0x01, 0x04, 0x01, 0x04, 0x01, 0xc8, 0x00, 0xc8, 0x00, 0x8d, 0x00, 0x8d, 0x00, 0x55, 0x00, 0x55, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0xe8, 0xff, 0xe8, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0x7e, 0xff, 0x7e, 0xff, 0x49, 0xff, 0x49, 0xff, 0x11, 0xff, 0x11, 0xff, 0xd3, 0xfe, 0xd3, 0xfe, 0x90, 0xfe, 0x90, 0xfe, 0x4a, 0xfe, 0x4a, 0xfe, 0x04, 0xfe, 0x04, 0xfe, 0xc4, 0xfd, 0xc4, 0xfd, 0x8c, 0xfd, 0x8c, 0xfd, 0x60, 0xfd, 0x60, 0xfd, 0x41, 0xfd, 0x41, 0xfd, 0x31, 0xfd, 0x31, 0xfd, 0x2b, 0xfd, 0x2b, 0xfd, 0x2f, 0xfd, 0x2f, 0xfd, 0x40, 0xfd, 0x40, 0xfd, 0x61, 0xfd, 0x61, 0xfd, 0x94, 0xfd, 0x94, 0xfd, 0xd4, 0xfd, 0xd4, 0xfd, 0x1a, 0xfe, 0x1a, 0xfe, 0x62, 0xfe, 0x62, 0xfe, 0xaa, 0xfe, 0xaa, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe, 0x37, 0xff, 0x37, 0xff, 0x80, 0xff, 0x80, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0x0c, 0x00, 0x0c, 0x00, 0x48, 0x00, 0x48, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0xae, 0x00, 0xae, 0x00, 0xdb, 0x00, 0xdb, 0x00, 0x09, 0x01, 0x09, 0x01, 0x39, 0x01, 0x39, 0x01, 0x67, 0x01, 0x67, 0x01, 0x8b, 0x01, 0x8b, 0x01, 0xa7, 0x01, 0xa7, 0x01, 0xbc, 0x01, 0xbc, 0x01, 0xc9, 0x01, 0xc9, 0x01, 0xcd, 0x01, 0xcd, 0x01, 0xc5, 0x01, 0xc5, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0x8a, 0x01, 0x8a, 0x01, 0x57, 0x01, 0x57, 0x01, 0x19, 0x01, 0x19, 0x01, 0xdb, 0x00, 0xdb, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0x71, 0x00, 0x71, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x32, 0x00, 0x39, 0x00, 0x39, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x92, 0x00, 0x92, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xec, 0x00, 0xec, 0x00, 0x0f, 0x01, 0x0f, 0x01, 0x25, 0x01, 0x25, 0x01, 0x2b, 0x01, 0x2b, 0x01, 0x20, 0x01, 0x20, 0x01, 0x06, 0x01, 0x06, 0x01, 0xdd, 0x00, 0xdd, 0x00, 0xa6, 0x00, 0xa6, 0x00, 0x65, 0x00, 0x65, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0xce, 0xff, 0xce, 0xff, 0x7b, 0xff, 0x7b, 0xff, 0x24, 0xff, 0x24, 0xff, 0xcf, 0xfe, 0xcf, 0xfe, 0x7c, 0xfe, 0x7c, 0xfe, 0x2e, 0xfe, 0x2e, 0xfe, 0xe6, 0xfd, 0xe6, 0xfd, 0xaa, 0xfd, 0xaa, 0xfd, 0x7a, 0xfd, 0x7a, 0xfd, 0x55, 0xfd, 0x55, 0xfd, 0x3c, 0xfd, 0x3c, 0xfd, 0x2c, 0xfd, 0x2c, 0xfd, 0x24, 0xfd, 0x24, 0xfd, 0x29, 0xfd, 0x29, 0xfd, 0x3c, 0xfd, 0x3c, 0xfd, 0x63, 0xfd, 0x63, 0xfd, 0x9d, 0xfd, 0x9d, 0xfd, 0xe7, 0xfd, 0xe7, 0xfd, 0x40, 0xfe, 0x40, 0xfe, 0xa9, 0xfe, 0xa9, 0xfe, 0x24, 0xff, 0x24, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0x53, 0x00, 0x53, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xa9, 0x01, 0xa9, 0x01, 0x4b, 0x02, 0x4b, 0x02, 0xe0, 0x02, 0xe0, 0x02, 0x66, 0x03, 0x66, 0x03, 0xd9, 0x03, 0xd9, 0x03, 0x32, 0x04, 0x32, 0x04, 0x6c, 0x04, 0x6c, 0x04, 0x83, 0x04, 0x83, 0x04, 0x75, 0x04, 0x75, 0x04, 0x45, 0x04, 0x45, 0x04, 0xfa, 0x03, 0xfa, 0x03, 0x97, 0x03, 0x97, 0x03, 0x1f, 0x03, 0x1f, 0x03, 0x96, 0x02, 0x96, 0x02, 0xfb, 0x01, 0xfb, 0x01, 0x53, 0x01, 0x53, 0x01, 0x9f, 0x00, 0x9f, 0x00, 0xe5, 0xff, 0xe5, 0xff, 0x2e, 0xff, 0x2e, 0xff, 0x7e, 0xfe, 0x7e, 0xfe, 0xd8, 0xfd, 0xd8, 0xfd, 0x3a, 0xfd, 0x3a, 0xfd, 0xa6, 0xfc, 0xa6, 0xfc, 0x21, 0xfc, 0x21, 0xfc, 0xb5, 0xfb, 0xb5, 0xfb, 0x6c, 0xfb, 0x6c, 0xfb, 0x47, 0xfb, 0x47, 0xfb, 0x47, 0xfb, 0x47, 0xfb, 0x6a, 0xfb, 0x6a, 0xfb, 0xaf, 0xfb, 0xaf, 0xfb, 0x17, 0xfc, 0x17, 0xfc, 0xa1, 0xfc, 0xa1, 0xfc, 0x48, 0xfd, 0x48, 0xfd, 0x08, 0xfe, 0x08, 0xfe, 0xda, 0xfe, 0xda, 0xfe, 0xb8, 0xff, 0xb8, 0xff, 0x98, 0x00, 0x98, 0x00, 0x78, 0x01, 0x78, 0x01, 0x52, 0x02, 0x52, 0x02, 0x22, 0x03, 0x22, 0x03, 0xe8, 0x03, 0xe8, 0x03, 0x9b, 0x04, 0x9b, 0x04, 0x33, 0x05, 0x33, 0x05, 0xa6, 0x05, 0xa6, 0x05, 0xf2, 0x05, 0xf2, 0x05, 0x19, 0x06, 0x19, 0x06, 0x1f, 0x06, 0x1f, 0x06, 0x04, 0x06, 0x04, 0x06, 0xc4, 0x05, 0xc4, 0x05, 0x5b, 0x05, 0x5b, 0x05, 0xc7, 0x04, 0xc7, 0x04, 0x0e, 0x04, 0x0e, 0x04, 0x3b, 0x03, 0x3b, 0x03, 0x55, 0x02, 0x55, 0x02, 0x60, 0x01, 0x60, 0x01, 0x61, 0x00, 0x61, 0x00, 0x5a, 0xff, 0x5a, 0xff, 0x4d, 0xfe, 0x4d, 0xfe, 0x47, 0xfd, 0x47, 0xfd, 0x52, 0xfc, 0x52, 0xfc, 0x77, 0xfb, 0x77, 0xfb, 0xb9, 0xfa, 0xb9, 0xfa, 0x1d, 0xfa, 0x1d, 0xfa, 0xa7, 0xf9, 0xa7, 0xf9, 0x57, 0xf9, 0x57, 0xf9, 0x30, 0xf9, 0x30, 0xf9, 0x36, 0xf9, 0x36, 0xf9, 0x69, 0xf9, 0x69, 0xf9, 0xc6, 0xf9, 0xc6, 0xf9, 0x4a, 0xfa, 0x4a, 0xfa, 0xf0, 0xfa, 0xf0, 0xfa, 0xb0, 0xfb, 0xb0, 0xfb, 0x81, 0xfc, 0x81, 0xfc, 0x61, 0xfd, 0x61, 0xfd, 0x4a, 0xfe, 0x4a, 0xfe, 0x3c, 0xff, 0x3c, 0xff, 0x31, 0x00, 0x31, 0x00, 0x23, 0x01, 0x23, 0x01, 0x0f, 0x02, 0x0f, 0x02, 0xf1, 0x02, 0xf1, 0x02, 0xc7, 0x03, 0xc7, 0x03, 0x8d, 0x04, 0x8d, 0x04, 0x3c, 0x05, 0x3c, 0x05, 0xce, 0x05, 0xce, 0x05, 0x3d, 0x06, 0x3d, 0x06, 0x88, 0x06, 0x88, 0x06, 0xae, 0x06, 0xae, 0x06, 0xaf, 0x06, 0xaf, 0x06, 0x87, 0x06, 0x87, 0x06, 0x35, 0x06, 0x35, 0x06, 0xbc, 0x05, 0xbc, 0x05, 0x1d, 0x05, 0x1d, 0x05, 0x5f, 0x04, 0x5f, 0x04, 0x88, 0x03, 0x88, 0x03, 0xa2, 0x02, 0xa2, 0x02, 0xb1, 0x01, 0xb1, 0x01, 0xbe, 0x00, 0xbe, 0x00, 0xd2, 0xff, 0xd2, 0xff, 0xf0, 0xfe, 0xf0, 0xfe, 0x1c, 0xfe, 0x1c, 0xfe, 0x5b, 0xfd, 0x5b, 0xfd, 0xb5, 0xfc, 0xb5, 0xfc, 0x2e, 0xfc, 0x2e, 0xfc, 0xc5, 0xfb, 0xc5, 0xfb, 0x75, 0xfb, 0x75, 0xfb, 0x3d, 0xfb, 0x3d, 0xfb, 0x1d, 0xfb, 0x1d, 0xfb, 0x19, 0xfb, 0x19, 0xfb, 0x31, 0xfb, 0x31, 0xfb, 0x65, 0xfb, 0x65, 0xfb, 0xae, 0xfb, 0xae, 0xfb, 0x06, 0xfc, 0x06, 0xfc, 0x66, 0xfc, 0x66, 0xfc, 0xce, 0xfc, 0xce, 0xfc, 0x41, 0xfd, 0x41, 0xfd, 0xbf, 0xfd, 0xbf, 0xfd, 0x47, 0xfe, 0x47, 0xfe, 0xd0, 0xfe, 0xd0, 0xfe, 0x5b, 0xff, 0x5b, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0x5b, 0x00, 0x5b, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0x1f, 0x01, 0x1f, 0x01, 0x6b, 0x01, 0x6b, 0x01, 0xa9, 0x01, 0xa9, 0x01, 0xda, 0x01, 0xda, 0x01, 0xfc, 0x01, 0xfc, 0x01, 0x0e, 0x02, 0x0e, 0x02, 0x0b, 0x02, 0x0b, 0x02, 0xf9, 0x01, 0xf9, 0x01, 0xda, 0x01, 0xda, 0x01, 0xb4, 0x01, 0xb4, 0x01, 0x8b, 0x01, 0x8b, 0x01, 0x60, 0x01, 0x60, 0x01, 0x34, 0x01, 0x34, 0x01, 0x05, 0x01, 0x05, 0x01, 0xd6, 0x00, 0xd6, 0x00, 0xa7, 0x00, 0xa7, 0x00, 0x7f, 0x00, 0x7f, 0x00, 0x62, 0x00, 0x62, 0x00, 0x55, 0x00, 0x55, 0x00, 0x53, 0x00, 0x53, 0x00, 0x58, 0x00, 0x58, 0x00, 0x5e, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x63, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0x00, 0x64, 0x00, 0x63, 0x00, 0x63, 0x00, 0x60, 0x00, 0x60, 0x00, 0x56, 0x00, 0x56, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0xe9, 0xff, 0xe9, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0x78, 0xff, 0x78, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x0b, 0xff, 0x0b, 0xff, 0xdc, 0xfe, 0xdc, 0xfe, 0xad, 0xfe, 0xad, 0xfe, 0x7e, 0xfe, 0x7e, 0xfe, 0x53, 0xfe, 0x53, 0xfe, 0x2d, 0xfe, 0x2d, 0xfe, 0x11, 0xfe, 0x11, 0xfe, 0xfc, 0xfd, 0xfc, 0xfd, 0xec, 0xfd, 0xec, 0xfd, 0xdf, 0xfd, 0xdf, 0xfd, 0xd3, 0xfd, 0xd3, 0xfd, 0xc9, 0xfd, 0xc9, 0xfd, 0xc5, 0xfd, 0xc5, 0xfd, 0xcc, 0xfd, 0xcc, 0xfd, 0xe3, 0xfd, 0xe3, 0xfd, 0x0b, 0xfe, 0x0b, 0xfe, 0x45, 0xfe, 0x45, 0xfe, 0x90, 0xfe, 0x90, 0xfe, 0xe9, 0xfe, 0xe9, 0xfe, 0x53, 0xff, 0x53, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0x50, 0x00, 0x50, 0x00, 0xdd, 0x00, 0xdd, 0x00, 0x6c, 0x01, 0x6c, 0x01, 0xf8, 0x01, 0xf8, 0x01, 0x79, 0x02, 0x79, 0x02, 0xea, 0x02, 0xea, 0x02, 0x4b, 0x03, 0x4b, 0x03, 0x98, 0x03, 0x98, 0x03, 0xd1, 0x03, 0xd1, 0x03, 0xf4, 0x03, 0xf4, 0x03, 0x03, 0x04, 0x03, 0x04, 0xfd, 0x03, 0xfd, 0x03, 0xe0, 0x03, 0xe0, 0x03, 0xab, 0x03, 0xab, 0x03, 0x5e, 0x03, 0x5e, 0x03, 0xfe, 0x02, 0xfe, 0x02, 0x8c, 0x02, 0x8c, 0x02, 0x09, 0x02, 0x09, 0x02, 0x7b, 0x01, 0x7b, 0x01, 0xe2, 0x00, 0xe2, 0x00, 0x44, 0x00, 0x44, 0x00, 0xa4, 0xff, 0xa4, 0xff, 0x08, 0xff, 0x08, 0xff, 0x74, 0xfe, 0x74, 0xfe, 0xeb, 0xfd, 0xeb, 0xfd, 0x6e, 0xfd, 0x6e, 0xfd, 0xfd, 0xfc, 0xfd, 0xfc, 0x99, 0xfc, 0x99, 0xfc, 0x47, 0xfc, 0x47, 0xfc, 0x0c, 0xfc, 0x0c, 0xfc, 0xec, 0xfb, 0xec, 0xfb, 0xea, 0xfb, 0xea, 0xfb, 0x05, 0xfc, 0x05, 0xfc, 0x38, 0xfc, 0x38, 0xfc, 0x7d, 0xfc, 0x7d, 0xfc, 0xcf, 0xfc, 0xcf, 0xfc, 0x33, 0xfd, 0x33, 0xfd, 0xad, 0xfd, 0xad, 0xfd, 0x3e, 0xfe, 0x3e, 0xfe, 0xe4, 0xfe, 0xe4, 0xfe, 0x97, 0xff, 0x97, 0xff, 0x50, 0x00, 0x50, 0x00, 0x03, 0x01, 0x03, 0x01, 0xa6, 0x01, 0xa6, 0x01, 0x36, 0x02, 0x36, 0x02, 0xb8, 0x02, 0xb8, 0x02, 0x2c, 0x03, 0x2c, 0x03, 0x91, 0x03, 0x91, 0x03, 0xe4, 0x03, 0xe4, 0x03, 0x1d, 0x04, 0x1d, 0x04, 0x35, 0x04, 0x35, 0x04, 0x27, 0x04, 0x27, 0x04, 0xf7, 0x03, 0xf7, 0x03, 0xb1, 0x03, 0xb1, 0x03, 0x5b, 0x03, 0x5b, 0x03, 0xf7, 0x02, 0xf7, 0x02, 0x83, 0x02, 0x83, 0x02, 0xfa, 0x01, 0xfa, 0x01, 0x61, 0x01, 0x61, 0x01, 0xbe, 0x00, 0xbe, 0x00, 0x19, 0x00, 0x19, 0x00, 0x7c, 0xff, 0x7c, 0xff, 0xf0, 0xfe, 0xf0, 0xfe, 0x78, 0xfe, 0x78, 0xfe, 0x14, 0xfe, 0x14, 0xfe, 0xbf, 0xfd, 0xbf, 0xfd, 0x75, 0xfd, 0x75, 0xfd, 0x38, 0xfd, 0x38, 0xfd, 0x0c, 0xfd, 0x0c, 0xfd, 0xf6, 0xfc, 0xf6, 0xfc, 0xf4, 0xfc, 0xf4, 0xfc, 0x06, 0xfd, 0x06, 0xfd, 0x26, 0xfd, 0x26, 0xfd, 0x4e, 0xfd, 0x4e, 0xfd, 0x7d, 0xfd, 0x7d, 0xfd, 0xb4, 0xfd, 0xb4, 0xfd, 0xf7, 0xfd, 0xf7, 0xfd, 0x48, 0xfe, 0x48, 0xfe, 0xaa, 0xfe, 0xaa, 0xfe, 0x1c, 0xff, 0x1c, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0x22, 0x00, 0x22, 0x00, 0xa4, 0x00, 0xa4, 0x00, 0x1c, 0x01, 0x1c, 0x01, 0x87, 0x01, 0x87, 0x01, 0xe5, 0x01, 0xe5, 0x01, 0x35, 0x02, 0x35, 0x02, 0x75, 0x02, 0x75, 0x02, 0x9f, 0x02, 0x9f, 0x02, 0xaf, 0x02, 0xaf, 0x02, 0xa3, 0x02, 0xa3, 0x02, 0x7d, 0x02, 0x7d, 0x02, 0x42, 0x02, 0x42, 0x02, 0xf9, 0x01, 0xf9, 0x01, 0xaa, 0x01, 0xaa, 0x01, 0x57, 0x01, 0x57, 0x01, 0x04, 0x01, 0x04, 0x01, 0xad, 0x00, 0xad, 0x00, 0x53, 0x00, 0x53, 0x00, 0xf4, 0xff, 0xf4, 0xff, 0x97, 0xff, 0x97, 0xff, 0x44, 0xff, 0x44, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xc9, 0xfe, 0xc9, 0xfe, 0x9c, 0xfe, 0x9c, 0xfe, 0x76, 0xfe, 0x76, 0xfe, 0x57, 0xfe, 0x57, 0xfe, 0x43, 0xfe, 0x43, 0xfe, 0x3a, 0xfe, 0x3a, 0xfe, 0x3d, 0xfe, 0x3d, 0xfe, 0x4a, 0xfe, 0x4a, 0xfe, 0x5b, 0xfe, 0x5b, 0xfe, 0x71, 0xfe, 0x71, 0xfe, 0x8c, 0xfe, 0x8c, 0xfe, 0xac, 0xfe, 0xac, 0xfe, 0xd6, 0xfe, 0xd6, 0xfe, 0x09, 0xff, 0x09, 0xff, 0x48, 0xff, 0x48, 0xff, 0x8c, 0xff, 0x8c, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0x25, 0x00, 0x25, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x48, 0x01, 0x48, 0x01, 0xad, 0x01, 0xad, 0x01, 0x07, 0x02, 0x07, 0x02, 0x4f, 0x02, 0x4f, 0x02, 0x82, 0x02, 0x82, 0x02, 0x9e, 0x02, 0x9e, 0x02, 0xa7, 0x02, 0xa7, 0x02, 0xa3, 0x02, 0xa3, 0x02, 0x90, 0x02, 0x90, 0x02, 0x6a, 0x02, 0x6a, 0x02, 0x2f, 0x02, 0x2f, 0x02, 0xe2, 0x01, 0xe2, 0x01, 0x86, 0x01, 0x86, 0x01, 0x24, 0x01, 0x24, 0x01, 0xc4, 0x00, 0xc4, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0xcf, 0xff, 0xcf, 0xff, 0x84, 0xff, 0x84, 0xff, 0x3b, 0xff, 0x3b, 0xff, 0xf4, 0xfe, 0xf4, 0xfe, 0xb2, 0xfe, 0xb2, 0xfe, 0x72, 0xfe, 0x72, 0xfe, 0x30, 0xfe, 0x30, 0xfe, 0xeb, 0xfd, 0xeb, 0xfd, 0xa7, 0xfd, 0xa7, 0xfd, 0x67, 0xfd, 0x67, 0xfd, 0x2f, 0xfd, 0x2f, 0xfd, 0x02, 0xfd, 0x02, 0xfd, 0xe2, 0xfc, 0xe2, 0xfc, 0xd1, 0xfc, 0xd1, 0xfc, 0xd1, 0xfc, 0xd1, 0xfc, 0xe5, 0xfc, 0xe5, 0xfc, 0x10, 0xfd, 0x10, 0xfd, 0x53, 0xfd, 0x53, 0xfd, 0xab, 0xfd, 0xab, 0xfd, 0x15, 0xfe, 0x15, 0xfe, 0x8a, 0xfe, 0x8a, 0xfe, 0x08, 0xff, 0x08, 0xff, 0x87, 0xff, 0x87, 0xff, 0x04, 0x00, 0x04, 0x00, 0x80, 0x00, 0x80, 0x00, 0xfa, 0x00, 0xfa, 0x00, 0x6c, 0x01, 0x6c, 0x01, 0xcf, 0x01, 0xcf, 0x01, 0x1f, 0x02, 0x1f, 0x02, 0x59, 0x02, 0x59, 0x02, 0x81, 0x02, 0x81, 0x02, 0x99, 0x02, 0x99, 0x02, 0xa5, 0x02, 0xa5, 0x02, 0xa8, 0x02, 0xa8, 0x02, 0x9e, 0x02, 0x9e, 0x02, 0x87, 0x02, 0x87, 0x02, 0x65, 0x02, 0x65, 0x02, 0x3b, 0x02, 0x3b, 0x02, 0x0d, 0x02, 0x0d, 0x02, 0xd9, 0x01, 0xd9, 0x01, 0x9f, 0x01, 0x9f, 0x01, 0x5e, 0x01, 0x5e, 0x01, 0x11, 0x01, 0x11, 0x01, 0xba, 0x00, 0xba, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0xfb, 0xff, 0xfb, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0x41, 0xff, 0x41, 0xff, 0xea, 0xfe, 0xea, 0xfe, 0x95, 0xfe, 0x95, 0xfe, 0x43, 0xfe, 0x43, 0xfe, 0xf7, 0xfd, 0xf7, 0xfd, 0xba, 0xfd, 0xba, 0xfd, 0x92, 0xfd, 0x92, 0xfd, 0x87, 0xfd, 0x87, 0xfd, 0x97, 0xfd, 0x97, 0xfd, 0xb8, 0xfd, 0xb8, 0xfd, 0xe5, 0xfd, 0xe5, 0xfd, 0x19, 0xfe, 0x19, 0xfe, 0x53, 0xfe, 0x53, 0xfe, 0x94, 0xfe, 0x94, 0xfe, 0xdb, 0xfe, 0xdb, 0xfe, 0x28, 0xff, 0x28, 0xff, 0x77, 0xff, 0x77, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2e, 0x00, 0x2e, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x69, 0x00, 0x69, 0x00, 0x84, 0x00, 0x84, 0x00, 0xa1, 0x00, 0xa1, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xda, 0x00, 0xda, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0x04, 0x01, 0x04, 0x01, 0x14, 0x01, 0x14, 0x01, 0x24, 0x01, 0x24, 0x01, 0x34, 0x01, 0x34, 0x01, 0x40, 0x01, 0x40, 0x01, 0x45, 0x01, 0x45, 0x01, 0x40, 0x01, 0x40, 0x01, 0x30, 0x01, 0x30, 0x01, 0x18, 0x01, 0x18, 0x01, 0xfb, 0x00, 0xfb, 0x00, 0xdc, 0x00, 0xdc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0x9e, 0x00, 0x9e, 0x00, 0x81, 0x00, 0x81, 0x00, 0x69, 0x00, 0x69, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x64, 0x00, 0x64, 0x00, 0x73, 0x00, 0x73, 0x00, 0x83, 0x00, 0x83, 0x00, 0x8d, 0x00, 0x8d, 0x00, 0x8a, 0x00, 0x8a, 0x00, 0x7f, 0x00, 0x7f, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x55, 0x00, 0x55, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x19, 0x00, 0x19, 0x00, 0xeb, 0xff, 0xeb, 0xff, 0xac, 0xff, 0xac, 0xff, 0x5f, 0xff, 0x5f, 0xff, 0x0c, 0xff, 0x0c, 0xff, 0xbd, 0xfe, 0xbd, 0xfe, 0x77, 0xfe, 0x77, 0xfe, 0x3e, 0xfe, 0x3e, 0xfe, 0x10, 0xfe, 0x10, 0xfe, 0xeb, 0xfd, 0xeb, 0xfd, 0xce, 0xfd, 0xce, 0xfd, 0xb9, 0xfd, 0xb9, 0xfd, 0xad, 0xfd, 0xad, 0xfd, 0xac, 0xfd, 0xac, 0xfd, 0xb6, 0xfd, 0xb6, 0xfd, 0xce, 0xfd, 0xce, 0xfd, 0xf1, 0xfd, 0xf1, 0xfd, 0x1a, 0xfe, 0x1a, 0xfe, 0x46, 0xfe, 0x46, 0xfe, 0x73, 0xfe, 0x73, 0xfe, 0xa2, 0xfe, 0xa2, 0xfe, 0xd4, 0xfe, 0xd4, 0xfe, 0x07, 0xff, 0x07, 0xff, 0x3e, 0xff, 0x3e, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0x26, 0x00, 0x26, 0x00, 0x85, 0x00, 0x85, 0x00, 0xe4, 0x00, 0xe4, 0x00, 0x3e, 0x01, 0x3e, 0x01, 0x93, 0x01, 0x93, 0x01, 0xe3, 0x01, 0xe3, 0x01, 0x2c, 0x02, 0x2c, 0x02, 0x6e, 0x02, 0x6e, 0x02, 0xa5, 0x02, 0xa5, 0x02, 0xd0, 0x02, 0xd0, 0x02, 0xea, 0x02, 0xea, 0x02, 0xf0, 0x02, 0xf0, 0x02, 0xe8, 0x02, 0xe8, 0x02, 0xd5, 0x02, 0xd5, 0x02, 0xc0, 0x02, 0xc0, 0x02, 0xad, 0x02, 0xad, 0x02, 0x9d, 0x02, 0x9d, 0x02, 0x8b, 0x02, 0x8b, 0x02, 0x76, 0x02, 0x76, 0x02, 0x5f, 0x02, 0x5f, 0x02, 0x48, 0x02, 0x48, 0x02, 0x32, 0x02, 0x32, 0x02, 0x1b, 0x02, 0x1b, 0x02, 0xff, 0x01, 0xff, 0x01, 0xdb, 0x01, 0xdb, 0x01, 0xae, 0x01, 0xae, 0x01, 0x75, 0x01, 0x75, 0x01, 0x37, 0x01, 0x37, 0x01, 0xf5, 0x00, 0xf5, 0x00, 0xb6, 0x00, 0xb6, 0x00, 0x79, 0x00, 0x79, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x03, 0x00, 0xc7, 0xff, 0xc7, 0xff, 0x8b, 0xff, 0x8b, 0xff, 0x54, 0xff, 0x54, 0xff, 0x22, 0xff, 0x22, 0xff, 0xf2, 0xfe, 0xf2, 0xfe, 0xbf, 0xfe, 0xbf, 0xfe, 0x85, 0xfe, 0x85, 0xfe, 0x43, 0xfe, 0x43, 0xfe, 0xf9, 0xfd, 0xf9, 0xfd, 0xad, 0xfd, 0xad, 0xfd, 0x63, 0xfd, 0x63, 0xfd, 0x20, 0xfd, 0x20, 0xfd, 0xe3, 0xfc, 0xe3, 0xfc, 0xa9, 0xfc, 0xa9, 0xfc, 0x73, 0xfc, 0x73, 0xfc, 0x45, 0xfc, 0x45, 0xfc, 0x24, 0xfc, 0x24, 0xfc, 0x15, 0xfc, 0x15, 0xfc, 0x1b, 0xfc, 0x1b, 0xfc, 0x35, 0xfc, 0x35, 0xfc, 0x61, 0xfc, 0x61, 0xfc, 0x9c, 0xfc, 0x9c, 0xfc, 0xe5, 0xfc, 0xe5, 0xfc, 0x3c, 0xfd, 0x3c, 0xfd, 0x9f, 0xfd, 0x9f, 0xfd, 0x11, 0xfe, 0x11, 0xfe, 0x8e, 0xfe, 0x8e, 0xfe, 0x15, 0xff, 0x15, 0xff, 0x9f, 0xff, 0x9f, 0xff, 0x29, 0x00, 0x29, 0x00, 0xb0, 0x00, 0xb0, 0x00, 0x32, 0x01, 0x32, 0x01, 0xae, 0x01, 0xae, 0x01, 0x22, 0x02, 0x22, 0x02, 0x8e, 0x02, 0x8e, 0x02, 0xef, 0x02, 0xef, 0x02, 0x3f, 0x03, 0x3f, 0x03, 0x82, 0x03, 0x82, 0x03, 0xbb, 0x03, 0xbb, 0x03, 0xe9, 0x03, 0xe9, 0x03, 0x0c, 0x04, 0x0c, 0x04, 0x1e, 0x04, 0x1e, 0x04, 0x1f, 0x04, 0x1f, 0x04, 0x0a, 0x04, 0x0a, 0x04, 0xde, 0x03, 0xde, 0x03, 0x9c, 0x03, 0x9c, 0x03, 0x4a, 0x03, 0x4a, 0x03, 0xed, 0x02, 0xed, 0x02, 0x88, 0x02, 0x88, 0x02, 0x19, 0x02, 0x19, 0x02, 0xa0, 0x01, 0xa0, 0x01, 0x1c, 0x01, 0x1c, 0x01, 0x94, 0x00, 0x94, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x86, 0xff, 0x86, 0xff, 0x0e, 0xff, 0x0e, 0xff, 0xa3, 0xfe, 0xa3, 0xfe, 0x46, 0xfe, 0x46, 0xfe, 0xf5, 0xfd, 0xf5, 0xfd, 0xae, 0xfd, 0xae, 0xfd, 0x73, 0xfd, 0x73, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x22, 0xfd, 0x22, 0xfd, 0x0d, 0xfd, 0x0d, 0xfd, 0x05, 0xfd, 0x05, 0xfd, 0x07, 0xfd, 0x07, 0xfd, 0x11, 0xfd, 0x11, 0xfd, 0x21, 0xfd, 0x21, 0xfd, 0x3b, 0xfd, 0x3b, 0xfd, 0x5e, 0xfd, 0x5e, 0xfd, 0x8c, 0xfd, 0x8c, 0xfd, 0xc5, 0xfd, 0xc5, 0xfd, 0x0b, 0xfe, 0x0b, 0xfe, 0x5c, 0xfe, 0x5c, 0xfe, 0xb3, 0xfe, 0xb3, 0xfe, 0x0d, 0xff, 0x0d, 0xff, 0x65, 0xff, 0x65, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0x16, 0x00, 0x16, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0xc4, 0x00, 0xc4, 0x00, 0x10, 0x01, 0x10, 0x01, 0x4e, 0x01, 0x4e, 0x01, 0x7f, 0x01, 0x7f, 0x01, 0xa0, 0x01, 0xa0, 0x01, 0xb0, 0x01, 0xb0, 0x01, 0xae, 0x01, 0xae, 0x01, 0x9b, 0x01, 0x9b, 0x01, 0x7e, 0x01, 0x7e, 0x01, 0x58, 0x01, 0x58, 0x01, 0x27, 0x01, 0x27, 0x01, 0xf1, 0x00, 0xf1, 0x00, 0xb5, 0x00, 0xb5, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0x41, 0x00, 0x41, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0xd9, 0xff, 0xd9, 0xff, 0xaa, 0xff, 0xaa, 0xff, 0x80, 0xff, 0x80, 0xff, 0x5c, 0xff, 0x5c, 0xff, 0x40, 0xff, 0x40, 0xff, 0x2b, 0xff, 0x2b, 0xff, 0x17, 0xff, 0x17, 0xff, 0x04, 0xff, 0x04, 0xff, 0xf3, 0xfe, 0xf3, 0xfe, 0xe4, 0xfe, 0xe4, 0xfe, 0xdd, 0xfe, 0xdd, 0xfe, 0xdc, 0xfe, 0xdc, 0xfe, 0xe1, 0xfe, 0xe1, 0xfe, 0xee, 0xfe, 0xee, 0xfe, 0x01, 0xff, 0x01, 0xff, 0x1d, 0xff, 0x1d, 0xff, 0x45, 0xff, 0x45, 0xff, 0x79, 0xff, 0x79, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x47, 0x00, 0x47, 0x00, 0x90, 0x00, 0x90, 0x00, 0xd6, 0x00, 0xd6, 0x00, 0x18, 0x01, 0x18, 0x01, 0x53, 0x01, 0x53, 0x01, 0x8a, 0x01, 0x8a, 0x01, 0xb8, 0x01, 0xb8, 0x01, 0xda, 0x01, 0xda, 0x01, 0xf0, 0x01, 0xf0, 0x01, 0xf8, 0x01, 0xf8, 0x01, 0xf7, 0x01, 0xf7, 0x01, 0xef, 0x01, 0xef, 0x01, 0xe2, 0x01, 0xe2, 0x01, 0xd2, 0x01, 0xd2, 0x01, 0xbc, 0x01, 0xbc, 0x01, 0x9c, 0x01, 0x9c, 0x01, 0x73, 0x01, 0x73, 0x01, 0x44, 0x01, 0x44, 0x01, 0x13, 0x01, 0x13, 0x01, 0xe2, 0x00, 0xe2, 0x00, 0xb0, 0x00, 0xb0, 0x00, 0x77, 0x00, 0x77, 0x00, 0x38, 0x00, 0x38, 0x00, 0xf4, 0xff, 0xf4, 0xff, 0xab, 0xff, 0xab, 0xff, 0x62, 0xff, 0x62, 0xff, 0x1b, 0xff, 0x1b, 0xff, 0xd7, 0xfe, 0xd7, 0xfe, 0x96, 0xfe, 0x96, 0xfe, 0x5a, 0xfe, 0x5a, 0xfe, 0x22, 0xfe, 0x22, 0xfe, 0xf2, 0xfd, 0xf2, 0xfd, 0xcb, 0xfd, 0xcb, 0xfd, 0xb1, 0xfd, 0xb1, 0xfd, 0xa4, 0xfd, 0xa4, 0xfd, 0xa6, 0xfd, 0xa6, 0xfd, 0xb6, 0xfd, 0xb6, 0xfd, 0xd0, 0xfd, 0xd0, 0xfd, 0xf5, 0xfd, 0xf5, 0xfd, 0x24, 0xfe, 0x24, 0xfe, 0x5b, 0xfe, 0x5b, 0xfe, 0x9a, 0xfe, 0x9a, 0xfe, 0xe2, 0xfe, 0xe2, 0xfe, 0x30, 0xff, 0x30, 0xff, 0x82, 0xff, 0x82, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0x3b, 0x00, 0x3b, 0x00, 0xa5, 0x00, 0xa5, 0x00, 0x14, 0x01, 0x14, 0x01, 0x82, 0x01, 0x82, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x46, 0x02, 0x46, 0x02, 0x99, 0x02, 0x99, 0x02, 0xdd, 0x02, 0xdd, 0x02, 0x11, 0x03, 0x11, 0x03, 0x32, 0x03, 0x32, 0x03, 0x3c, 0x03, 0x3c, 0x03, 0x30, 0x03, 0x30, 0x03, 0x0a, 0x03, 0x0a, 0x03, 0xcf, 0x02, 0xcf, 0x02, 0x83, 0x02, 0x83, 0x02, 0x2d, 0x02, 0x2d, 0x02, 0xd3, 0x01, 0xd3, 0x01, 0x76, 0x01, 0x76, 0x01, 0x16, 0x01, 0x16, 0x01, 0xb3, 0x00, 0xb3, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0xe7, 0xff, 0xe7, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x18, 0xff, 0x18, 0xff, 0xb2, 0xfe, 0xb2, 0xfe, 0x50, 0xfe, 0x50, 0xfe, 0xf2, 0xfd, 0xf2, 0xfd, 0x97, 0xfd, 0x97, 0xfd, 0x42, 0xfd, 0x42, 0xfd, 0xf8, 0xfc, 0xf8, 0xfc, 0xbc, 0xfc, 0xbc, 0xfc, 0x93, 0xfc, 0x93, 0xfc, 0x81, 0xfc, 0x81, 0xfc, 0x85, 0xfc, 0x85, 0xfc, 0xa0, 0xfc, 0xa0, 0xfc, 0xcd, 0xfc, 0xcd, 0xfc, 0x09, 0xfd, 0x09, 0xfd, 0x54, 0xfd, 0x54, 0xfd, 0xaf, 0xfd, 0xaf, 0xfd, 0x1a, 0xfe, 0x1a, 0xfe, 0x8f, 0xfe, 0x8f, 0xfe, 0x0b, 0xff, 0x0b, 0xff, 0x88, 0xff, 0x88, 0xff, 0x02, 0x00, 0x02, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0xf4, 0x00, 0xf4, 0x00, 0x6f, 0x01, 0x6f, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x58, 0x02, 0x58, 0x02, 0xb6, 0x02, 0xb6, 0x02, 0xfd, 0x02, 0xfd, 0x02, 0x2b, 0x03, 0x2b, 0x03, 0x46, 0x03, 0x46, 0x03, 0x53, 0x03, 0x53, 0x03, 0x56, 0x03, 0x56, 0x03, 0x4e, 0x03, 0x4e, 0x03, 0x36, 0x03, 0x36, 0x03, 0x0c, 0x03, 0x0c, 0x03, 0xd2, 0x02, 0xd2, 0x02, 0x8b, 0x02, 0x8b, 0x02, 0x3f, 0x02, 0x3f, 0x02, 0xf2, 0x01, 0xf2, 0x01, 0xa6, 0x01, 0xa6, 0x01, 0x5a, 0x01, 0x5a, 0x01, 0x07, 0x01, 0x07, 0x01, 0xa6, 0x00, 0xa6, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0xc7, 0xff, 0xc7, 0xff, 0x55, 0xff, 0x55, 0xff, 0xe7, 0xfe, 0xe7, 0xfe, 0x80, 0xfe, 0x80, 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0xc3, 0xfd, 0xc3, 0xfd, 0x70, 0xfd, 0x70, 0xfd, 0x2d, 0xfd, 0x2d, 0xfd, 0xfe, 0xfc, 0xfe, 0xfc, 0xe6, 0xfc, 0xe6, 0xfc, 0xe5, 0xfc, 0xe5, 0xfc, 0xf8, 0xfc, 0xf8, 0xfc, 0x19, 0xfd, 0x19, 0xfd, 0x45, 0xfd, 0x45, 0xfd, 0x7a, 0xfd, 0x7a, 0xfd, 0xb6, 0xfd, 0xb6, 0xfd, 0xf3, 0xfd, 0xf3, 0xfd, 0x35, 0xfe, 0x35, 0xfe, 0x7b, 0xfe, 0x7b, 0xfe, 0xc6, 0xfe, 0xc6, 0xfe, 0x0f, 0xff, 0x0f, 0xff, 0x56, 0xff, 0x56, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0x32, 0x00, 0x32, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0xc9, 0x00, 0xc9, 0x00, 0x1a, 0x01, 0x1a, 0x01, 0x6e, 0x01, 0x6e, 0x01, 0xc3, 0x01, 0xc3, 0x01, 0x14, 0x02, 0x14, 0x02, 0x60, 0x02, 0x60, 0x02, 0xa4, 0x02, 0xa4, 0x02, 0xde, 0x02, 0xde, 0x02, 0x0e, 0x03, 0x0e, 0x03, 0x31, 0x03, 0x31, 0x03, 0x45, 0x03, 0x45, 0x03, 0x46, 0x03, 0x46, 0x03, 0x33, 0x03, 0x33, 0x03, 0x0a, 0x03, 0x0a, 0x03, 0xce, 0x02, 0xce, 0x02, 0x86, 0x02, 0x86, 0x02, 0x32, 0x02, 0x32, 0x02, 0xd7, 0x01, 0xd7, 0x01, 0x74, 0x01, 0x74, 0x01, 0x0c, 0x01, 0x0c, 0x01, 0xa2, 0x00, 0xa2, 0x00, 0x38, 0x00, 0x38, 0x00, 0xce, 0xff, 0xce, 0xff, 0x66, 0xff, 0x66, 0xff, 0x03, 0xff, 0x03, 0xff, 0xa4, 0xfe, 0xa4, 0xfe, 0x48, 0xfe, 0x48, 0xfe, 0xef, 0xfd, 0xef, 0xfd, 0x95, 0xfd, 0x95, 0xfd, 0x3c, 0xfd, 0x3c, 0xfd, 0xe5, 0xfc, 0xe5, 0xfc, 0x94, 0xfc, 0x94, 0xfc, 0x4f, 0xfc, 0x4f, 0xfc, 0x15, 0xfc, 0x15, 0xfc, 0xe8, 0xfb, 0xe8, 0xfb, 0xcc, 0xfb, 0xcc, 0xfb, 0xc3, 0xfb, 0xc3, 0xfb, 0xcf, 0xfb, 0xcf, 0xfb, 0xf2, 0xfb, 0xf2, 0xfb, 0x2f, 0xfc, 0x2f, 0xfc, 0x84, 0xfc, 0x84, 0xfc, 0xee, 0xfc, 0xee, 0xfc, 0x67, 0xfd, 0x67, 0xfd, 0xee, 0xfd, 0xee, 0xfd, 0x81, 0xfe, 0x81, 0xfe, 0x1f, 0xff, 0x1f, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0x6d, 0x00, 0x6d, 0x00, 0x13, 0x01, 0x13, 0x01, 0xb1, 0x01, 0xb1, 0x01, 0x42, 0x02, 0x42, 0x02, 0xc6, 0x02, 0xc6, 0x02, 0x3a, 0x03, 0x3a, 0x03, 0x9e, 0x03, 0x9e, 0x03, 0xf3, 0x03, 0xf3, 0x03, 0x38, 0x04, 0x38, 0x04, 0x6a, 0x04, 0x6a, 0x04, 0x89, 0x04, 0x89, 0x04, 0x95, 0x04, 0x95, 0x04, 0x8e, 0x04, 0x8e, 0x04, 0x78, 0x04, 0x78, 0x04, 0x51, 0x04, 0x51, 0x04, 0x19, 0x04, 0x19, 0x04, 0xcd, 0x03, 0xcd, 0x03, 0x6d, 0x03, 0x6d, 0x03, 0xf9, 0x02, 0xf9, 0x02, 0x73, 0x02, 0x73, 0x02, 0xde, 0x01, 0xde, 0x01, 0x3e, 0x01, 0x3e, 0x01, 0x97, 0x00, 0x97, 0x00, 0xe8, 0xff, 0xe8, 0xff, 0x36, 0xff, 0x36, 0xff, 0x88, 0xfe, 0x88, 0xfe, 0xe1, 0xfd, 0xe1, 0xfd, 0x47, 0xfd, 0x47, 0xfd, 0xc0, 0xfc, 0xc0, 0xfc, 0x51, 0xfc, 0x51, 0xfc, 0x01, 0xfc, 0x01, 0xfc, 0xcc, 0xfb, 0xcc, 0xfb, 0xaf, 0xfb, 0xaf, 0xfb, 0xa9, 0xfb, 0xa9, 0xfb, 0xb9, 0xfb, 0xb9, 0xfb, 0xe0, 0xfb, 0xe0, 0xfb, 0x1a, 0xfc, 0x1a, 0xfc, 0x66, 0xfc, 0x66, 0xfc, 0xc0, 0xfc, 0xc0, 0xfc, 0x23, 0xfd, 0x23, 0xfd, 0x8c, 0xfd, 0x8c, 0xfd, 0xfc, 0xfd, 0xfc, 0xfd, 0x73, 0xfe, 0x73, 0xfe, 0xf2, 0xfe, 0xf2, 0xfe, 0x75, 0xff, 0x75, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0x80, 0x00, 0x80, 0x00, 0x05, 0x01, 0x05, 0x01, 0x86, 0x01, 0x86, 0x01, 0xfd, 0x01, 0xfd, 0x01, 0x67, 0x02, 0x67, 0x02, 0xc2, 0x02, 0xc2, 0x02, 0x0c, 0x03, 0x0c, 0x03, 0x43, 0x03, 0x43, 0x03, 0x60, 0x03, 0x60, 0x03, 0x64, 0x03, 0x64, 0x03, 0x4a, 0x03, 0x4a, 0x03, 0x16, 0x03, 0x16, 0x03, 0xc9, 0x02, 0xc9, 0x02, 0x64, 0x02, 0x64, 0x02, 0xeb, 0x01, 0xeb, 0x01, 0x62, 0x01, 0x62, 0x01, 0xd0, 0x00, 0xd0, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0xae, 0xff, 0xae, 0xff, 0x29, 0xff, 0x29, 0xff, 0xae, 0xfe, 0xae, 0xfe, 0x40, 0xfe, 0x40, 0xfe, 0xe2, 0xfd, 0xe2, 0xfd, 0x96, 0xfd, 0x96, 0xfd, 0x5a, 0xfd, 0x5a, 0xfd, 0x2d, 0xfd, 0x2d, 0xfd, 0x12, 0xfd, 0x12, 0xfd, 0x0c, 0xfd, 0x0c, 0xfd, 0x1b, 0xfd, 0x1b, 0xfd, 0x3c, 0xfd, 0x3c, 0xfd, 0x70, 0xfd, 0x70, 0xfd, 0xb4, 0xfd, 0xb4, 0xfd, 0x08, 0xfe, 0x08, 0xfe, 0x6b, 0xfe, 0x6b, 0xfe, 0xdd, 0xfe, 0xdd, 0xfe, 0x5a, 0xff, 0x5a, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0x6a, 0x00, 0x6a, 0x00, 0xf5, 0x00, 0xf5, 0x00, 0x7f, 0x01, 0x7f, 0x01, 0x01, 0x02, 0x01, 0x02, 0x76, 0x02, 0x76, 0x02, 0xdd, 0x02, 0xdd, 0x02, 0x35, 0x03, 0x35, 0x03, 0x7d, 0x03, 0x7d, 0x03, 0xaf, 0x03, 0xaf, 0x03, 0xcb, 0x03, 0xcb, 0x03, 0xcf, 0x03, 0xcf, 0x03, 0xbb, 0x03, 0xbb, 0x03, 0x93, 0x03, 0x93, 0x03, 0x59, 0x03, 0x59, 0x03, 0x0b, 0x03, 0x0b, 0x03, 0xaa, 0x02, 0xaa, 0x02, 0x39, 0x02, 0x39, 0x02, 0xb9, 0x01, 0xb9, 0x01, 0x2d, 0x01, 0x2d, 0x01, 0x99, 0x00, 0x99, 0x00, 0x02, 0x00, 0x02, 0x00, 0x6d, 0xff, 0x6d, 0xff, 0xe0, 0xfe, 0xe0, 0xfe, 0x59, 0xfe, 0x59, 0xfe, 0xd9, 0xfd, 0xd9, 0xfd, 0x64, 0xfd, 0x64, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xa7, 0xfc, 0xa7, 0xfc, 0x69, 0xfc, 0x69, 0xfc, 0x47, 0xfc, 0x47, 0xfc, 0x41, 0xfc, 0x41, 0xfc, 0x56, 0xfc, 0x56, 0xfc, 0x83, 0xfc, 0x83, 0xfc, 0xc5, 0xfc, 0xc5, 0xfc, 0x1b, 0xfd, 0x1b, 0xfd, 0x84, 0xfd, 0x84, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0x88, 0xfe, 0x88, 0xfe, 0x1a, 0xff, 0x1a, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0x3e, 0x00, 0x3e, 0x00, 0xc6, 0x00, 0xc6, 0x00, 0x43, 0x01, 0x43, 0x01, 0xb3, 0x01, 0xb3, 0x01, 0x14, 0x02, 0x14, 0x02, 0x65, 0x02, 0x65, 0x02, 0xa7, 0x02, 0xa7, 0x02, 0xd8, 0x02, 0xd8, 0x02, 0xf9, 0x02, 0xf9, 0x02, 0x06, 0x03, 0x06, 0x03, 0x03, 0x03, 0x03, 0x03, 0xf0, 0x02, 0xf0, 0x02, 0xcf, 0x02, 0xcf, 0x02, 0xa2, 0x02, 0xa2, 0x02, 0x68, 0x02, 0x68, 0x02, 0x26, 0x02, 0x26, 0x02, 0xd9, 0x01, 0xd9, 0x01, 0x81, 0x01, 0x81, 0x01, 0x1d, 0x01, 0x1d, 0x01, 0xad, 0x00, 0xad, 0x00, 0x37, 0x00, 0x37, 0x00, 0xbf, 0xff, 0xbf, 0xff, 0x4b, 0xff, 0x4b, 0xff, 0xe2, 0xfe, 0xe2, 0xfe, 0x84, 0xfe, 0x84, 0xfe, 0x32, 0xfe, 0x32, 0xfe, 0xed, 0xfd, 0xed, 0xfd, 0xb3, 0xfd, 0xb3, 0xfd, 0x89, 0xfd, 0x89, 0xfd, 0x70, 0xfd, 0x70, 0xfd, 0x6b, 0xfd, 0x6b, 0xfd, 0x7b, 0xfd, 0x7b, 0xfd, 0x9e, 0xfd, 0x9e, 0xfd, 0xcc, 0xfd, 0xcc, 0xfd, 0x00, 0xfe, 0x00, 0xfe, 0x36, 0xfe, 0x36, 0xfe, 0x6f, 0xfe, 0x6f, 0xfe, 0xab, 0xfe, 0xab, 0xfe, 0xea, 0xfe, 0xea, 0xfe, 0x2a, 0xff, 0x2a, 0xff, 0x67, 0xff, 0x67, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0x09, 0x00, 0x09, 0x00, 0x26, 0x00, 0x26, 0x00, 0x43, 0x00, 0x43, 0x00, 0x5e, 0x00, 0x5e, 0x00, 0x75, 0x00, 0x75, 0x00, 0x86, 0x00, 0x86, 0x00, 0x93, 0x00, 0x93, 0x00, 0x9f, 0x00, 0x9f, 0x00, 0xb0, 0x00, 0xb0, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xd7, 0x00, 0xd7, 0x00, 0xe5, 0x00, 0xe5, 0x00, 0xec, 0x00, 0xec, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf2, 0x00, 0xf2, 0x00, 0xf7, 0x00, 0xf7, 0x00, 0x01, 0x01, 0x01, 0x01, 0x11, 0x01, 0x11, 0x01, 0x20, 0x01, 0x20, 0x01, 0x2b, 0x01, 0x2b, 0x01, 0x32, 0x01, 0x32, 0x01, 0x37, 0x01, 0x37, 0x01, 0x3e, 0x01, 0x3e, 0x01, 0x48, 0x01, 0x48, 0x01, 0x56, 0x01, 0x56, 0x01, 0x62, 0x01, 0x62, 0x01, 0x68, 0x01, 0x68, 0x01, 0x62, 0x01, 0x62, 0x01, 0x4e, 0x01, 0x4e, 0x01, 0x2e, 0x01, 0x2e, 0x01, 0x04, 0x01, 0x04, 0x01, 0xd2, 0x00, 0xd2, 0x00, 0x96, 0x00, 0x96, 0x00, 0x50, 0x00, 0x50, 0x00, 0xfe, 0xff, 0xfe, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0x3d, 0xff, 0x3d, 0xff, 0xd8, 0xfe, 0xd8, 0xfe, 0x72, 0xfe, 0x72, 0xfe, 0x10, 0xfe, 0x10, 0xfe, 0xb4, 0xfd, 0xb4, 0xfd, 0x5f, 0xfd, 0x5f, 0xfd, 0x16, 0xfd, 0x16, 0xfd, 0xdb, 0xfc, 0xdb, 0xfc, 0xb3, 0xfc, 0xb3, 0xfc, 0x9f, 0xfc, 0x9f, 0xfc, 0xa1, 0xfc, 0xa1, 0xfc, 0xb6, 0xfc, 0xb6, 0xfc, 0xe0, 0xfc, 0xe0, 0xfc, 0x1e, 0xfd, 0x1e, 0xfd, 0x6f, 0xfd, 0x6f, 0xfd, 0xd0, 0xfd, 0xd0, 0xfd, 0x3b, 0xfe, 0x3b, 0xfe, 0xb0, 0xfe, 0xb0, 0xfe, 0x2b, 0xff, 0x2b, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0x2a, 0x00, 0x2a, 0x00, 0xab, 0x00, 0xab, 0x00, 0x2d, 0x01, 0x2d, 0x01, 0xac, 0x01, 0xac, 0x01, 0x23, 0x02, 0x23, 0x02, 0x91, 0x02, 0x91, 0x02, 0xf2, 0x02, 0xf2, 0x02, 0x46, 0x03, 0x46, 0x03, 0x8c, 0x03, 0x8c, 0x03, 0xc4, 0x03, 0xc4, 0x03, 0xea, 0x03, 0xea, 0x03, 0xfb, 0x03, 0xfb, 0x03, 0xf3, 0x03, 0xf3, 0x03, 0xd2, 0x03, 0xd2, 0x03, 0x99, 0x03, 0x99, 0x03, 0x49, 0x03, 0x49, 0x03, 0xe6, 0x02, 0xe6, 0x02, 0x70, 0x02, 0x70, 0x02, 0xe7, 0x01, 0xe7, 0x01, 0x4b, 0x01, 0x4b, 0x01, 0xa2, 0x00, 0xa2, 0x00, 0xf1, 0xff, 0xf1, 0xff, 0x41, 0xff, 0x41, 0xff, 0x9d, 0xfe, 0x9d, 0xfe, 0x09, 0xfe, 0x09, 0xfe, 0x82, 0xfd, 0x82, 0xfd, 0x08, 0xfd, 0x08, 0xfd, 0x9e, 0xfc, 0x9e, 0xfc, 0x48, 0xfc, 0x48, 0xfc, 0x09, 0xfc, 0x09, 0xfc, 0xe8, 0xfb, 0xe8, 0xfb, 0xe4, 0xfb, 0xe4, 0xfb, 0xf9, 0xfb, 0xf9, 0xfb, 0x24, 0xfc, 0x24, 0xfc, 0x5f, 0xfc, 0x5f, 0xfc, 0xac, 0xfc, 0xac, 0xfc, 0x08, 0xfd, 0x08, 0xfd, 0x78, 0xfd, 0x78, 0xfd, 0xf6, 0xfd, 0xf6, 0xfd, 0x81, 0xfe, 0x81, 0xfe, 0x15, 0xff, 0x15, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0x3a, 0x00, 0x3a, 0x00, 0xc7, 0x00, 0xc7, 0x00, 0x51, 0x01, 0x51, 0x01, 0xd5, 0x01, 0xd5, 0x01, 0x4c, 0x02, 0x4c, 0x02, 0xb2, 0x02, 0xb2, 0x02, 0x03, 0x03, 0x03, 0x03, 0x40, 0x03, 0x40, 0x03, 0x66, 0x03, 0x66, 0x03, 0x78, 0x03, 0x78, 0x03, 0x77, 0x03, 0x77, 0x03, 0x64, 0x03, 0x64, 0x03, 0x3d, 0x03, 0x3d, 0x03, 0x01, 0x03, 0x01, 0x03, 0xb1, 0x02, 0xb1, 0x02, 0x4f, 0x02, 0x4f, 0x02, 0xe1, 0x01, 0xe1, 0x01, 0x6f, 0x01, 0x6f, 0x01, 0xff, 0x00, 0xff, 0x00, 0x91, 0x00, 0x91, 0x00, 0x25, 0x00, 0x25, 0x00, 0xb8, 0xff, 0xb8, 0xff, 0x4f, 0xff, 0x4f, 0xff, 0xf0, 0xfe, 0xf0, 0xfe, 0x9f, 0xfe, 0x9f, 0xfe, 0x5f, 0xfe, 0x5f, 0xfe, 0x31, 0xfe, 0x31, 0xfe, 0x14, 0xfe, 0x14, 0xfe, 0x03, 0xfe, 0x03, 0xfe, 0xfb, 0xfd, 0xfb, 0xfd, 0xfb, 0xfd, 0xfb, 0xfd, 0x04, 0xfe, 0x04, 0xfe, 0x19, 0xfe, 0x19, 0xfe, 0x3c, 0xfe, 0x3c, 0xfe, 0x70, 0xfe, 0x70, 0xfe, 0xb0, 0xfe, 0xb0, 0xfe, 0xf6, 0xfe, 0xf6, 0xfe, 0x3f, 0xff, 0x3f, 0xff, 0x88, 0xff, 0x88, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0x20, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0x0b, 0x01, 0x0b, 0x01, 0x4f, 0x01, 0x4f, 0x01, 0x87, 0x01, 0x87, 0x01, 0xac, 0x01, 0xac, 0x01, 0xbd, 0x01, 0xbd, 0x01, 0xbd, 0x01, 0xbd, 0x01, 0xad, 0x01, 0xad, 0x01, 0x8e, 0x01, 0x8e, 0x01, 0x5e, 0x01, 0x5e, 0x01, 0x1f, 0x01, 0x1f, 0x01, 0xd7, 0x00, 0xd7, 0x00, 0x87, 0x00, 0x87, 0x00, 0x32, 0x00, 0x32, 0x00, 0xdc, 0xff, 0xdc, 0xff, 0x87, 0xff, 0x87, 0xff, 0x3a, 0xff, 0x3a, 0xff, 0xf9, 0xfe, 0xf9, 0xfe, 0xc6, 0xfe, 0xc6, 0xfe, 0xa0, 0xfe, 0xa0, 0xfe, 0x89, 0xfe, 0x89, 0xfe, 0x7e, 0xfe, 0x7e, 0xfe, 0x7e, 0xfe, 0x7e, 0xfe, 0x8a, 0xfe, 0x8a, 0xfe, 0x9e, 0xfe, 0x9e, 0xfe, 0xbb, 0xfe, 0xbb, 0xfe, 0xe1, 0xfe, 0xe1, 0xfe, 0x0e, 0xff, 0x0e, 0xff, 0x41, 0xff, 0x41, 0xff, 0x79, 0xff, 0x79, 0xff, 0xb4, 0xff, 0xb4, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0x31, 0x00, 0x31, 0x00, 0x71, 0x00, 0x71, 0x00, 0xad, 0x00, 0xad, 0x00, 0xe8, 0x00, 0xe8, 0x00, 0x1e, 0x01, 0x1e, 0x01, 0x4d, 0x01, 0x4d, 0x01, 0x72, 0x01, 0x72, 0x01, 0x88, 0x01, 0x88, 0x01, 0x8e, 0x01, 0x8e, 0x01, 0x83, 0x01, 0x83, 0x01, 0x68, 0x01, 0x68, 0x01, 0x40, 0x01, 0x40, 0x01, 0x0a, 0x01, 0x0a, 0x01, 0xc9, 0x00, 0xc9, 0x00, 0x81, 0x00, 0x81, 0x00, 0x34, 0x00, 0x34, 0x00, 0xe2, 0xff, 0xe2, 0xff, 0x8e, 0xff, 0x8e, 0xff, 0x38, 0xff, 0x38, 0xff, 0xe6, 0xfe, 0xe6, 0xfe, 0x9d, 0xfe, 0x9d, 0xfe, 0x5e, 0xfe, 0x5e, 0xfe, 0x2f, 0xfe, 0x2f, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe, 0xfa, 0xfd, 0xfa, 0xfd, 0xf4, 0xfd, 0xf4, 0xfd, 0xfa, 0xfd, 0xfa, 0xfd, 0x0e, 0xfe, 0x0e, 0xfe, 0x32, 0xfe, 0x32, 0xfe, 0x67, 0xfe, 0x67, 0xfe, 0xad, 0xfe, 0xad, 0xfe, 0xfd, 0xfe, 0xfd, 0xfe, 0x55, 0xff, 0x55, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0x0f, 0x00, 0x0f, 0x00, 0x70, 0x00, 0x70, 0x00, 0xce, 0x00, 0xce, 0x00, 0x28, 0x01, 0x28, 0x01, 0x7a, 0x01, 0x7a, 0x01, 0xc2, 0x01, 0xc2, 0x01, 0xfc, 0x01, 0xfc, 0x01, 0x29, 0x02, 0x29, 0x02, 0x47, 0x02, 0x47, 0x02, 0x58, 0x02, 0x58, 0x02, 0x5b, 0x02, 0x5b, 0x02, 0x4d, 0x02, 0x4d, 0x02, 0x31, 0x02, 0x31, 0x02, 0x05, 0x02, 0x05, 0x02, 0xca, 0x01, 0xca, 0x01, 0x81, 0x01, 0x81, 0x01, 0x2c, 0x01, 0x2c, 0x01, 0xd1, 0x00, 0xd1, 0x00, 0x73, 0x00, 0x73, 0x00, 0x11, 0x00, 0x11, 0x00, 0xad, 0xff, 0xad, 0xff, 0x4a, 0xff, 0x4a, 0xff, 0xed, 0xfe, 0xed, 0xfe, 0x9b, 0xfe, 0x9b, 0xfe, 0x58, 0xfe, 0x58, 0xfe, 0x24, 0xfe, 0x24, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0xef, 0xfd, 0xef, 0xfd, 0xeb, 0xfd, 0xeb, 0xfd, 0xf4, 0xfd, 0xf4, 0xfd, 0x09, 0xfe, 0x09, 0xfe, 0x28, 0xfe, 0x28, 0xfe, 0x54, 0xfe, 0x54, 0xfe, 0x8b, 0xfe, 0x8b, 0xfe, 0xce, 0xfe, 0xce, 0xfe, 0x15, 0xff, 0x15, 0xff, 0x5f, 0xff, 0x5f, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0xed, 0xff, 0xed, 0xff, 0x2f, 0x00, 0x2f, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0xa8, 0x00, 0xa8, 0x00, 0xdc, 0x00, 0xdc, 0x00, 0x08, 0x01, 0x08, 0x01, 0x2a, 0x01, 0x2a, 0x01, 0x3e, 0x01, 0x3e, 0x01, 0x44, 0x01, 0x44, 0x01, 0x3b, 0x01, 0x3b, 0x01, 0x28, 0x01, 0x28, 0x01, 0x0d, 0x01, 0x0d, 0x01, 0xee, 0x00, 0xee, 0x00, 0xca, 0x00, 0xca, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0x71, 0x00, 0x71, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0xd9, 0xff, 0xd9, 0xff, 0xab, 0xff, 0xab, 0xff, 0x82, 0xff, 0x82, 0xff, 0x62, 0xff, 0x62, 0xff, 0x47, 0xff, 0x47, 0xff, 0x31, 0xff, 0x31, 0xff, 0x22, 0xff, 0x22, 0xff, 0x1c, 0xff, 0x1c, 0xff, 0x24, 0xff, 0x24, 0xff, 0x39, 0xff, 0x39, 0xff, 0x5b, 0xff, 0x5b, 0xff, 0x89, 0xff, 0x89, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x41, 0x00, 0x85, 0x00, 0x85, 0x00, 0xc8, 0x00, 0xc8, 0x00, 0x06, 0x01, 0x06, 0x01, 0x3e, 0x01, 0x3e, 0x01, 0x6c, 0x01, 0x6c, 0x01, 0x8e, 0x01, 0x8e, 0x01, 0xa2, 0x01, 0xa2, 0x01, 0xa8, 0x01, 0xa8, 0x01, 0xa5, 0x01, 0xa5, 0x01, 0x99, 0x01, 0x99, 0x01, 0x81, 0x01, 0x81, 0x01, 0x5f, 0x01, 0x5f, 0x01, 0x2f, 0x01, 0x2f, 0x01, 0xf4, 0x00, 0xf4, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0x64, 0x00, 0x64, 0x00, 0x17, 0x00, 0x17, 0x00, 0xc8, 0xff, 0xc8, 0xff, 0x79, 0xff, 0x79, 0xff, 0x28, 0xff, 0x28, 0xff, 0xd8, 0xfe, 0xd8, 0xfe, 0x8e, 0xfe, 0x8e, 0xfe, 0x4e, 0xfe, 0x4e, 0xfe, 0x1c, 0xfe, 0x1c, 0xfe, 0xf8, 0xfd, 0xf8, 0xfd, 0xe2, 0xfd, 0xe2, 0xfd, 0xda, 0xfd, 0xda, 0xfd, 0xe0, 0xfd, 0xe0, 0xfd, 0xf4, 0xfd, 0xf4, 0xfd, 0x14, 0xfe, 0x14, 0xfe, 0x43, 0xfe, 0x43, 0xfe, 0x82, 0xfe, 0x82, 0xfe, 0xcc, 0xfe, 0xcc, 0xfe, 0x1f, 0xff, 0x1f, 0xff, 0x75, 0xff, 0x75, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0x23, 0x00, 0x23, 0x00, 0x77, 0x00, 0x77, 0x00, 0xc7, 0x00, 0xc7, 0x00, 0x12, 0x01, 0x12, 0x01, 0x53, 0x01, 0x53, 0x01, 0x8d, 0x01, 0x8d, 0x01, 0xbc, 0x01, 0xbc, 0x01, 0xe0, 0x01, 0xe0, 0x01, 0xf7, 0x01, 0xf7, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0xf5, 0x01, 0xf5, 0x01, 0xdc, 0x01, 0xdc, 0x01, 0xb5, 0x01, 0xb5, 0x01, 0x85, 0x01, 0x85, 0x01, 0x4b, 0x01, 0x4b, 0x01, 0x0b, 0x01, 0x0b, 0x01, 0xc7, 0x00, 0xc7, 0x00, 0x81, 0x00, 0x81, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0xf9, 0xff, 0xf9, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0x8a, 0xff, 0x8a, 0xff, 0x5d, 0xff, 0x5d, 0xff, 0x37, 0xff, 0x37, 0xff, 0x16, 0xff, 0x16, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xee, 0xfe, 0xee, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xee, 0xfe, 0xee, 0xfe, 0xf5, 0xfe, 0xf5, 0xfe, 0xfd, 0xfe, 0xfd, 0xfe, 0x06, 0xff, 0x06, 0xff, 0x12, 0xff, 0x12, 0xff, 0x22, 0xff, 0x22, 0xff, 0x34, 0xff, 0x34, 0xff, 0x49, 0xff, 0x49, 0xff, 0x5e, 0xff, 0x5e, 0xff, 0x73, 0xff, 0x73, 0xff, 0x85, 0xff, 0x85, 0xff, 0x95, 0xff, 0x95, 0xff, 0xa5, 0xff, 0xa5, 0xff, 0xb6, 0xff, 0xb6, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xda, 0xff, 0xda, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xba, 0xff, 0xba, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0xac, 0xff, 0xac, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0xaa, 0xff, 0xaa, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0x15, 0x00, 0x15, 0x00, 0x31, 0x00, 0x31, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x68, 0x00, 0x68, 0x00, 0x85, 0x00, 0x85, 0x00, 0x9f, 0x00, 0x9f, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xc2, 0x00, 0xc2, 0x00, 0xca, 0x00, 0xca, 0x00, 0xce, 0x00, 0xce, 0x00, 0xcf, 0x00, 0xcf, 0x00, 0xd1, 0x00, 0xd1, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xbf, 0x00, 0xbf, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0x83, 0x00, 0x83, 0x00, 0x67, 0x00, 0x67, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x35, 0x00, 0x35, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0xf5, 0xff, 0xf5, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xce, 0xff, 0xce, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x0a, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x15, 0x00, 0x22, 0x00, 0x22, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x4d, 0x00, 0x4d, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x69, 0x00, 0x69, 0x00, 0x71, 0x00, 0x71, 0x00, 0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x72, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x42, 0x00, 0x42, 0x00, 0x24, 0x00, 0x24, 0x00, 0x02, 0x00, 0x02, 0x00, 0xdc, 0xff, 0xdc, 0xff, 0xb4, 0xff, 0xb4, 0xff, 0x8a, 0xff, 0x8a, 0xff, 0x62, 0xff, 0x62, 0xff, 0x3b, 0xff, 0x3b, 0xff, 0x16, 0xff, 0x16, 0xff, 0xf9, 0xfe, 0xf9, 0xfe, 0xe2, 0xfe, 0xe2, 0xfe, 0xd3, 0xfe, 0xd3, 0xfe, 0xcd, 0xfe, 0xcd, 0xfe, 0xd1, 0xfe, 0xd1, 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xfc, 0xfe, 0xfc, 0xfe, 0x20, 0xff, 0x20, 0xff, 0x4d, 0xff, 0x4d, 0xff, 0x82, 0xff, 0x82, 0xff, 0xba, 0xff, 0xba, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0x3e, 0x00, 0x3e, 0x00, 0x86, 0x00, 0x86, 0x00, 0xcd, 0x00, 0xcd, 0x00, 0x0d, 0x01, 0x0d, 0x01, 0x44, 0x01, 0x44, 0x01, 0x71, 0x01, 0x71, 0x01, 0x94, 0x01, 0x94, 0x01, 0xae, 0x01, 0xae, 0x01, 0xbc, 0x01, 0xbc, 0x01, 0xbe, 0x01, 0xbe, 0x01, 0xb3, 0x01, 0xb3, 0x01, 0x98, 0x01, 0x98, 0x01, 0x70, 0x01, 0x70, 0x01, 0x3d, 0x01, 0x3d, 0x01, 0x02, 0x01, 0x02, 0x01, 0xc1, 0x00, 0xc1, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0xda, 0xff, 0xda, 0xff, 0x83, 0xff, 0x83, 0xff, 0x2a, 0xff, 0x2a, 0xff, 0xd6, 0xfe, 0xd6, 0xfe, 0x88, 0xfe, 0x88, 0xfe, 0x41, 0xfe, 0x41, 0xfe, 0x03, 0xfe, 0x03, 0xfe, 0xd1, 0xfd, 0xd1, 0xfd, 0xae, 0xfd, 0xae, 0xfd, 0x9b, 0xfd, 0x9b, 0xfd, 0x9d, 0xfd, 0x9d, 0xfd, 0xb4, 0xfd, 0xb4, 0xfd, 0xe1, 0xfd, 0xe1, 0xfd, 0x23, 0xfe, 0x23, 0xfe, 0x74, 0xfe, 0x74, 0xfe, 0xd1, 0xfe, 0xd1, 0xfe, 0x38, 0xff, 0x38, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0x1c, 0x00, 0x1c, 0x00, 0x92, 0x00, 0x92, 0x00, 0x05, 0x01, 0x05, 0x01, 0x70, 0x01, 0x70, 0x01, 0xce, 0x01, 0xce, 0x01, 0x1d, 0x02, 0x1d, 0x02, 0x5c, 0x02, 0x5c, 0x02, 0x8b, 0x02, 0x8b, 0x02, 0xa9, 0x02, 0xa9, 0x02, 0xb6, 0x02, 0xb6, 0x02, 0xb1, 0x02, 0xb1, 0x02, 0x99, 0x02, 0x99, 0x02, 0x6d, 0x02, 0x6d, 0x02, 0x32, 0x02, 0x32, 0x02, 0xe9, 0x01, 0xe9, 0x01, 0x95, 0x01, 0x95, 0x01, 0x33, 0x01, 0x33, 0x01, 0xc5, 0x00, 0xc5, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0xcf, 0xff, 0xcf, 0xff, 0x4e, 0xff, 0x4e, 0xff, 0xcd, 0xfe, 0xcd, 0xfe, 0x52, 0xfe, 0x52, 0xfe, 0xe1, 0xfd, 0xe1, 0xfd, 0x7a, 0xfd, 0x7a, 0xfd, 0x22, 0xfd, 0x22, 0xfd, 0xd7, 0xfc, 0xd7, 0xfc, 0x9c, 0xfc, 0x9c, 0xfc, 0x75, 0xfc, 0x75, 0xfc, 0x61, 0xfc, 0x61, 0xfc, 0x63, 0xfc, 0x63, 0xfc, 0x79, 0xfc, 0x79, 0xfc, 0xa3, 0xfc, 0xa3, 0xfc, 0xe2, 0xfc, 0xe2, 0xfc, 0x35, 0xfd, 0x35, 0xfd, 0x9b, 0xfd, 0x9b, 0xfd, 0x10, 0xfe, 0x10, 0xfe, 0x95, 0xfe, 0x95, 0xfe, 0x23, 0xff, 0x23, 0xff, 0xb7, 0xff, 0xb7, 0xff, 0x4c, 0x00, 0x4c, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x6f, 0x01, 0x6f, 0x01, 0xf2, 0x01, 0xf2, 0x01, 0x68, 0x02, 0x68, 0x02, 0xcd, 0x02, 0xcd, 0x02, 0x21, 0x03, 0x21, 0x03, 0x60, 0x03, 0x60, 0x03, 0x8d, 0x03, 0x8d, 0x03, 0xa7, 0x03, 0xa7, 0x03, 0xaf, 0x03, 0xaf, 0x03, 0xa6, 0x03, 0xa6, 0x03, 0x8a, 0x03, 0x8a, 0x03, 0x5f, 0x03, 0x5f, 0x03, 0x26, 0x03, 0x26, 0x03, 0xde, 0x02, 0xde, 0x02, 0x89, 0x02, 0x89, 0x02, 0x29, 0x02, 0x29, 0x02, 0xbe, 0x01, 0xbe, 0x01, 0x4a, 0x01, 0x4a, 0x01, 0xcd, 0x00, 0xcd, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0xc5, 0xff, 0xc5, 0xff, 0x3e, 0xff, 0x3e, 0xff, 0xbb, 0xfe, 0xbb, 0xfe, 0x3b, 0xfe, 0x3b, 0xfe, 0xc6, 0xfd, 0xc6, 0xfd, 0x5e, 0xfd, 0x5e, 0xfd, 0x05, 0xfd, 0x05, 0xfd, 0xbe, 0xfc, 0xbe, 0xfc, 0x8c, 0xfc, 0x8c, 0xfc, 0x70, 0xfc, 0x70, 0xfc, 0x67, 0xfc, 0x67, 0xfc, 0x77, 0xfc, 0x77, 0xfc, 0x9c, 0xfc, 0x9c, 0xfc, 0xd6, 0xfc, 0xd6, 0xfc, 0x21, 0xfd, 0x21, 0xfd, 0x7c, 0xfd, 0x7c, 0xfd, 0xe6, 0xfd, 0xe6, 0xfd, 0x59, 0xfe, 0x59, 0xfe, 0xd0, 0xfe, 0xd0, 0xfe, 0x49, 0xff, 0x49, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0x35, 0x00, 0x35, 0x00, 0xa7, 0x00, 0xa7, 0x00, 0x14, 0x01, 0x14, 0x01, 0x7d, 0x01, 0x7d, 0x01, 0xe0, 0x01, 0xe0, 0x01, 0x3c, 0x02, 0x3c, 0x02, 0x91, 0x02, 0x91, 0x02, 0xde, 0x02, 0xde, 0x02, 0x20, 0x03, 0x20, 0x03, 0x55, 0x03, 0x55, 0x03, 0x7f, 0x03, 0x7f, 0x03, 0x9a, 0x03, 0x9a, 0x03, 0xa4, 0x03, 0xa4, 0x03, 0x99, 0x03, 0x99, 0x03, 0x78, 0x03, 0x78, 0x03, 0x43, 0x03, 0x43, 0x03, 0xfa, 0x02, 0xfa, 0x02, 0xa0, 0x02, 0xa0, 0x02, 0x34, 0x02, 0x34, 0x02, 0xba, 0x01, 0xba, 0x01, 0x34, 0x01, 0x34, 0x01, 0xa8, 0x00, 0xa8, 0x00, 0x19, 0x00, 0x19, 0x00, 0x8d, 0xff, 0x8d, 0xff, 0x08, 0xff, 0x08, 0xff, 0x8b, 0xfe, 0x8b, 0xfe, 0x1d, 0xfe, 0x1d, 0xfe, 0xbc, 0xfd, 0xbc, 0xfd, 0x6b, 0xfd, 0x6b, 0xfd, 0x2a, 0xfd, 0x2a, 0xfd, 0xf5, 0xfc, 0xf5, 0xfc, 0xcd, 0xfc, 0xcd, 0xfc, 0xb2, 0xfc, 0xb2, 0xfc, 0xa4, 0xfc, 0xa4, 0xfc, 0xa1, 0xfc, 0xa1, 0xfc, 0xab, 0xfc, 0xab, 0xfc, 0xbf, 0xfc, 0xbf, 0xfc, 0xe1, 0xfc, 0xe1, 0xfc, 0x14, 0xfd, 0x14, 0xfd, 0x55, 0xfd, 0x55, 0xfd, 0xa4, 0xfd, 0xa4, 0xfd, 0xfe, 0xfd, 0xfe, 0xfd, 0x62, 0xfe, 0x62, 0xfe, 0xcd, 0xfe, 0xcd, 0xfe, 0x3e, 0xff, 0x3e, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0x2c, 0x00, 0x2c, 0x00, 0x9f, 0x00, 0x9f, 0x00, 0x0d, 0x01, 0x0d, 0x01, 0x6f, 0x01, 0x6f, 0x01, 0xc3, 0x01, 0xc3, 0x01, 0x06, 0x02, 0x06, 0x02, 0x3a, 0x02, 0x3a, 0x02, 0x5b, 0x02, 0x5b, 0x02, 0x6d, 0x02, 0x6d, 0x02, 0x6f, 0x02, 0x6f, 0x02, 0x62, 0x02, 0x62, 0x02, 0x4c, 0x02, 0x4c, 0x02, 0x2a, 0x02, 0x2a, 0x02, 0x02, 0x02, 0x02, 0x02, 0xd1, 0x01, 0xd1, 0x01, 0x9c, 0x01, 0x9c, 0x01, 0x63, 0x01, 0x63, 0x01, 0x24, 0x01, 0x24, 0x01, 0xe4, 0x00, 0xe4, 0x00, 0xa4, 0x00, 0xa4, 0x00, 0x68, 0x00, 0x68, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0xf8, 0xff, 0xf8, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0x9b, 0xff, 0x9b, 0xff, 0x74, 0xff, 0x74, 0xff, 0x54, 0xff, 0x54, 0xff, 0x3a, 0xff, 0x3a, 0xff, 0x2b, 0xff, 0x2b, 0xff, 0x22, 0xff, 0x22, 0xff, 0x20, 0xff, 0x20, 0xff, 0x24, 0xff, 0x24, 0xff, 0x30, 0xff, 0x30, 0xff, 0x43, 0xff, 0x43, 0xff, 0x5a, 0xff, 0x5a, 0xff, 0x77, 0xff, 0x77, 0xff, 0x99, 0xff, 0x99, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0x09, 0x00, 0x09, 0x00, 0x25, 0x00, 0x25, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x57, 0x00, 0x57, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x53, 0x00, 0x53, 0x00, 0x42, 0x00, 0x42, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0xee, 0xff, 0xee, 0xff, 0xce, 0xff, 0xce, 0xff, 0xac, 0xff, 0xac, 0xff, 0x8c, 0xff, 0x8c, 0xff, 0x70, 0xff, 0x70, 0xff, 0x5a, 0xff, 0x5a, 0xff, 0x4c, 0xff, 0x4c, 0xff, 0x43, 0xff, 0x43, 0xff, 0x3d, 0xff, 0x3d, 0xff, 0x3a, 0xff, 0x3a, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x43, 0xff, 0x43, 0xff, 0x4f, 0xff, 0x4f, 0xff, 0x5d, 0xff, 0x5d, 0xff, 0x6f, 0xff, 0x6f, 0xff, 0x84, 0xff, 0x84, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0x23, 0x00, 0x23, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x72, 0x00, 0x72, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0xc1, 0x00, 0xc1, 0x00, 0xe6, 0x00, 0xe6, 0x00, 0x05, 0x01, 0x05, 0x01, 0x1b, 0x01, 0x1b, 0x01, 0x2a, 0x01, 0x2a, 0x01, 0x2f, 0x01, 0x2f, 0x01, 0x2c, 0x01, 0x2c, 0x01, 0x21, 0x01, 0x21, 0x01, 0x0f, 0x01, 0x0f, 0x01, 0xf6, 0x00, 0xf6, 0x00, 0xd7, 0x00, 0xd7, 0x00, 0xb2, 0x00, 0xb2, 0x00, 0x8a, 0x00, 0x8a, 0x00, 0x5e, 0x00, 0x5e, 0x00, 0x32, 0x00, 0x32, 0x00, 0x08, 0x00, 0x08, 0x00, 0xde, 0xff, 0xde, 0xff, 0xba, 0xff, 0xba, 0xff, 0x9b, 0xff, 0x9b, 0xff, 0x82, 0xff, 0x82, 0xff, 0x6f, 0xff, 0x6f, 0xff, 0x5e, 0xff, 0x5e, 0xff, 0x52, 0xff, 0x52, 0xff, 0x4a, 0xff, 0x4a, 0xff, 0x48, 0xff, 0x48, 0xff, 0x4b, 0xff, 0x4b, 0xff, 0x51, 0xff, 0x51, 0xff, 0x58, 0xff, 0x58, 0xff, 0x61, 0xff, 0x61, 0xff, 0x6f, 0xff, 0x6f, 0xff, 0x80, 0xff, 0x80, 0xff, 0x96, 0xff, 0x96, 0xff, 0xac, 0xff, 0xac, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0x18, 0x00, 0x18, 0x00, 0x37, 0x00, 0x37, 0x00, 0x54, 0x00, 0x54, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x81, 0x00, 0x81, 0x00, 0x92, 0x00, 0x92, 0x00, 0x9e, 0x00, 0x9e, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0x9f, 0x00, 0x9f, 0x00, 0x93, 0x00, 0x93, 0x00, 0x84, 0x00, 0x84, 0x00, 0x74, 0x00, 0x74, 0x00, 0x62, 0x00, 0x62, 0x00, 0x50, 0x00, 0x50, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x28, 0x00, 0x28, 0x00, 0x16, 0x00, 0x16, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xef, 0xff, 0xef, 0xff, 0xea, 0xff, 0xea, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xea, 0xff, 0xea, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0x01, 0x00, 0x01, 0x00, 0x09, 0x00, 0x09, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x12, 0x00, 0x12, 0x00, 0x13, 0x00, 0x13, 0x00, 0x10, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x03, 0x00, 0xfb, 0xff, 0xfb, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xab, 0xff, 0xab, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0x96, 0xff, 0x96, 0xff, 0x8a, 0xff, 0x8a, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x75, 0xff, 0x75, 0xff, 0x6e, 0xff, 0x6e, 0xff, 0x67, 0xff, 0x67, 0xff, 0x61, 0xff, 0x61, 0xff, 0x5e, 0xff, 0x5e, 0xff, 0x5d, 0xff, 0x5d, 0xff, 0x5f, 0xff, 0x5f, 0xff, 0x63, 0xff, 0x63, 0xff, 0x6b, 0xff, 0x6b, 0xff, 0x7a, 0xff, 0x7a, 0xff, 0x8f, 0xff, 0x8f, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0xc4, 0xff, 0xc4, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1c, 0x00, 0x1c, 0x00, 0x38, 0x00, 0x38, 0x00, 0x52, 0x00, 0x52, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x82, 0x00, 0x82, 0x00, 0x93, 0x00, 0x93, 0x00, 0x9f, 0x00, 0x9f, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0xb1, 0x00, 0xb1, 0x00, 0xb0, 0x00, 0xb0, 0x00, 0xad, 0x00, 0xad, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0x99, 0x00, 0x99, 0x00, 0x8b, 0x00, 0x8b, 0x00, 0x79, 0x00, 0x79, 0x00, 0x64, 0x00, 0x64, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0xef, 0xff, 0xef, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xae, 0xff, 0xae, 0xff, 0x90, 0xff, 0x90, 0xff, 0x73, 0xff, 0x73, 0xff, 0x59, 0xff, 0x59, 0xff, 0x45, 0xff, 0x45, 0xff, 0x3a, 0xff, 0x3a, 0xff, 0x39, 0xff, 0x39, 0xff, 0x41, 0xff, 0x41, 0xff, 0x52, 0xff, 0x52, 0xff, 0x68, 0xff, 0x68, 0xff, 0x85, 0xff, 0x85, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0xce, 0xff, 0xce, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0x24, 0x00, 0x24, 0x00, 0x53, 0x00, 0x53, 0x00, 0x82, 0x00, 0x82, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0xd6, 0x00, 0xd6, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x14, 0x01, 0x14, 0x01, 0x2a, 0x01, 0x2a, 0x01, 0x39, 0x01, 0x39, 0x01, 0x3e, 0x01, 0x3e, 0x01, 0x39, 0x01, 0x39, 0x01, 0x28, 0x01, 0x28, 0x01, 0x0e, 0x01, 0x0e, 0x01, 0xec, 0x00, 0xec, 0x00, 0xc4, 0x00, 0xc4, 0x00, 0x93, 0x00, 0x93, 0x00, 0x58, 0x00, 0x58, 0x00, 0x17, 0x00, 0x17, 0x00, 0xcf, 0xff, 0xcf, 0xff, 0x81, 0xff, 0x81, 0xff, 0x33, 0xff, 0x33, 0xff, 0xe9, 0xfe, 0xe9, 0xfe, 0xa1, 0xfe, 0xa1, 0xfe, 0x5b, 0xfe, 0x5b, 0xfe, 0x1a, 0xfe, 0x1a, 0xfe, 0xe2, 0xfd, 0xe2, 0xfd, 0xb5, 0xfd, 0xb5, 0xfd, 0x95, 0xfd, 0x95, 0xfd, 0x86, 0xfd, 0x86, 0xfd, 0x8a, 0xfd, 0x8a, 0xfd, 0xa0, 0xfd, 0xa0, 0xfd, 0xc7, 0xfd, 0xc7, 0xfd, 0xfe, 0xfd, 0xfe, 0xfd, 0x43, 0xfe, 0x43, 0xfe, 0x97, 0xfe, 0x97, 0xfe, 0xf7, 0xfe, 0xf7, 0xfe, 0x5e, 0xff, 0x5e, 0xff, 0xca, 0xff, 0xca, 0xff, 0x35, 0x00, 0x35, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0x00, 0x01, 0x00, 0x01, 0x5b, 0x01, 0x5b, 0x01, 0xab, 0x01, 0xab, 0x01, 0xf0, 0x01, 0xf0, 0x01, 0x29, 0x02, 0x29, 0x02, 0x56, 0x02, 0x56, 0x02, 0x76, 0x02, 0x76, 0x02, 0x8a, 0x02, 0x8a, 0x02, 0x92, 0x02, 0x92, 0x02, 0x8c, 0x02, 0x8c, 0x02, 0x7a, 0x02, 0x7a, 0x02, 0x5c, 0x02, 0x5c, 0x02, 0x2f, 0x02, 0x2f, 0x02, 0xf2, 0x01, 0xf2, 0x01, 0xa8, 0x01, 0xa8, 0x01, 0x52, 0x01, 0x52, 0x01, 0xf3, 0x00, 0xf3, 0x00, 0x8e, 0x00, 0x8e, 0x00, 0x24, 0x00, 0x24, 0x00, 0xb7, 0xff, 0xb7, 0xff, 0x4b, 0xff, 0x4b, 0xff, 0xe6, 0xfe, 0xe6, 0xfe, 0x8c, 0xfe, 0x8c, 0xfe, 0x42, 0xfe, 0x42, 0xfe, 0x0a, 0xfe, 0x0a, 0xfe, 0xe7, 0xfd, 0xe7, 0xfd, 0xda, 0xfd, 0xda, 0xfd, 0xdf, 0xfd, 0xdf, 0xfd, 0xf9, 0xfd, 0xf9, 0xfd, 0x26, 0xfe, 0x26, 0xfe, 0x63, 0xfe, 0x63, 0xfe, 0xad, 0xfe, 0xad, 0xfe, 0x02, 0xff, 0x02, 0xff, 0x5e, 0xff, 0x5e, 0xff, 0xba, 0xff, 0xba, 0xff, 0x11, 0x00, 0x11, 0x00, 0x64, 0x00, 0x64, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0xf1, 0x00, 0xf1, 0x00, 0x2b, 0x01, 0x2b, 0x01, 0x5c, 0x01, 0x5c, 0x01, 0x80, 0x01, 0x80, 0x01, 0x98, 0x01, 0x98, 0x01, 0xa2, 0x01, 0xa2, 0x01, 0x9e, 0x01, 0x9e, 0x01, 0x8b, 0x01, 0x8b, 0x01, 0x6b, 0x01, 0x6b, 0x01, 0x40, 0x01, 0x40, 0x01, 0x0b, 0x01, 0x0b, 0x01, 0xcd, 0x00, 0xcd, 0x00, 0x84, 0x00, 0x84, 0x00, 0x31, 0x00, 0x31, 0x00, 0xd9, 0xff, 0xd9, 0xff, 0x7e, 0xff, 0x7e, 0xff, 0x28, 0xff, 0x28, 0xff, 0xd6, 0xfe, 0xd6, 0xfe, 0x8b, 0xfe, 0x8b, 0xfe, 0x46, 0xfe, 0x46, 0xfe, 0x09, 0xfe, 0x09, 0xfe, 0xdb, 0xfd, 0xdb, 0xfd, 0xba, 0xfd, 0xba, 0xfd, 0xaa, 0xfd, 0xaa, 0xfd, 0xad, 0xfd, 0xad, 0xfd, 0xc3, 0xfd, 0xc3, 0xfd, 0xeb, 0xfd, 0xeb, 0xfd, 0x24, 0xfe, 0x24, 0xfe, 0x6d, 0xfe, 0x6d, 0xfe, 0xc4, 0xfe, 0xc4, 0xfe, 0x25, 0xff, 0x25, 0xff, 0x8e, 0xff, 0x8e, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0x6d, 0x00, 0x6d, 0x00, 0xda, 0x00, 0xda, 0x00, 0x3d, 0x01, 0x3d, 0x01, 0x97, 0x01, 0x97, 0x01, 0xe7, 0x01, 0xe7, 0x01, 0x2b, 0x02, 0x2b, 0x02, 0x60, 0x02, 0x60, 0x02, 0x83, 0x02, 0x83, 0x02, 0x95, 0x02, 0x95, 0x02, 0x94, 0x02, 0x94, 0x02, 0x81, 0x02, 0x81, 0x02, 0x5d, 0x02, 0x5d, 0x02, 0x2b, 0x02, 0x2b, 0x02, 0xec, 0x01, 0xec, 0x01, 0xa4, 0x01, 0xa4, 0x01, 0x55, 0x01, 0x55, 0x01, 0xff, 0x00, 0xff, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0x44, 0x00, 0x44, 0x00, 0xe7, 0xff, 0xe7, 0xff, 0x8b, 0xff, 0x8b, 0xff, 0x32, 0xff, 0x32, 0xff, 0xdf, 0xfe, 0xdf, 0xfe, 0x92, 0xfe, 0x92, 0xfe, 0x4e, 0xfe, 0x4e, 0xfe, 0x15, 0xfe, 0x15, 0xfe, 0xe6, 0xfd, 0xe6, 0xfd, 0xc4, 0xfd, 0xc4, 0xfd, 0xad, 0xfd, 0xad, 0xfd, 0xa3, 0xfd, 0xa3, 0xfd, 0xa9, 0xfd, 0xa9, 0xfd, 0xc0, 0xfd, 0xc0, 0xfd, 0xe8, 0xfd, 0xe8, 0xfd, 0x20, 0xfe, 0x20, 0xfe, 0x6a, 0xfe, 0x6a, 0xfe, 0xc4, 0xfe, 0xc4, 0xfe, 0x2a, 0xff, 0x2a, 0xff, 0x96, 0xff, 0x96, 0xff, 0x04, 0x00, 0x04, 0x00, 0x71, 0x00, 0x71, 0x00, 0xdb, 0x00, 0xdb, 0x00, 0x3d, 0x01, 0x3d, 0x01, 0x93, 0x01, 0x93, 0x01, 0xdd, 0x01, 0xdd, 0x01, 0x16, 0x02, 0x16, 0x02, 0x3c, 0x02, 0x3c, 0x02, 0x4f, 0x02, 0x4f, 0x02, 0x53, 0x02, 0x53, 0x02, 0x48, 0x02, 0x48, 0x02, 0x2e, 0x02, 0x2e, 0x02, 0x0a, 0x02, 0x0a, 0x02, 0xde, 0x01, 0xde, 0x01, 0xaa, 0x01, 0xaa, 0x01, 0x6f, 0x01, 0x6f, 0x01, 0x2e, 0x01, 0x2e, 0x01, 0xe9, 0x00, 0xe9, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x15, 0x00, 0x15, 0x00, 0xce, 0xff, 0xce, 0xff, 0x87, 0xff, 0x87, 0xff, 0x40, 0xff, 0x40, 0xff, 0xfa, 0xfe, 0xfa, 0xfe, 0xb7, 0xfe, 0xb7, 0xfe, 0x77, 0xfe, 0x77, 0xfe, 0x3d, 0xfe, 0x3d, 0xfe, 0x0a, 0xfe, 0x0a, 0xfe, 0xe1, 0xfd, 0xe1, 0xfd, 0xc3, 0xfd, 0xc3, 0xfd, 0xb5, 0xfd, 0xb5, 0xfd, 0xb6, 0xfd, 0xb6, 0xfd, 0xc5, 0xfd, 0xc5, 0xfd, 0xe4, 0xfd, 0xe4, 0xfd, 0x11, 0xfe, 0x11, 0xfe, 0x4e, 0xfe, 0x4e, 0xfe, 0x98, 0xfe, 0x98, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0x39, 0xff, 0x39, 0xff, 0x8e, 0xff, 0x8e, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0x32, 0x00, 0x32, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0xbd, 0x00, 0xbd, 0x00, 0xf6, 0x00, 0xf6, 0x00, 0x26, 0x01, 0x26, 0x01, 0x4f, 0x01, 0x4f, 0x01, 0x70, 0x01, 0x70, 0x01, 0x8b, 0x01, 0x8b, 0x01, 0x9f, 0x01, 0x9f, 0x01, 0xae, 0x01, 0xae, 0x01, 0xb9, 0x01, 0xb9, 0x01, 0xc2, 0x01, 0xc2, 0x01, 0xc6, 0x01, 0xc6, 0x01, 0xc4, 0x01, 0xc4, 0x01, 0xbc, 0x01, 0xbc, 0x01, 0xaa, 0x01, 0xaa, 0x01, 0x93, 0x01, 0x93, 0x01, 0x75, 0x01, 0x75, 0x01, 0x52, 0x01, 0x52, 0x01, 0x29, 0x01, 0x29, 0x01, 0xfa, 0x00, 0xfa, 0x00, 0xc6, 0x00, 0xc6, 0x00, 0x90, 0x00, 0x90, 0x00, 0x58, 0x00, 0x58, 0x00, 0x21, 0x00, 0x21, 0x00, 0xec, 0xff, 0xec, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0x88, 0xff, 0x88, 0xff, 0x5d, 0xff, 0x5d, 0xff, 0x3a, 0xff, 0x3a, 0xff, 0x1d, 0xff, 0x1d, 0xff, 0x04, 0xff, 0x04, 0xff, 0xf2, 0xfe, 0xf2, 0xfe, 0xe5, 0xfe, 0xe5, 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xdf, 0xfe, 0xdf, 0xfe, 0xe1, 0xfe, 0xe1, 0xfe, 0xe6, 0xfe, 0xe6, 0xfe, 0xec, 0xfe, 0xec, 0xfe, 0xf4, 0xfe, 0xf4, 0xfe, 0xfc, 0xfe, 0xfc, 0xfe, 0x06, 0xff, 0x06, 0xff, 0x10, 0xff, 0x10, 0xff, 0x19, 0xff, 0x19, 0xff, 0x24, 0xff, 0x24, 0xff, 0x32, 0xff, 0x32, 0xff, 0x42, 0xff, 0x42, 0xff, 0x53, 0xff, 0x53, 0xff, 0x65, 0xff, 0x65, 0xff, 0x7a, 0xff, 0x7a, 0xff, 0x92, 0xff, 0x92, 0xff, 0xaa, 0xff, 0xaa, 0xff, 0xc4, 0xff, 0xc4, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0x0f, 0x00, 0x0f, 0x00, 0x27, 0x00, 0x27, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x4d, 0x00, 0x4d, 0x00, 0x58, 0x00, 0x58, 0x00, 0x60, 0x00, 0x60, 0x00, 0x67, 0x00, 0x67, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x74, 0x00, 0x78, 0x00, 0x78, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x80, 0x00, 0x80, 0x00, 0x84, 0x00, 0x84, 0x00, 0x89, 0x00, 0x89, 0x00, 0x8f, 0x00, 0x8f, 0x00, 0x95, 0x00, 0x95, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9d, 0x00, 0x9d, 0x00, 0x9d, 0x00, 0x9d, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x95, 0x00, 0x95, 0x00, 0x8d, 0x00, 0x8d, 0x00, 0x82, 0x00, 0x82, 0x00, 0x72, 0x00, 0x72, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x47, 0x00, 0x47, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x15, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xff, 0xec, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0x95, 0xff, 0x95, 0xff, 0x84, 0xff, 0x84, 0xff, 0x75, 0xff, 0x75, 0xff, 0x6a, 0xff, 0x6a, 0xff, 0x64, 0xff, 0x64, 0xff, 0x60, 0xff, 0x60, 0xff, 0x5a, 0xff, 0x5a, 0xff, 0x54, 0xff, 0x54, 0xff, 0x50, 0xff, 0x50, 0xff, 0x4b, 0xff, 0x4b, 0xff, 0x46, 0xff, 0x46, 0xff, 0x43, 0xff, 0x43, 0xff, 0x43, 0xff, 0x43, 0xff, 0x49, 0xff, 0x49, 0xff, 0x53, 0xff, 0x53, 0xff, 0x60, 0xff, 0x60, 0xff, 0x71, 0xff, 0x71, 0xff, 0x89, 0xff, 0x89, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0x24, 0x00, 0x24, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x77, 0x00, 0x77, 0x00, 0x99, 0x00, 0x99, 0x00, 0xb7, 0x00, 0xb7, 0x00, 0xcd, 0x00, 0xcd, 0x00, 0xdd, 0x00, 0xdd, 0x00, 0xe7, 0x00, 0xe7, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0xff, 0x00, 0xff, 0x00, 0x05, 0x01, 0x05, 0x01, 0x09, 0x01, 0x09, 0x01, 0x0c, 0x01, 0x0c, 0x01, 0x0c, 0x01, 0x0c, 0x01, 0x09, 0x01, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0xf6, 0x00, 0xf6, 0x00, 0xe6, 0x00, 0xe6, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xb1, 0x00, 0xb1, 0x00, 0x89, 0x00, 0x89, 0x00, 0x59, 0x00, 0x59, 0x00, 0x21, 0x00, 0x21, 0x00, 0xe5, 0xff, 0xe5, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0x69, 0xff, 0x69, 0xff, 0x2c, 0xff, 0x2c, 0xff, 0xf3, 0xfe, 0xf3, 0xfe, 0xbd, 0xfe, 0xbd, 0xfe, 0x8e, 0xfe, 0x8e, 0xfe, 0x69, 0xfe, 0x69, 0xfe, 0x4d, 0xfe, 0x4d, 0xfe, 0x3f, 0xfe, 0x3f, 0xfe, 0x3c, 0xfe, 0x3c, 0xfe, 0x43, 0xfe, 0x43, 0xfe, 0x52, 0xfe, 0x52, 0xfe, 0x6a, 0xfe, 0x6a, 0xfe, 0x89, 0xfe, 0x89, 0xfe, 0xb1, 0xfe, 0xb1, 0xfe, 0xe2, 0xfe, 0xe2, 0xfe, 0x17, 0xff, 0x17, 0xff, 0x53, 0xff, 0x53, 0xff, 0x94, 0xff, 0x94, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0x1b, 0x00, 0x1b, 0x00, 0x60, 0x00, 0x60, 0x00, 0xa7, 0x00, 0xa7, 0x00, 0xee, 0x00, 0xee, 0x00, 0x31, 0x01, 0x31, 0x01, 0x70, 0x01, 0x70, 0x01, 0xac, 0x01, 0xac, 0x01, 0xe5, 0x01, 0xe5, 0x01, 0x17, 0x02, 0x17, 0x02, 0x3c, 0x02, 0x3c, 0x02, 0x53, 0x02, 0x53, 0x02, 0x5d, 0x02, 0x5d, 0x02, 0x57, 0x02, 0x57, 0x02, 0x41, 0x02, 0x41, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0xe9, 0x01, 0xe9, 0x01, 0xa8, 0x01, 0xa8, 0x01, 0x5b, 0x01, 0x5b, 0x01, 0x03, 0x01, 0x03, 0x01, 0xa4, 0x00, 0xa4, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0xd8, 0xff, 0xd8, 0xff, 0x71, 0xff, 0x71, 0xff, 0x0e, 0xff, 0x0e, 0xff, 0xb0, 0xfe, 0xb0, 0xfe, 0x5a, 0xfe, 0x5a, 0xfe, 0x0c, 0xfe, 0x0c, 0xfe, 0xcd, 0xfd, 0xcd, 0xfd, 0x9f, 0xfd, 0x9f, 0xfd, 0x7f, 0xfd, 0x7f, 0xfd, 0x71, 0xfd, 0x71, 0xfd, 0x73, 0xfd, 0x73, 0xfd, 0x82, 0xfd, 0x82, 0xfd, 0x9e, 0xfd, 0x9e, 0xfd, 0xc7, 0xfd, 0xc7, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0x42, 0xfe, 0x42, 0xfe, 0x8e, 0xfe, 0x8e, 0xfe, 0xe2, 0xfe, 0xe2, 0xfe, 0x3b, 0xff, 0x3b, 0xff, 0x98, 0xff, 0x98, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0x59, 0x00, 0x59, 0x00, 0xba, 0x00, 0xba, 0x00, 0x1a, 0x01, 0x1a, 0x01, 0x74, 0x01, 0x74, 0x01, 0xc6, 0x01, 0xc6, 0x01, 0x0d, 0x02, 0x0d, 0x02, 0x48, 0x02, 0x48, 0x02, 0x78, 0x02, 0x78, 0x02, 0x98, 0x02, 0x98, 0x02, 0xa9, 0x02, 0xa9, 0x02, 0xa9, 0x02, 0xa9, 0x02, 0x9b, 0x02, 0x9b, 0x02, 0x7d, 0x02, 0x7d, 0x02, 0x4f, 0x02, 0x4f, 0x02, 0x10, 0x02, 0x10, 0x02, 0xc3, 0x01, 0xc3, 0x01, 0x6d, 0x01, 0x6d, 0x01, 0x12, 0x01, 0x12, 0x01, 0xb2, 0x00, 0xb2, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0xe5, 0xff, 0xe5, 0xff, 0x84, 0xff, 0x84, 0xff, 0x2a, 0xff, 0x2a, 0xff, 0xd6, 0xfe, 0xd6, 0xfe, 0x8a, 0xfe, 0x8a, 0xfe, 0x49, 0xfe, 0x49, 0xfe, 0x15, 0xfe, 0x15, 0xfe, 0xef, 0xfd, 0xef, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xc9, 0xfd, 0xc9, 0xfd, 0xd4, 0xfd, 0xd4, 0xfd, 0xe6, 0xfd, 0xe6, 0xfd, 0x03, 0xfe, 0x03, 0xfe, 0x29, 0xfe, 0x29, 0xfe, 0x57, 0xfe, 0x57, 0xfe, 0x8d, 0xfe, 0x8d, 0xfe, 0xc8, 0xfe, 0xc8, 0xfe, 0x06, 0xff, 0x06, 0xff, 0x46, 0xff, 0x46, 0xff, 0x87, 0xff, 0x87, 0xff, 0xc8, 0xff, 0xc8, 0xff, 0x07, 0x00, 0x07, 0x00, 0x41, 0x00, 0x41, 0x00, 0x77, 0x00, 0x77, 0x00, 0xa7, 0x00, 0xa7, 0x00, 0xcf, 0x00, 0xcf, 0x00, 0xed, 0x00, 0xed, 0x00, 0x03, 0x01, 0x03, 0x01, 0x10, 0x01, 0x10, 0x01, 0x15, 0x01, 0x15, 0x01, 0x13, 0x01, 0x13, 0x01, 0x0a, 0x01, 0x0a, 0x01, 0xfb, 0x00, 0xfb, 0x00, 0xe6, 0x00, 0xe6, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xb0, 0x00, 0xb0, 0x00, 0x94, 0x00, 0x94, 0x00, 0x78, 0x00, 0x78, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x37, 0x00, 0x37, 0x00, 0x35, 0x00, 0x35, 0x00, 0x38, 0x00, 0x38, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x71, 0x00, 0x71, 0x00, 0x85, 0x00, 0x85, 0x00, 0x97, 0x00, 0x97, 0x00, 0xa7, 0x00, 0xa7, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xbf, 0x00, 0xbf, 0x00, 0xc9, 0x00, 0xc9, 0x00, 0xcf, 0x00, 0xcf, 0x00, 0xd2, 0x00, 0xd2, 0x00, 0xd1, 0x00, 0xd1, 0x00, 0xca, 0x00, 0xca, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0x99, 0x00, 0x99, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x58, 0x00, 0x58, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0xfb, 0xff, 0xfb, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0x86, 0xff, 0x86, 0xff, 0x47, 0xff, 0x47, 0xff, 0x06, 0xff, 0x06, 0xff, 0xc6, 0xfe, 0xc6, 0xfe, 0x88, 0xfe, 0x88, 0xfe, 0x51, 0xfe, 0x51, 0xfe, 0x23, 0xfe, 0x23, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xe5, 0xfd, 0xe5, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xd4, 0xfd, 0xd4, 0xfd, 0xdd, 0xfd, 0xdd, 0xfd, 0xf5, 0xfd, 0xf5, 0xfd, 0x18, 0xfe, 0x18, 0xfe, 0x46, 0xfe, 0x46, 0xfe, 0x7d, 0xfe, 0x7d, 0xfe, 0xba, 0xfe, 0xba, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x43, 0xff, 0x43, 0xff, 0x87, 0xff, 0x87, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0x0f, 0x00, 0x0f, 0x00, 0x51, 0x00, 0x51, 0x00, 0x90, 0x00, 0x90, 0x00, 0xc9, 0x00, 0xc9, 0x00, 0xfb, 0x00, 0xfb, 0x00, 0x26, 0x01, 0x26, 0x01, 0x4c, 0x01, 0x4c, 0x01, 0x6b, 0x01, 0x6b, 0x01, 0x83, 0x01, 0x83, 0x01, 0x91, 0x01, 0x91, 0x01, 0x95, 0x01, 0x95, 0x01, 0x90, 0x01, 0x90, 0x01, 0x84, 0x01, 0x84, 0x01, 0x6f, 0x01, 0x6f, 0x01, 0x52, 0x01, 0x52, 0x01, 0x2f, 0x01, 0x2f, 0x01, 0x08, 0x01, 0x08, 0x01, 0xde, 0x00, 0xde, 0x00, 0xb1, 0x00, 0xb1, 0x00, 0x81, 0x00, 0x81, 0x00, 0x54, 0x00, 0x54, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0xef, 0xff, 0xef, 0xff, 0xda, 0xff, 0xda, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xc4, 0xff, 0xc4, 0xff, 0xca, 0xff, 0xca, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0x0c, 0x00, 0x0c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x29, 0x00, 0x29, 0x00, 0x31, 0x00, 0x31, 0x00, 0x33, 0x00, 0x33, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x24, 0x00, 0x24, 0x00, 0x16, 0x00, 0x16, 0x00, 0x02, 0x00, 0x02, 0x00, 0xea, 0xff, 0xea, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xaa, 0xff, 0xaa, 0xff, 0x85, 0xff, 0x85, 0xff, 0x5f, 0xff, 0x5f, 0xff, 0x38, 0xff, 0x38, 0xff, 0x13, 0xff, 0x13, 0xff, 0xef, 0xfe, 0xef, 0xfe, 0xcc, 0xfe, 0xcc, 0xfe, 0xac, 0xfe, 0xac, 0xfe, 0x91, 0xfe, 0x91, 0xfe, 0x7a, 0xfe, 0x7a, 0xfe, 0x66, 0xfe, 0x66, 0xfe, 0x59, 0xfe, 0x59, 0xfe, 0x54, 0xfe, 0x54, 0xfe, 0x55, 0xfe, 0x55, 0xfe, 0x60, 0xfe, 0x60, 0xfe, 0x76, 0xfe, 0x76, 0xfe, 0x96, 0xfe, 0x96, 0xfe, 0xbe, 0xfe, 0xbe, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe, 0x2b, 0xff, 0x2b, 0xff, 0x70, 0xff, 0x70, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0x0a, 0x00, 0x0a, 0x00, 0x5e, 0x00, 0x5e, 0x00, 0xb3, 0x00, 0xb3, 0x00, 0x08, 0x01, 0x08, 0x01, 0x5a, 0x01, 0x5a, 0x01, 0xa7, 0x01, 0xa7, 0x01, 0xec, 0x01, 0xec, 0x01, 0x27, 0x02, 0x27, 0x02, 0x57, 0x02, 0x57, 0x02, 0x7e, 0x02, 0x7e, 0x02, 0x9a, 0x02, 0x9a, 0x02, 0xa8, 0x02, 0xa8, 0x02, 0xa8, 0x02, 0xa8, 0x02, 0x99, 0x02, 0x99, 0x02, 0x7c, 0x02, 0x7c, 0x02, 0x52, 0x02, 0x52, 0x02, 0x1a, 0x02, 0x1a, 0x02, 0xdb, 0x01, 0xdb, 0x01, 0x95, 0x01, 0x95, 0x01, 0x49, 0x01, 0x49, 0x01, 0xf8, 0x00, 0xf8, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0xf3, 0xff, 0xf3, 0xff, 0x9b, 0xff, 0x9b, 0xff, 0x47, 0xff, 0x47, 0xff, 0xf9, 0xfe, 0xf9, 0xfe, 0xb0, 0xfe, 0xb0, 0xfe, 0x6b, 0xfe, 0x6b, 0xfe, 0x2d, 0xfe, 0x2d, 0xfe, 0xf4, 0xfd, 0xf4, 0xfd, 0xc3, 0xfd, 0xc3, 0xfd, 0x9d, 0xfd, 0x9d, 0xfd, 0x86, 0xfd, 0x86, 0xfd, 0x7c, 0xfd, 0x7c, 0xfd, 0x7c, 0xfd, 0x7c, 0xfd, 0x89, 0xfd, 0x89, 0xfd, 0xa2, 0xfd, 0xa2, 0xfd, 0xc7, 0xfd, 0xc7, 0xfd, 0xf7, 0xfd, 0xf7, 0xfd, 0x30, 0xfe, 0x30, 0xfe, 0x72, 0xfe, 0x72, 0xfe, 0xb8, 0xfe, 0xb8, 0xfe, 0x00, 0xff, 0x00, 0xff, 0x4b, 0xff, 0x4b, 0xff, 0x96, 0xff, 0x96, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0x30, 0x00, 0x30, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0x12, 0x01, 0x12, 0x01, 0x50, 0x01, 0x50, 0x01, 0x86, 0x01, 0x86, 0x01, 0xb6, 0x01, 0xb6, 0x01, 0xe0, 0x01, 0xe0, 0x01, 0x02, 0x02, 0x02, 0x02, 0x1d, 0x02, 0x1d, 0x02, 0x2d, 0x02, 0x2d, 0x02, 0x34, 0x02, 0x34, 0x02, 0x2f, 0x02, 0x2f, 0x02, 0x21, 0x02, 0x21, 0x02, 0x0b, 0x02, 0x0b, 0x02, 0xec, 0x01, 0xec, 0x01, 0xc4, 0x01, 0xc4, 0x01, 0x98, 0x01, 0x98, 0x01, 0x67, 0x01, 0x67, 0x01, 0x30, 0x01, 0x30, 0x01, 0xf3, 0x00, 0xf3, 0x00, 0xb2, 0x00, 0xb2, 0x00, 0x70, 0x00, 0x70, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0xee, 0xff, 0xee, 0xff, 0xac, 0xff, 0xac, 0xff, 0x6a, 0xff, 0x6a, 0xff, 0x28, 0xff, 0x28, 0xff, 0xe8, 0xfe, 0xe8, 0xfe, 0xad, 0xfe, 0xad, 0xfe, 0x77, 0xfe, 0x77, 0xfe, 0x46, 0xfe, 0x46, 0xfe, 0x1b, 0xfe, 0x1b, 0xfe, 0xf9, 0xfd, 0xf9, 0xfd, 0xde, 0xfd, 0xde, 0xfd, 0xca, 0xfd, 0xca, 0xfd, 0xc2, 0xfd, 0xc2, 0xfd, 0xc5, 0xfd, 0xc5, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xf3, 0xfd, 0xf3, 0xfd, 0x19, 0xfe, 0x19, 0xfe, 0x48, 0xfe, 0x48, 0xfe, 0x81, 0xfe, 0x81, 0xfe, 0xc4, 0xfe, 0xc4, 0xfe, 0x10, 0xff, 0x10, 0xff, 0x65, 0xff, 0x65, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0x1b, 0x00, 0x1b, 0x00, 0x78, 0x00, 0x78, 0x00, 0xd2, 0x00, 0xd2, 0x00, 0x27, 0x01, 0x27, 0x01, 0x78, 0x01, 0x78, 0x01, 0xc2, 0x01, 0xc2, 0x01, 0x04, 0x02, 0x04, 0x02, 0x3d, 0x02, 0x3d, 0x02, 0x6a, 0x02, 0x6a, 0x02, 0x8c, 0x02, 0x8c, 0x02, 0xa4, 0x02, 0xa4, 0x02, 0xb3, 0x02, 0xb3, 0x02, 0xb9, 0x02, 0xb9, 0x02, 0xb5, 0x02, 0xb5, 0x02, 0xa5, 0x02, 0xa5, 0x02, 0x88, 0x02, 0x88, 0x02, 0x61, 0x02, 0x61, 0x02, 0x2e, 0x02, 0x2e, 0x02, 0xf0, 0x01, 0xf0, 0x01, 0xa7, 0x01, 0xa7, 0x01, 0x55, 0x01, 0x55, 0x01, 0xfc, 0x00, 0xfc, 0x00, 0x9d, 0x00, 0x9d, 0x00, 0x35, 0x00, 0x35, 0x00, 0xc9, 0xff, 0xc9, 0xff, 0x5d, 0xff, 0x5d, 0xff, 0xf1, 0xfe, 0xf1, 0xfe, 0x89, 0xfe, 0x89, 0xfe, 0x28, 0xfe, 0x28, 0xfe, 0xd1, 0xfd, 0xd1, 0xfd, 0x89, 0xfd, 0x89, 0xfd, 0x4f, 0xfd, 0x4f, 0xfd, 0x24, 0xfd, 0x24, 0xfd, 0x08, 0xfd, 0x08, 0xfd, 0xfb, 0xfc, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0x0b, 0xfd, 0x0b, 0xfd, 0x29, 0xfd, 0x29, 0xfd, 0x53, 0xfd, 0x53, 0xfd, 0x89, 0xfd, 0x89, 0xfd, 0xc9, 0xfd, 0xc9, 0xfd, 0x10, 0xfe, 0x10, 0xfe, 0x5c, 0xfe, 0x5c, 0xfe, 0xae, 0xfe, 0xae, 0xfe, 0x01, 0xff, 0x01, 0xff, 0x55, 0xff, 0x55, 0xff, 0xad, 0xff, 0xad, 0xff, 0x07, 0x00, 0x07, 0x00, 0x60, 0x00, 0x60, 0x00, 0xb7, 0x00, 0xb7, 0x00, 0x0b, 0x01, 0x0b, 0x01, 0x5b, 0x01, 0x5b, 0x01, 0xa5, 0x01, 0xa5, 0x01, 0xe6, 0x01, 0xe6, 0x01, 0x1f, 0x02, 0x1f, 0x02, 0x4d, 0x02, 0x4d, 0x02, 0x6f, 0x02, 0x6f, 0x02, 0x85, 0x02, 0x85, 0x02, 0x8e, 0x02, 0x8e, 0x02, 0x89, 0x02, 0x89, 0x02, 0x76, 0x02, 0x76, 0x02, 0x55, 0x02, 0x55, 0x02, 0x28, 0x02, 0x28, 0x02, 0xf2, 0x01, 0xf2, 0x01, 0xb1, 0x01, 0xb1, 0x01, 0x68, 0x01, 0x68, 0x01, 0x1b, 0x01, 0x1b, 0x01, 0xcd, 0x00, 0xcd, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0xe5, 0xff, 0xe5, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0x5f, 0xff, 0x5f, 0xff, 0x28, 0xff, 0x28, 0xff, 0xf7, 0xfe, 0xf7, 0xfe, 0xce, 0xfe, 0xce, 0xfe, 0xab, 0xfe, 0xab, 0xfe, 0x90, 0xfe, 0x90, 0xfe, 0x7e, 0xfe, 0x7e, 0xfe, 0x73, 0xfe, 0x73, 0xfe, 0x6f, 0xfe, 0x6f, 0xfe, 0x71, 0xfe, 0x71, 0xfe, 0x7b, 0xfe, 0x7b, 0xfe, 0x8b, 0xfe, 0x8b, 0xfe, 0xa0, 0xfe, 0xa0, 0xfe, 0xbe, 0xfe, 0xbe, 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0x06, 0xff, 0x06, 0xff, 0x2e, 0xff, 0x2e, 0xff, 0x5b, 0xff, 0x5b, 0xff, 0x8a, 0xff, 0x8a, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xec, 0xff, 0xec, 0xff, 0x1c, 0x00, 0x1c, 0x00, 0x4d, 0x00, 0x4d, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0xa8, 0x00, 0xa8, 0x00, 0xcf, 0x00, 0xcf, 0x00, 0xed, 0x00, 0xed, 0x00, 0x00, 0x01, 0x00, 0x01, 0x08, 0x01, 0x08, 0x01, 0x06, 0x01, 0x06, 0x01, 0xfa, 0x00, 0xfa, 0x00, 0xe5, 0x00, 0xe5, 0x00, 0xc9, 0x00, 0xc9, 0x00, 0xa7, 0x00, 0xa7, 0x00, 0x81, 0x00, 0x81, 0x00, 0x59, 0x00, 0x59, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x05, 0x00, 0x05, 0x00, 0xdf, 0xff, 0xdf, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0x9f, 0xff, 0x9f, 0xff, 0x87, 0xff, 0x87, 0xff, 0x76, 0xff, 0x76, 0xff, 0x68, 0xff, 0x68, 0xff, 0x5d, 0xff, 0x5d, 0xff, 0x53, 0xff, 0x53, 0xff, 0x4e, 0xff, 0x4e, 0xff, 0x50, 0xff, 0x50, 0xff, 0x56, 0xff, 0x56, 0xff, 0x60, 0xff, 0x60, 0xff, 0x6d, 0xff, 0x6d, 0xff, 0x7e, 0xff, 0x7e, 0xff, 0x95, 0xff, 0x95, 0xff, 0xb1, 0xff, 0xb1, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0x1e, 0x00, 0x1e, 0x00, 0x49, 0x00, 0x49, 0x00, 0x76, 0x00, 0x76, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0xc8, 0x00, 0xc8, 0x00, 0xe9, 0x00, 0xe9, 0x00, 0x00, 0x01, 0x00, 0x01, 0x0e, 0x01, 0x0e, 0x01, 0x11, 0x01, 0x11, 0x01, 0x07, 0x01, 0x07, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xce, 0x00, 0xce, 0x00, 0xa7, 0x00, 0xa7, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x17, 0x00, 0x17, 0x00, 0xe1, 0xff, 0xe1, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0x84, 0xff, 0x84, 0xff, 0x5e, 0xff, 0x5e, 0xff, 0x40, 0xff, 0x40, 0xff, 0x2a, 0xff, 0x2a, 0xff, 0x18, 0xff, 0x18, 0xff, 0x0b, 0xff, 0x0b, 0xff, 0x03, 0xff, 0x03, 0xff, 0x02, 0xff, 0x02, 0xff, 0x07, 0xff, 0x07, 0xff, 0x10, 0xff, 0x10, 0xff, 0x20, 0xff, 0x20, 0xff, 0x36, 0xff, 0x36, 0xff, 0x4f, 0xff, 0x4f, 0xff, 0x6e, 0xff, 0x6e, 0xff, 0x8f, 0xff, 0x8f, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0x16, 0x00, 0x16, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0xd4, 0x00, 0xd4, 0x00, 0xfa, 0x00, 0xfa, 0x00, 0x17, 0x01, 0x17, 0x01, 0x2d, 0x01, 0x2d, 0x01, 0x38, 0x01, 0x38, 0x01, 0x38, 0x01, 0x38, 0x01, 0x2c, 0x01, 0x2c, 0x01, 0x12, 0x01, 0x12, 0x01, 0xef, 0x00, 0xef, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0x8a, 0x00, 0x8a, 0x00, 0x51, 0x00, 0x51, 0x00, 0x18, 0x00, 0x18, 0x00, 0xe1, 0xff, 0xe1, 0xff, 0xad, 0xff, 0xad, 0xff, 0x7e, 0xff, 0x7e, 0xff, 0x55, 0xff, 0x55, 0xff, 0x34, 0xff, 0x34, 0xff, 0x1b, 0xff, 0x1b, 0xff, 0x0d, 0xff, 0x0d, 0xff, 0x09, 0xff, 0x09, 0xff, 0x0a, 0xff, 0x0a, 0xff, 0x11, 0xff, 0x11, 0xff, 0x1d, 0xff, 0x1d, 0xff, 0x30, 0xff, 0x30, 0xff, 0x49, 0xff, 0x49, 0xff, 0x65, 0xff, 0x65, 0xff, 0x85, 0xff, 0x85, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0x28, 0x00, 0x28, 0x00, 0x58, 0x00, 0x58, 0x00, 0x89, 0x00, 0x89, 0x00, 0xba, 0x00, 0xba, 0x00, 0xe7, 0x00, 0xe7, 0x00, 0x11, 0x01, 0x11, 0x01, 0x35, 0x01, 0x35, 0x01, 0x50, 0x01, 0x50, 0x01, 0x61, 0x01, 0x61, 0x01, 0x66, 0x01, 0x66, 0x01, 0x60, 0x01, 0x60, 0x01, 0x4a, 0x01, 0x4a, 0x01, 0x27, 0x01, 0x27, 0x01, 0xf9, 0x00, 0xf9, 0x00, 0xc2, 0x00, 0xc2, 0x00, 0x85, 0x00, 0x85, 0x00, 0x44, 0x00, 0x44, 0x00, 0x03, 0x00, 0x03, 0x00, 0xc3, 0xff, 0xc3, 0xff, 0x86, 0xff, 0x86, 0xff, 0x4f, 0xff, 0x4f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0xf5, 0xfe, 0xf5, 0xfe, 0xcf, 0xfe, 0xcf, 0xfe, 0xb0, 0xfe, 0xb0, 0xfe, 0x97, 0xfe, 0x97, 0xfe, 0x86, 0xfe, 0x86, 0xfe, 0x7c, 0xfe, 0x7c, 0xfe, 0x79, 0xfe, 0x79, 0xfe, 0x7d, 0xfe, 0x7d, 0xfe, 0x87, 0xfe, 0x87, 0xfe, 0x97, 0xfe, 0x97, 0xfe, 0xaf, 0xfe, 0xaf, 0xfe, 0xcf, 0xfe, 0xcf, 0xfe, 0xf6, 0xfe, 0xf6, 0xfe, 0x24, 0xff, 0x24, 0xff, 0x58, 0xff, 0x58, 0xff, 0x92, 0xff, 0x92, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0x0d, 0x00, 0x0d, 0x00, 0x48, 0x00, 0x48, 0x00, 0x82, 0x00, 0x82, 0x00, 0xb7, 0x00, 0xb7, 0x00, 0xe7, 0x00, 0xe7, 0x00, 0x11, 0x01, 0x11, 0x01, 0x31, 0x01, 0x31, 0x01, 0x4b, 0x01, 0x4b, 0x01, 0x5c, 0x01, 0x5c, 0x01, 0x64, 0x01, 0x64, 0x01, 0x65, 0x01, 0x65, 0x01, 0x60, 0x01, 0x60, 0x01, 0x57, 0x01, 0x57, 0x01, 0x45, 0x01, 0x45, 0x01, 0x2b, 0x01, 0x2b, 0x01, 0x0a, 0x01, 0x0a, 0x01, 0xe6, 0x00, 0xe6, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0x98, 0x00, 0x98, 0x00, 0x71, 0x00, 0x71, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x25, 0x00, 0x25, 0x00, 0x02, 0x00, 0x02, 0x00, 0xe2, 0xff, 0xe2, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xac, 0xff, 0xac, 0xff, 0x98, 0xff, 0x98, 0xff, 0x88, 0xff, 0x88, 0xff, 0x7c, 0xff, 0x7c, 0xff, 0x71, 0xff, 0x71, 0xff, 0x6a, 0xff, 0x6a, 0xff, 0x68, 0xff, 0x68, 0xff, 0x6b, 0xff, 0x6b, 0xff, 0x72, 0xff, 0x72, 0xff, 0x79, 0xff, 0x79, 0xff, 0x81, 0xff, 0x81, 0xff, 0x89, 0xff, 0x89, 0xff, 0x91, 0xff, 0x91, 0xff, 0x9b, 0xff, 0x9b, 0xff, 0xa2, 0xff, 0xa2, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0xad, 0xff, 0xad, 0xff, 0xae, 0xff, 0xae, 0xff, 0xac, 0xff, 0xac, 0xff, 0xa6, 0xff, 0xa6, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0x9a, 0xff, 0x9a, 0xff, 0x93, 0xff, 0x93, 0xff, 0x8d, 0xff, 0x8d, 0xff, 0x89, 0xff, 0x89, 0xff, 0x88, 0xff, 0x88, 0xff, 0x87, 0xff, 0x87, 0xff, 0x89, 0xff, 0x89, 0xff, 0x90, 0xff, 0x90, 0xff, 0x9a, 0xff, 0x9a, 0xff, 0xa5, 0xff, 0xa5, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0x10, 0x00, 0x10, 0x00, 0x28, 0x00, 0x28, 0x00, 0x42, 0x00, 0x42, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xde, 0x00, 0xde, 0x00, 0x00, 0x01, 0x00, 0x01, 0x1e, 0x01, 0x1e, 0x01, 0x36, 0x01, 0x36, 0x01, 0x48, 0x01, 0x48, 0x01, 0x54, 0x01, 0x54, 0x01, 0x59, 0x01, 0x59, 0x01, 0x54, 0x01, 0x54, 0x01, 0x45, 0x01, 0x45, 0x01, 0x2d, 0x01, 0x2d, 0x01, 0x0c, 0x01, 0x0c, 0x01, 0xe4, 0x00, 0xe4, 0x00, 0xb5, 0x00, 0xb5, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0x44, 0x00, 0x44, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0xd3, 0xff, 0xd3, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0x6c, 0xff, 0x6c, 0xff, 0x3d, 0xff, 0x3d, 0xff, 0x12, 0xff, 0x12, 0xff, 0xee, 0xfe, 0xee, 0xfe, 0xce, 0xfe, 0xce, 0xfe, 0xb2, 0xfe, 0xb2, 0xfe, 0x99, 0xfe, 0x99, 0xfe, 0x86, 0xfe, 0x86, 0xfe, 0x7a, 0xfe, 0x7a, 0xfe, 0x72, 0xfe, 0x72, 0xfe, 0x71, 0xfe, 0x71, 0xfe, 0x7a, 0xfe, 0x7a, 0xfe, 0x8c, 0xfe, 0x8c, 0xfe, 0xa6, 0xfe, 0xa6, 0xfe, 0xc9, 0xfe, 0xc9, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe, 0x1e, 0xff, 0x1e, 0xff, 0x54, 0xff, 0x54, 0xff, 0x91, 0xff, 0x91, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0x19, 0x00, 0x19, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x9d, 0x00, 0x9d, 0x00, 0xd9, 0x00, 0xd9, 0x00, 0x10, 0x01, 0x10, 0x01, 0x3d, 0x01, 0x3d, 0x01, 0x62, 0x01, 0x62, 0x01, 0x7b, 0x01, 0x7b, 0x01, 0x89, 0x01, 0x89, 0x01, 0x8d, 0x01, 0x8d, 0x01, 0x88, 0x01, 0x88, 0x01, 0x7f, 0x01, 0x7f, 0x01, 0x70, 0x01, 0x70, 0x01, 0x5a, 0x01, 0x5a, 0x01, 0x3f, 0x01, 0x3f, 0x01, 0x1e, 0x01, 0x1e, 0x01, 0xfa, 0x00, 0xfa, 0x00, 0xd3, 0x00, 0xd3, 0x00, 0xab, 0x00, 0xab, 0x00, 0x81, 0x00, 0x81, 0x00, 0x54, 0x00, 0x54, 0x00, 0x23, 0x00, 0x23, 0x00, 0xf0, 0xff, 0xf0, 0xff, 0xba, 0xff, 0xba, 0xff, 0x83, 0xff, 0x83, 0xff, 0x50, 0xff, 0x50, 0xff, 0x23, 0xff, 0x23, 0xff, 0xfd, 0xfe, 0xfd, 0xfe, 0xda, 0xfe, 0xda, 0xfe, 0xbd, 0xfe, 0xbd, 0xfe, 0xa7, 0xfe, 0xa7, 0xfe, 0x97, 0xfe, 0x97, 0xfe, 0x8f, 0xfe, 0x8f, 0xfe, 0x8e, 0xfe, 0x8e, 0xfe, 0x95, 0xfe, 0x95, 0xfe, 0xa3, 0xfe, 0xa3, 0xfe, 0xb8, 0xfe, 0xb8, 0xfe, 0xd3, 0xfe, 0xd3, 0xfe, 0xf3, 0xfe, 0xf3, 0xfe, 0x18, 0xff, 0x18, 0xff, 0x40, 0xff, 0x40, 0xff, 0x69, 0xff, 0x69, 0xff, 0x92, 0xff, 0x92, 0xff, 0xba, 0xff, 0xba, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0x0a, 0x00, 0x0a, 0x00, 0x33, 0x00, 0x33, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x82, 0x00, 0x82, 0x00, 0xa8, 0x00, 0xa8, 0x00, 0xcd, 0x00, 0xcd, 0x00, 0xec, 0x00, 0xec, 0x00, 0x07, 0x01, 0x07, 0x01, 0x1d, 0x01, 0x1d, 0x01, 0x30, 0x01, 0x30, 0x01, 0x3f, 0x01, 0x3f, 0x01, 0x47, 0x01, 0x47, 0x01, 0x4b, 0x01, 0x4b, 0x01, 0x47, 0x01, 0x47, 0x01, 0x38, 0x01, 0x38, 0x01, 0x20, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0xe0, 0x00, 0xe0, 0x00, 0xba, 0x00, 0xba, 0x00, 0x8f, 0x00, 0x8f, 0x00, 0x60, 0x00, 0x60, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0xfc, 0xff, 0xfc, 0xff, 0xca, 0xff, 0xca, 0xff, 0x99, 0xff, 0x99, 0xff, 0x6c, 0xff, 0x6c, 0xff, 0x42, 0xff, 0x42, 0xff, 0x1c, 0xff, 0x1c, 0xff, 0xfb, 0xfe, 0xfb, 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xcd, 0xfe, 0xcd, 0xfe, 0xc2, 0xfe, 0xc2, 0xfe, 0xbe, 0xfe, 0xbe, 0xfe, 0xc2, 0xfe, 0xc2, 0xfe, 0xcf, 0xfe, 0xcf, 0xfe, 0xe3, 0xfe, 0xe3, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0x21, 0xff, 0x21, 0xff, 0x48, 0xff, 0x48, 0xff, 0x73, 0xff, 0x73, 0xff, 0xa3, 0xff, 0xa3, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0x09, 0x00, 0x09, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xcf, 0x00, 0xcf, 0x00, 0xfb, 0x00, 0xfb, 0x00, 0x21, 0x01, 0x21, 0x01, 0x41, 0x01, 0x41, 0x01, 0x5a, 0x01, 0x5a, 0x01, 0x6b, 0x01, 0x6b, 0x01, 0x74, 0x01, 0x74, 0x01, 0x75, 0x01, 0x75, 0x01, 0x6c, 0x01, 0x6c, 0x01, 0x57, 0x01, 0x57, 0x01, 0x36, 0x01, 0x36, 0x01, 0x0c, 0x01, 0x0c, 0x01, 0xda, 0x00, 0xda, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0x60, 0x00, 0x60, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0xda, 0xff, 0xda, 0xff, 0x92, 0xff, 0x92, 0xff, 0x4a, 0xff, 0x4a, 0xff, 0x06, 0xff, 0x06, 0xff, 0xcc, 0xfe, 0xcc, 0xfe, 0x97, 0xfe, 0x97, 0xfe, 0x6b, 0xfe, 0x6b, 0xfe, 0x49, 0xfe, 0x49, 0xfe, 0x33, 0xfe, 0x33, 0xfe, 0x2a, 0xfe, 0x2a, 0xfe, 0x2b, 0xfe, 0x2b, 0xfe, 0x39, 0xfe, 0x39, 0xfe, 0x54, 0xfe, 0x54, 0xfe, 0x7e, 0xfe, 0x7e, 0xfe, 0xb2, 0xfe, 0xb2, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe, 0x34, 0xff, 0x34, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0x1c, 0x00, 0x1c, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0xba, 0x00, 0xba, 0x00, 0x03, 0x01, 0x03, 0x01, 0x45, 0x01, 0x45, 0x01, 0x80, 0x01, 0x80, 0x01, 0xb4, 0x01, 0xb4, 0x01, 0xdd, 0x01, 0xdd, 0x01, 0xfb, 0x01, 0xfb, 0x01, 0x0c, 0x02, 0x0c, 0x02, 0x10, 0x02, 0x10, 0x02, 0x07, 0x02, 0x07, 0x02, 0xf2, 0x01, 0xf2, 0x01, 0xd1, 0x01, 0xd1, 0x01, 0xa4, 0x01, 0xa4, 0x01, 0x6e, 0x01, 0x6e, 0x01, 0x2d, 0x01, 0x2d, 0x01, 0xe4, 0x00, 0xe4, 0x00, 0x94, 0x00, 0x94, 0x00, 0x40, 0x00, 0x40, 0x00, 0xeb, 0xff, 0xeb, 0xff, 0x96, 0xff, 0x96, 0xff, 0x44, 0xff, 0x44, 0xff, 0xf6, 0xfe, 0xf6, 0xfe, 0xac, 0xfe, 0xac, 0xfe, 0x6a, 0xfe, 0x6a, 0xfe, 0x33, 0xfe, 0x33, 0xfe, 0x09, 0xfe, 0x09, 0xfe, 0xeb, 0xfd, 0xeb, 0xfd, 0xda, 0xfd, 0xda, 0xfd, 0xd6, 0xfd, 0xd6, 0xfd, 0xe0, 0xfd, 0xe0, 0xfd, 0xf6, 0xfd, 0xf6, 0xfd, 0x1b, 0xfe, 0x1b, 0xfe, 0x4e, 0xfe, 0x4e, 0xfe, 0x8b, 0xfe, 0x8b, 0xfe, 0xd0, 0xfe, 0xd0, 0xfe, 0x17, 0xff, 0x17, 0xff, 0x62, 0xff, 0x62, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4a, 0x00, 0x4a, 0x00, 0x91, 0x00, 0x91, 0x00, 0xd3, 0x00, 0xd3, 0x00, 0x0c, 0x01, 0x0c, 0x01, 0x3c, 0x01, 0x3c, 0x01, 0x61, 0x01, 0x61, 0x01, 0x7f, 0x01, 0x7f, 0x01, 0x94, 0x01, 0x94, 0x01, 0x9e, 0x01, 0x9e, 0x01, 0xa2, 0x01, 0xa2, 0x01, 0x9f, 0x01, 0x9f, 0x01, 0x92, 0x01, 0x92, 0x01, 0x7a, 0x01, 0x7a, 0x01, 0x59, 0x01, 0x59, 0x01, 0x31, 0x01, 0x31, 0x01, 0x05, 0x01, 0x05, 0x01, 0xd4, 0x00, 0xd4, 0x00, 0xa1, 0x00, 0xa1, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x39, 0x00, 0x39, 0x00, 0x05, 0x00, 0x05, 0x00, 0xd3, 0xff, 0xd3, 0xff, 0xa6, 0xff, 0xa6, 0xff, 0x80, 0xff, 0x80, 0xff, 0x5e, 0xff, 0x5e, 0xff, 0x43, 0xff, 0x43, 0xff, 0x32, 0xff, 0x32, 0xff, 0x29, 0xff, 0x29, 0xff, 0x2a, 0xff, 0x2a, 0xff, 0x31, 0xff, 0x31, 0xff, 0x41, 0xff, 0x41, 0xff, 0x56, 0xff, 0x56, 0xff, 0x71, 0xff, 0x71, 0xff, 0x91, 0xff, 0x91, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0x16, 0x00, 0x16, 0x00, 0x34, 0x00, 0x34, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x62, 0x00, 0x62, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x74, 0x00, 0x73, 0x00, 0x73, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x65, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x51, 0x00, 0x51, 0x00, 0x40, 0x00, 0x40, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x16, 0x00, 0x16, 0x00, 0xfe, 0xff, 0xfe, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0x92, 0xff, 0x92, 0xff, 0x74, 0xff, 0x74, 0xff, 0x57, 0xff, 0x57, 0xff, 0x40, 0xff, 0x40, 0xff, 0x2e, 0xff, 0x2e, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x14, 0xff, 0x14, 0xff, 0x10, 0xff, 0x10, 0xff, 0x15, 0xff, 0x15, 0xff, 0x22, 0xff, 0x22, 0xff, 0x37, 0xff, 0x37, 0xff, 0x53, 0xff, 0x53, 0xff, 0x74, 0xff, 0x74, 0xff, 0x98, 0xff, 0x98, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0x15, 0x00, 0x15, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x64, 0x00, 0x64, 0x00, 0x8a, 0x00, 0x8a, 0x00, 0xb2, 0x00, 0xb2, 0x00, 0xdb, 0x00, 0xdb, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x19, 0x01, 0x19, 0x01, 0x2e, 0x01, 0x2e, 0x01, 0x3c, 0x01, 0x3c, 0x01, 0x47, 0x01, 0x47, 0x01, 0x4e, 0x01, 0x4e, 0x01, 0x4f, 0x01, 0x4f, 0x01, 0x4b, 0x01, 0x4b, 0x01, 0x40, 0x01, 0x40, 0x01, 0x2e, 0x01, 0x2e, 0x01, 0x16, 0x01, 0x16, 0x01, 0xf8, 0x00, 0xf8, 0x00, 0xd5, 0x00, 0xd5, 0x00, 0xad, 0x00, 0xad, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x14, 0x00, 0x14, 0x00, 0xdf, 0xff, 0xdf, 0xff, 0xab, 0xff, 0xab, 0xff, 0x7b, 0xff, 0x7b, 0xff, 0x4c, 0xff, 0x4c, 0xff, 0x21, 0xff, 0x21, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xc7, 0xfe, 0xc7, 0xfe, 0xb2, 0xfe, 0xb2, 0xfe, 0xa4, 0xfe, 0xa4, 0xfe, 0x9f, 0xfe, 0x9f, 0xfe, 0xa4, 0xfe, 0xa4, 0xfe, 0xb0, 0xfe, 0xb0, 0xfe, 0xc0, 0xfe, 0xc0, 0xfe, 0xd3, 0xfe, 0xd3, 0xfe, 0xe8, 0xfe, 0xe8, 0xfe, 0x02, 0xff, 0x02, 0xff, 0x22, 0xff, 0x22, 0xff, 0x43, 0xff, 0x43, 0xff, 0x66, 0xff, 0x66, 0xff, 0x88, 0xff, 0x88, 0xff, 0xab, 0xff, 0xab, 0xff, 0xce, 0xff, 0xce, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0x14, 0x00, 0x14, 0x00, 0x36, 0x00, 0x36, 0x00, 0x53, 0x00, 0x53, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x87, 0x00, 0x87, 0x00, 0x9f, 0x00, 0x9f, 0x00, 0xb3, 0x00, 0xb3, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xbd, 0x00, 0xbd, 0x00, 0xb3, 0x00, 0xb3, 0x00, 0xa5, 0x00, 0xa5, 0x00, 0x92, 0x00, 0x92, 0x00, 0x7f, 0x00, 0x7f, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x57, 0x00, 0x57, 0x00, 0x44, 0x00, 0x44, 0x00, 0x34, 0x00, 0x34, 0x00, 0x28, 0x00, 0x28, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x18, 0x00, 0x18, 0x00, 0x15, 0x00, 0x15, 0x00, 0x16, 0x00, 0x16, 0x00, 0x19, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x19, 0x00, 0x19, 0x00, 0x17, 0x00, 0x17, 0x00, 0x11, 0x00, 0x11, 0x00, 0x09, 0x00, 0x09, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xad, 0xff, 0xad, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0xae, 0xff, 0xae, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0xae, 0xff, 0xae, 0xff, 0xae, 0xff, 0xae, 0xff, 0xad, 0xff, 0xad, 0xff, 0xab, 0xff, 0xab, 0xff, 0xaa, 0xff, 0xaa, 0xff, 0xac, 0xff, 0xac, 0xff, 0xb7, 0xff, 0xb7, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xee, 0xff, 0xee, 0xff, 0x05, 0x00, 0x05, 0x00, 0x20, 0x00, 0x20, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x77, 0x00, 0x77, 0x00, 0x90, 0x00, 0x90, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0xb7, 0x00, 0xb7, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0x8d, 0x00, 0x8d, 0x00, 0x74, 0x00, 0x74, 0x00, 0x57, 0x00, 0x57, 0x00, 0x35, 0x00, 0x35, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xe6, 0xff, 0xe6, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0x9f, 0xff, 0x9f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x62, 0xff, 0x62, 0xff, 0x4b, 0xff, 0x4b, 0xff, 0x35, 0xff, 0x35, 0xff, 0x23, 0xff, 0x23, 0xff, 0x14, 0xff, 0x14, 0xff, 0x07, 0xff, 0x07, 0xff, 0xfc, 0xfe, 0xfc, 0xfe, 0xf3, 0xfe, 0xf3, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xf5, 0xfe, 0xf5, 0xfe, 0x03, 0xff, 0x03, 0xff, 0x17, 0xff, 0x17, 0xff, 0x33, 0xff, 0x33, 0xff, 0x54, 0xff, 0x54, 0xff, 0x7e, 0xff, 0x7e, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0x23, 0x00, 0x23, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x92, 0x00, 0x92, 0x00, 0xc4, 0x00, 0xc4, 0x00, 0xf2, 0x00, 0xf2, 0x00, 0x1b, 0x01, 0x1b, 0x01, 0x39, 0x01, 0x39, 0x01, 0x4c, 0x01, 0x4c, 0x01, 0x56, 0x01, 0x56, 0x01, 0x58, 0x01, 0x58, 0x01, 0x55, 0x01, 0x55, 0x01, 0x4c, 0x01, 0x4c, 0x01, 0x3f, 0x01, 0x3f, 0x01, 0x2e, 0x01, 0x2e, 0x01, 0x17, 0x01, 0x17, 0x01, 0xfc, 0x00, 0xfc, 0x00, 0xda, 0x00, 0xda, 0x00, 0xb3, 0x00, 0xb3, 0x00, 0x88, 0x00, 0x88, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x27, 0x00, 0x27, 0x00, 0xf4, 0xff, 0xf4, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0x8c, 0xff, 0x8c, 0xff, 0x58, 0xff, 0x58, 0xff, 0x28, 0xff, 0x28, 0xff, 0xfd, 0xfe, 0xfd, 0xfe, 0xd9, 0xfe, 0xd9, 0xfe, 0xbf, 0xfe, 0xbf, 0xfe, 0xb0, 0xfe, 0xb0, 0xfe, 0xae, 0xfe, 0xae, 0xfe, 0xb5, 0xfe, 0xb5, 0xfe, 0xc3, 0xfe, 0xc3, 0xfe, 0xd9, 0xfe, 0xd9, 0xfe, 0xfb, 0xfe, 0xfb, 0xfe, 0x24, 0xff, 0x24, 0xff, 0x53, 0xff, 0x53, 0xff, 0x86, 0xff, 0x86, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0x2a, 0x00, 0x2a, 0x00, 0x61, 0x00, 0x61, 0x00, 0x94, 0x00, 0x94, 0x00, 0xc1, 0x00, 0xc1, 0x00, 0xe8, 0x00, 0xe8, 0x00, 0x09, 0x01, 0x09, 0x01, 0x24, 0x01, 0x24, 0x01, 0x37, 0x01, 0x37, 0x01, 0x41, 0x01, 0x41, 0x01, 0x45, 0x01, 0x45, 0x01, 0x43, 0x01, 0x43, 0x01, 0x3d, 0x01, 0x3d, 0x01, 0x30, 0x01, 0x30, 0x01, 0x1c, 0x01, 0x1c, 0x01, 0xff, 0x00, 0xff, 0x00, 0xdb, 0x00, 0xdb, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x42, 0x00, 0x42, 0x00, 0x06, 0x00, 0x06, 0x00, 0xc5, 0xff, 0xc5, 0xff, 0x82, 0xff, 0x82, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x03, 0xff, 0x03, 0xff, 0xcf, 0xfe, 0xcf, 0xfe, 0xa3, 0xfe, 0xa3, 0xfe, 0x7d, 0xfe, 0x7d, 0xfe, 0x61, 0xfe, 0x61, 0xfe, 0x4d, 0xfe, 0x4d, 0xfe, 0x44, 0xfe, 0x44, 0xfe, 0x46, 0xfe, 0x46, 0xfe, 0x54, 0xfe, 0x54, 0xfe, 0x6c, 0xfe, 0x6c, 0xfe, 0x8c, 0xfe, 0x8c, 0xfe, 0xb4, 0xfe, 0xb4, 0xfe, 0xe3, 0xfe, 0xe3, 0xfe, 0x19, 0xff, 0x19, 0xff, 0x53, 0xff, 0x53, 0xff, 0x92, 0xff, 0x92, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0x14, 0x00, 0x14, 0x00, 0x57, 0x00, 0x57, 0x00, 0x9b, 0x00, 0x9b, 0x00, 0xde, 0x00, 0xde, 0x00, 0x1f, 0x01, 0x1f, 0x01, 0x5d, 0x01, 0x5d, 0x01, 0x96, 0x01, 0x96, 0x01, 0xcb, 0x01, 0xcb, 0x01, 0xf9, 0x01, 0xf9, 0x01, 0x1d, 0x02, 0x1d, 0x02, 0x35, 0x02, 0x35, 0x02, 0x41, 0x02, 0x41, 0x02, 0x3f, 0x02, 0x3f, 0x02, 0x30, 0x02, 0x30, 0x02, 0x13, 0x02, 0x13, 0x02, 0xe9, 0x01, 0xe9, 0x01, 0xb3, 0x01, 0xb3, 0x01, 0x6f, 0x01, 0x6f, 0x01, 0x24, 0x01, 0x24, 0x01, 0xd2, 0x00, 0xd2, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x29, 0x00, 0x29, 0x00, 0xd5, 0xff, 0xd5, 0xff, 0x84, 0xff, 0x84, 0xff, 0x36, 0xff, 0x36, 0xff, 0xec, 0xfe, 0xec, 0xfe, 0xab, 0xfe, 0xab, 0xfe, 0x77, 0xfe, 0x77, 0xfe, 0x4c, 0xfe, 0x4c, 0xfe, 0x2b, 0xfe, 0x2b, 0xfe, 0x12, 0xfe, 0x12, 0xfe, 0x02, 0xfe, 0x02, 0xfe, 0xf9, 0xfd, 0xf9, 0xfd, 0xf6, 0xfd, 0xf6, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0x0b, 0xfe, 0x0b, 0xfe, 0x21, 0xfe, 0x21, 0xfe, 0x40, 0xfe, 0x40, 0xfe, 0x6c, 0xfe, 0x6c, 0xfe, 0xa1, 0xfe, 0xa1, 0xfe, 0xdd, 0xfe, 0xdd, 0xfe, 0x20, 0xff, 0x20, 0xff, 0x67, 0xff, 0x67, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x91, 0x00, 0x91, 0x00, 0xd1, 0x00, 0xd1, 0x00, 0x0a, 0x01, 0x0a, 0x01, 0x3d, 0x01, 0x3d, 0x01, 0x67, 0x01, 0x67, 0x01, 0x84, 0x01, 0x84, 0x01, 0x96, 0x01, 0x96, 0x01, 0x9f, 0x01, 0x9f, 0x01, 0x9f, 0x01, 0x9f, 0x01, 0x95, 0x01, 0x95, 0x01, 0x85, 0x01, 0x85, 0x01, 0x70, 0x01, 0x70, 0x01, 0x54, 0x01, 0x54, 0x01, 0x31, 0x01, 0x31, 0x01, 0x0a, 0x01, 0x0a, 0x01, 0xe0, 0x00, 0xe0, 0x00, 0xb1, 0x00, 0xb1, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x19, 0x00, 0x19, 0x00, 0xe6, 0xff, 0xe6, 0xff, 0xb6, 0xff, 0xb6, 0xff, 0x85, 0xff, 0x85, 0xff, 0x58, 0xff, 0x58, 0xff, 0x2d, 0xff, 0x2d, 0xff, 0x09, 0xff, 0x09, 0xff, 0xed, 0xfe, 0xed, 0xfe, 0xd7, 0xfe, 0xd7, 0xfe, 0xc7, 0xfe, 0xc7, 0xfe, 0xbc, 0xfe, 0xbc, 0xfe, 0xb8, 0xfe, 0xb8, 0xfe, 0xb7, 0xfe, 0xb7, 0xfe, 0xbf, 0xfe, 0xbf, 0xfe, 0xd3, 0xfe, 0xd3, 0xfe, 0xee, 0xfe, 0xee, 0xfe, 0x10, 0xff, 0x10, 0xff, 0x35, 0xff, 0x35, 0xff, 0x5f, 0xff, 0x5f, 0xff, 0x8c, 0xff, 0x8c, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0x24, 0x00, 0x24, 0x00, 0x55, 0x00, 0x55, 0x00, 0x80, 0x00, 0x80, 0x00, 0xa7, 0x00, 0xa7, 0x00, 0xc9, 0x00, 0xc9, 0x00, 0xe4, 0x00, 0xe4, 0x00, 0xfb, 0x00, 0xfb, 0x00, 0x0d, 0x01, 0x0d, 0x01, 0x17, 0x01, 0x17, 0x01, 0x19, 0x01, 0x19, 0x01, 0x16, 0x01, 0x16, 0x01, 0x0b, 0x01, 0x0b, 0x01, 0xfd, 0x00, 0xfd, 0x00, 0xe9, 0x00, 0xe9, 0x00, 0xcf, 0x00, 0xcf, 0x00, 0xb3, 0x00, 0xb3, 0x00, 0x90, 0x00, 0x90, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x42, 0x00, 0x42, 0x00, 0x16, 0x00, 0x16, 0x00, 0xe7, 0xff, 0xe7, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0x8d, 0xff, 0x8d, 0xff, 0x63, 0xff, 0x63, 0xff, 0x3d, 0xff, 0x3d, 0xff, 0x1b, 0xff, 0x1b, 0xff, 0x01, 0xff, 0x01, 0xff, 0xec, 0xfe, 0xec, 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xdd, 0xfe, 0xdd, 0xfe, 0xe1, 0xfe, 0xe1, 0xfe, 0xee, 0xfe, 0xee, 0xfe, 0x01, 0xff, 0x01, 0xff, 0x1c, 0xff, 0x1c, 0xff, 0x3e, 0xff, 0x3e, 0xff, 0x67, 0xff, 0x67, 0xff, 0x95, 0xff, 0x95, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0x22, 0x00, 0x22, 0x00, 0x53, 0x00, 0x53, 0x00, 0x84, 0x00, 0x84, 0x00, 0xb3, 0x00, 0xb3, 0x00, 0xde, 0x00, 0xde, 0x00, 0x03, 0x01, 0x03, 0x01, 0x21, 0x01, 0x21, 0x01, 0x36, 0x01, 0x36, 0x01, 0x41, 0x01, 0x41, 0x01, 0x44, 0x01, 0x44, 0x01, 0x3d, 0x01, 0x3d, 0x01, 0x2b, 0x01, 0x2b, 0x01, 0x11, 0x01, 0x11, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0x92, 0x00, 0x92, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0xdd, 0xff, 0xdd, 0xff, 0x9f, 0xff, 0x9f, 0xff, 0x65, 0xff, 0x65, 0xff, 0x30, 0xff, 0x30, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xd6, 0xfe, 0xd6, 0xfe, 0xb4, 0xfe, 0xb4, 0xfe, 0x9c, 0xfe, 0x9c, 0xfe, 0x8e, 0xfe, 0x8e, 0xfe, 0x8a, 0xfe, 0x8a, 0xfe, 0x8e, 0xfe, 0x8e, 0xfe, 0x9e, 0xfe, 0x9e, 0xfe, 0xb8, 0xfe, 0xb8, 0xfe, 0xdd, 0xfe, 0xdd, 0xfe, 0x0b, 0xff, 0x0b, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x7a, 0xff, 0x7a, 0xff, 0xba, 0xff, 0xba, 0xff, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x46, 0x00, 0x8d, 0x00, 0x8d, 0x00, 0xd2, 0x00, 0xd2, 0x00, 0x0f, 0x01, 0x0f, 0x01, 0x48, 0x01, 0x48, 0x01, 0x7a, 0x01, 0x7a, 0x01, 0xa5, 0x01, 0xa5, 0x01, 0xc7, 0x01, 0xc7, 0x01, 0xdc, 0x01, 0xdc, 0x01, 0xe5, 0x01, 0xe5, 0x01, 0xe0, 0x01, 0xe0, 0x01, 0xce, 0x01, 0xce, 0x01, 0xaf, 0x01, 0xaf, 0x01, 0x84, 0x01, 0x84, 0x01, 0x4e, 0x01, 0x4e, 0x01, 0x0f, 0x01, 0x0f, 0x01, 0xca, 0x00, 0xca, 0x00, 0x80, 0x00, 0x80, 0x00, 0x31, 0x00, 0x31, 0x00, 0xdf, 0xff, 0xdf, 0xff, 0x8c, 0xff, 0x8c, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0xf1, 0xfe, 0xf1, 0xfe, 0xb1, 0xfe, 0xb1, 0xfe, 0x7d, 0xfe, 0x7d, 0xfe, 0x54, 0xfe, 0x54, 0xfe, 0x36, 0xfe, 0x36, 0xfe, 0x25, 0xfe, 0x25, 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x22, 0xfe, 0x22, 0xfe, 0x30, 0xfe, 0x30, 0xfe, 0x4d, 0xfe, 0x4d, 0xfe, 0x77, 0xfe, 0x77, 0xfe, 0xa7, 0xfe, 0xa7, 0xfe, 0xdc, 0xfe, 0xdc, 0xfe, 0x14, 0xff, 0x14, 0xff, 0x51, 0xff, 0x51, 0xff, 0x8e, 0xff, 0x8e, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0x07, 0x00, 0x07, 0x00, 0x42, 0x00, 0x42, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0xb6, 0x00, 0xb6, 0x00, 0xe8, 0x00, 0xe8, 0x00, 0x11, 0x01, 0x11, 0x01, 0x32, 0x01, 0x32, 0x01, 0x4a, 0x01, 0x4a, 0x01, 0x59, 0x01, 0x59, 0x01, 0x62, 0x01, 0x62, 0x01, 0x5f, 0x01, 0x5f, 0x01, 0x52, 0x01, 0x52, 0x01, 0x39, 0x01, 0x39, 0x01, 0x18, 0x01, 0x18, 0x01, 0xf1, 0x00, 0xf1, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0x97, 0x00, 0x97, 0x00, 0x65, 0x00, 0x65, 0x00, 0x33, 0x00, 0x33, 0x00, 0x05, 0x00, 0x05, 0x00, 0xda, 0xff, 0xda, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0x93, 0xff, 0x93, 0xff, 0x79, 0xff, 0x79, 0xff, 0x63, 0xff, 0x63, 0xff, 0x54, 0xff, 0x54, 0xff, 0x4b, 0xff, 0x4b, 0xff, 0x48, 0xff, 0x48, 0xff, 0x46, 0xff, 0x46, 0xff, 0x47, 0xff, 0x47, 0xff, 0x4f, 0xff, 0x4f, 0xff, 0x5e, 0xff, 0x5e, 0xff, 0x74, 0xff, 0x74, 0xff, 0x8e, 0xff, 0x8e, 0xff, 0xaa, 0xff, 0xaa, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xea, 0xff, 0xea, 0xff, 0x0c, 0x00, 0x0c, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x86, 0x00, 0x86, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0xad, 0x00, 0xad, 0x00, 0xb9, 0x00, 0xb9, 0x00, 0xbf, 0x00, 0xbf, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xb7, 0x00, 0xb7, 0x00, 0xab, 0x00, 0xab, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x85, 0x00, 0x85, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x4d, 0x00, 0x4d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0xe9, 0xff, 0xe9, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xa2, 0xff, 0xa2, 0xff, 0x81, 0xff, 0x81, 0xff, 0x61, 0xff, 0x61, 0xff, 0x43, 0xff, 0x43, 0xff, 0x27, 0xff, 0x27, 0xff, 0x11, 0xff, 0x11, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe1, 0xfe, 0xe1, 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xe1, 0xfe, 0xe1, 0xfe, 0xe9, 0xfe, 0xe9, 0xfe, 0xf9, 0xfe, 0xf9, 0xfe, 0x10, 0xff, 0x10, 0xff, 0x2d, 0xff, 0x2d, 0xff, 0x4e, 0xff, 0x4e, 0xff, 0x73, 0xff, 0x73, 0xff, 0x9b, 0xff, 0x9b, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0x22, 0x00, 0x22, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x77, 0x00, 0x77, 0x00, 0x9d, 0x00, 0x9d, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xdf, 0x00, 0xdf, 0x00, 0xfa, 0x00, 0xfa, 0x00, 0x12, 0x01, 0x12, 0x01, 0x25, 0x01, 0x25, 0x01, 0x34, 0x01, 0x34, 0x01, 0x3d, 0x01, 0x3d, 0x01, 0x43, 0x01, 0x43, 0x01, 0x46, 0x01, 0x46, 0x01, 0x45, 0x01, 0x45, 0x01, 0x40, 0x01, 0x40, 0x01, 0x37, 0x01, 0x37, 0x01, 0x28, 0x01, 0x28, 0x01, 0x14, 0x01, 0x14, 0x01, 0xfb, 0x00, 0xfb, 0x00, 0xdf, 0x00, 0xdf, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0x98, 0x00, 0x98, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x43, 0x00, 0x43, 0x00, 0x18, 0x00, 0x18, 0x00, 0xec, 0xff, 0xec, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0x94, 0xff, 0x94, 0xff, 0x6c, 0xff, 0x6c, 0xff, 0x45, 0xff, 0x45, 0xff, 0x22, 0xff, 0x22, 0xff, 0x05, 0xff, 0x05, 0xff, 0xec, 0xfe, 0xec, 0xfe, 0xd8, 0xfe, 0xd8, 0xfe, 0xc8, 0xfe, 0xc8, 0xfe, 0xbd, 0xfe, 0xbd, 0xfe, 0xb7, 0xfe, 0xb7, 0xfe, 0xb6, 0xfe, 0xb6, 0xfe, 0xb9, 0xfe, 0xb9, 0xfe, 0xc1, 0xfe, 0xc1, 0xfe, 0xce, 0xfe, 0xce, 0xfe, 0xdd, 0xfe, 0xdd, 0xfe, 0xef, 0xfe, 0xef, 0xfe, 0x06, 0xff, 0x06, 0xff, 0x20, 0xff, 0x20, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x64, 0xff, 0x64, 0xff, 0x8d, 0xff, 0x8d, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0x16, 0x00, 0x16, 0x00, 0x47, 0x00, 0x47, 0x00, 0x79, 0x00, 0x79, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0xd4, 0x00, 0xd4, 0x00, 0xfa, 0x00, 0xfa, 0x00, 0x1b, 0x01, 0x1b, 0x01, 0x35, 0x01, 0x35, 0x01, 0x48, 0x01, 0x48, 0x01, 0x52, 0x01, 0x52, 0x01, 0x53, 0x01, 0x53, 0x01, 0x4c, 0x01, 0x4c, 0x01, 0x40, 0x01, 0x40, 0x01, 0x2e, 0x01, 0x2e, 0x01, 0x19, 0x01, 0x19, 0x01, 0x01, 0x01, 0x01, 0x01, 0xe8, 0x00, 0xe8, 0x00, 0xcd, 0x00, 0xcd, 0x00, 0xae, 0x00, 0xae, 0x00, 0x8c, 0x00, 0x8c, 0x00, 0x69, 0x00, 0x69, 0x00, 0x46, 0x00, 0x46, 0x00, 0x20, 0x00, 0x20, 0x00, 0xfb, 0xff, 0xfb, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0x8d, 0xff, 0x8d, 0xff, 0x6c, 0xff, 0x6c, 0xff, 0x4d, 0xff, 0x4d, 0xff, 0x33, 0xff, 0x33, 0xff, 0x1d, 0xff, 0x1d, 0xff, 0x0d, 0xff, 0x0d, 0xff, 0x05, 0xff, 0x05, 0xff, 0x03, 0xff, 0x03, 0xff, 0x09, 0xff, 0x09, 0xff, 0x12, 0xff, 0x12, 0xff, 0x1e, 0xff, 0x1e, 0xff, 0x2c, 0xff, 0x2c, 0xff, 0x3d, 0xff, 0x3d, 0xff, 0x53, 0xff, 0x53, 0xff, 0x6a, 0xff, 0x6a, 0xff, 0x85, 0xff, 0x85, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0x0f, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x37, 0x00, 0x37, 0x00, 0x40, 0x00, 0x40, 0x00, 0x47, 0x00, 0x47, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x53, 0x00, 0x53, 0x00, 0x58, 0x00, 0x58, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x60, 0x00, 0x61, 0x00, 0x61, 0x00, 0x62, 0x00, 0x62, 0x00, 0x62, 0x00, 0x62, 0x00, 0x62, 0x00, 0x62, 0x00, 0x5e, 0x00, 0x5e, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x56, 0x00, 0x56, 0x00, 0x51, 0x00, 0x51, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x52, 0x00, 0x53, 0x00, 0x53, 0x00, 0x50, 0x00, 0x50, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x50, 0x00, 0x51, 0x00, 0x51, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x46, 0x00, 0x46, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0xfa, 0xff, 0xfa, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xce, 0xff, 0xce, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0x9a, 0xff, 0x9a, 0xff, 0x81, 0xff, 0x81, 0xff, 0x6a, 0xff, 0x6a, 0xff, 0x59, 0xff, 0x59, 0xff, 0x4d, 0xff, 0x4d, 0xff, 0x47, 0xff, 0x47, 0xff, 0x45, 0xff, 0x45, 0xff, 0x46, 0xff, 0x46, 0xff, 0x4d, 0xff, 0x4d, 0xff, 0x5b, 0xff, 0x5b, 0xff, 0x6b, 0xff, 0x6b, 0xff, 0x7d, 0xff, 0x7d, 0xff, 0x91, 0xff, 0x91, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xda, 0xff, 0xda, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0x14, 0x00, 0x14, 0x00, 0x31, 0x00, 0x31, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x68, 0x00, 0x68, 0x00, 0x84, 0x00, 0x84, 0x00, 0x9d, 0x00, 0x9d, 0x00, 0xb3, 0x00, 0xb3, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xd2, 0x00, 0xd2, 0x00, 0xda, 0x00, 0xda, 0x00, 0xdd, 0x00, 0xdd, 0x00, 0xdb, 0x00, 0xdb, 0x00, 0xd1, 0x00, 0xd1, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xab, 0x00, 0xab, 0x00, 0x8e, 0x00, 0x8e, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x45, 0x00, 0x45, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0xf5, 0xff, 0xf5, 0xff, 0xca, 0xff, 0xca, 0xff, 0xa0, 0xff, 0xa0, 0xff, 0x7a, 0xff, 0x7a, 0xff, 0x5b, 0xff, 0x5b, 0xff, 0x42, 0xff, 0x42, 0xff, 0x2f, 0xff, 0x2f, 0xff, 0x22, 0xff, 0x22, 0xff, 0x1b, 0xff, 0x1b, 0xff, 0x1c, 0xff, 0x1c, 0xff, 0x24, 0xff, 0x24, 0xff, 0x34, 0xff, 0x34, 0xff, 0x4a, 0xff, 0x4a, 0xff, 0x64, 0xff, 0x64, 0xff, 0x84, 0xff, 0x84, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0xce, 0xff, 0xce, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0x1c, 0x00, 0x1c, 0x00, 0x43, 0x00, 0x43, 0x00, 0x66, 0x00, 0x66, 0x00, 0x86, 0x00, 0x86, 0x00, 0xa1, 0x00, 0xa1, 0x00, 0xb8, 0x00, 0xb8, 0x00, 0xc9, 0x00, 0xc9, 0x00, 0xd1, 0x00, 0xd1, 0x00, 0xd5, 0x00, 0xd5, 0x00, 0xd3, 0x00, 0xd3, 0x00, 0xca, 0x00, 0xca, 0x00, 0xbb, 0x00, 0xbb, 0x00, 0xa7, 0x00, 0xa7, 0x00, 0x8f, 0x00, 0x8f, 0x00, 0x73, 0x00, 0x73, 0x00, 0x56, 0x00, 0x56, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x21, 0x00, 0x21, 0x00, 0x07, 0x00, 0x07, 0x00, 0xed, 0xff, 0xed, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0xa5, 0xff, 0xa5, 0xff, 0x9c, 0xff, 0x9c, 0xff, 0x96, 0xff, 0x96, 0xff, 0x92, 0xff, 0x92, 0xff, 0x93, 0xff, 0x93, 0xff, 0x99, 0xff, 0x99, 0xff, 0xa2, 0xff, 0xa2, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xed, 0xff, 0xed, 0xff, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x29, 0x00, 0x29, 0x00, 0x32, 0x00, 0x32, 0x00, 0x36, 0x00, 0x36, 0x00, 0x34, 0x00, 0x34, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfb, 0xff, 0xfb, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0x9b, 0xff, 0x9b, 0xff, 0x8b, 0xff, 0x8b, 0xff, 0x7e, 0xff, 0x7e, 0xff, 0x73, 0xff, 0x73, 0xff, 0x6a, 0xff, 0x6a, 0xff, 0x66, 0xff, 0x66, 0xff, 0x69, 0xff, 0x69, 0xff, 0x73, 0xff, 0x73, 0xff, 0x82, 0xff, 0x82, 0xff, 0x95, 0xff, 0x95, 0xff, 0xac, 0xff, 0xac, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1d, 0x00, 0x1d, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x54, 0x00, 0x54, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x82, 0x00, 0x82, 0x00, 0x98, 0x00, 0x98, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0xb5, 0x00, 0xb5, 0x00, 0xbd, 0x00, 0xbd, 0x00, 0xc2, 0x00, 0xc2, 0x00, 0xc2, 0x00, 0xc2, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xb2, 0x00, 0xb2, 0x00, 0xa1, 0x00, 0xa1, 0x00, 0x8a, 0x00, 0x8a, 0x00, 0x70, 0x00, 0x70, 0x00, 0x52, 0x00, 0x52, 0x00, 0x30, 0x00, 0x30, 0x00, 0x08, 0x00, 0x08, 0x00, 0xde, 0xff, 0xde, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0x89, 0xff, 0x89, 0xff, 0x64, 0xff, 0x64, 0xff, 0x46, 0xff, 0x46, 0xff, 0x31, 0xff, 0x31, 0xff, 0x22, 0xff, 0x22, 0xff, 0x1a, 0xff, 0x1a, 0xff, 0x19, 0xff, 0x19, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x2e, 0xff, 0x2e, 0xff, 0x42, 0xff, 0x42, 0xff, 0x5b, 0xff, 0x5b, 0xff, 0x7a, 0xff, 0x7a, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0x0e, 0x00, 0x0e, 0x00, 0x34, 0x00, 0x34, 0x00, 0x56, 0x00, 0x56, 0x00, 0x72, 0x00, 0x72, 0x00, 0x87, 0x00, 0x87, 0x00, 0x99, 0x00, 0x99, 0x00, 0xa5, 0x00, 0xa5, 0x00, 0xab, 0x00, 0xab, 0x00, 0xab, 0x00, 0xab, 0x00, 0xa4, 0x00, 0xa4, 0x00, 0x98, 0x00, 0x98, 0x00, 0x89, 0x00, 0x89, 0x00, 0x77, 0x00, 0x77, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x45, 0x00, 0x45, 0x00, 0x26, 0x00, 0x26, 0x00, 0x02, 0x00, 0x02, 0x00, 0xde, 0xff, 0xde, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0x95, 0xff, 0x95, 0xff, 0x74, 0xff, 0x74, 0xff, 0x54, 0xff, 0x54, 0xff, 0x3b, 0xff, 0x3b, 0xff, 0x29, 0xff, 0x29, 0xff, 0x1d, 0xff, 0x1d, 0xff, 0x18, 0xff, 0x18, 0xff, 0x1d, 0xff, 0x1d, 0xff, 0x2d, 0xff, 0x2d, 0xff, 0x43, 0xff, 0x43, 0xff, 0x60, 0xff, 0x60, 0xff, 0x83, 0xff, 0x83, 0xff, 0xac, 0xff, 0xac, 0xff, 0xda, 0xff, 0xda, 0xff, 0x09, 0x00, 0x09, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x68, 0x00, 0x68, 0x00, 0x92, 0x00, 0x92, 0x00, 0xb5, 0x00, 0xb5, 0x00, 0xd3, 0x00, 0xd3, 0x00, 0xe9, 0x00, 0xe9, 0x00, 0xf7, 0x00, 0xf7, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0xe9, 0x00, 0xe9, 0x00, 0xd2, 0x00, 0xd2, 0x00, 0xb5, 0x00, 0xb5, 0x00, 0x92, 0x00, 0x92, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x42, 0x00, 0x42, 0x00, 0x16, 0x00, 0x16, 0x00, 0xe8, 0xff, 0xe8, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0x8f, 0xff, 0x8f, 0xff, 0x69, 0xff, 0x69, 0xff, 0x4a, 0xff, 0x4a, 0xff, 0x31, 0xff, 0x31, 0xff, 0x1e, 0xff, 0x1e, 0xff, 0x0f, 0xff, 0x0f, 0xff, 0x07, 0xff, 0x07, 0xff, 0x06, 0xff, 0x06, 0xff, 0x0e, 0xff, 0x0e, 0xff, 0x1e, 0xff, 0x1e, 0xff, 0x35, 0xff, 0x35, 0xff, 0x53, 0xff, 0x53, 0xff, 0x73, 0xff, 0x73, 0xff, 0x95, 0xff, 0x95, 0xff, 0xba, 0xff, 0xba, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0x0a, 0x00, 0x0a, 0x00, 0x35, 0x00, 0x35, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x81, 0x00, 0x81, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xb7, 0x00, 0xb7, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xda, 0x00, 0xda, 0x00, 0xe1, 0x00, 0xe1, 0x00, 0xdf, 0x00, 0xdf, 0x00, 0xd7, 0x00, 0xd7, 0x00, 0xc7, 0x00, 0xc7, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0x90, 0x00, 0x90, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x48, 0x00, 0x48, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0xf3, 0xff, 0xf3, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xa0, 0xff, 0xa0, 0xff, 0x79, 0xff, 0x79, 0xff, 0x59, 0xff, 0x59, 0xff, 0x40, 0xff, 0x40, 0xff, 0x30, 0xff, 0x30, 0xff, 0x24, 0xff, 0x24, 0xff, 0x21, 0xff, 0x21, 0xff, 0x25, 0xff, 0x25, 0xff, 0x30, 0xff, 0x30, 0xff, 0x42, 0xff, 0x42, 0xff, 0x5a, 0xff, 0x5a, 0xff, 0x76, 0xff, 0x76, 0xff, 0x96, 0xff, 0x96, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0x06, 0x00, 0x06, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x55, 0x00, 0x55, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x9f, 0x00, 0x9f, 0x00, 0xbd, 0x00, 0xbd, 0x00, 0xd6, 0x00, 0xd6, 0x00, 0xeb, 0x00, 0xeb, 0x00, 0xf9, 0x00, 0xf9, 0x00, 0x00, 0x01, 0x00, 0x01, 0xff, 0x00, 0xff, 0x00, 0xf6, 0x00, 0xf6, 0x00, 0xe5, 0x00, 0xe5, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0x84, 0x00, 0x84, 0x00, 0x57, 0x00, 0x57, 0x00, 0x28, 0x00, 0x28, 0x00, 0xf9, 0xff, 0xf9, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0x7a, 0xff, 0x7a, 0xff, 0x5a, 0xff, 0x5a, 0xff, 0x42, 0xff, 0x42, 0xff, 0x2f, 0xff, 0x2f, 0xff, 0x23, 0xff, 0x23, 0xff, 0x1d, 0xff, 0x1d, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x28, 0xff, 0x28, 0xff, 0x38, 0xff, 0x38, 0xff, 0x4e, 0xff, 0x4e, 0xff, 0x67, 0xff, 0x67, 0xff, 0x83, 0xff, 0x83, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0x10, 0x00, 0x10, 0x00, 0x36, 0x00, 0x36, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x9b, 0x00, 0x9b, 0x00, 0xb6, 0x00, 0xb6, 0x00, 0xca, 0x00, 0xca, 0x00, 0xd7, 0x00, 0xd7, 0x00, 0xde, 0x00, 0xde, 0x00, 0xde, 0x00, 0xde, 0x00, 0xd6, 0x00, 0xd6, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xb0, 0x00, 0xb0, 0x00, 0x95, 0x00, 0x95, 0x00, 0x73, 0x00, 0x73, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0xf0, 0xff, 0xf0, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xa0, 0xff, 0xa0, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x63, 0xff, 0x63, 0xff, 0x4d, 0xff, 0x4d, 0xff, 0x3d, 0xff, 0x3d, 0xff, 0x36, 0xff, 0x36, 0xff, 0x37, 0xff, 0x37, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x4e, 0xff, 0x4e, 0xff, 0x64, 0xff, 0x64, 0xff, 0x81, 0xff, 0x81, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xee, 0xff, 0xee, 0xff, 0x15, 0x00, 0x15, 0x00, 0x38, 0x00, 0x38, 0x00, 0x58, 0x00, 0x58, 0x00, 0x75, 0x00, 0x75, 0x00, 0x8b, 0x00, 0x8b, 0x00, 0x9b, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0xa6, 0x00, 0xae, 0x00, 0xae, 0x00, 0xb1, 0x00, 0xb1, 0x00, 0xb0, 0x00, 0xb0, 0x00, 0xac, 0x00, 0xac, 0x00, 0xa1, 0x00, 0xa1, 0x00, 0x8e, 0x00, 0x8e, 0x00, 0x72, 0x00, 0x72, 0x00, 0x51, 0x00, 0x51, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x05, 0x00, 0x05, 0x00, 0xdc, 0xff, 0xdc, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0x87, 0xff, 0x87, 0xff, 0x5e, 0xff, 0x5e, 0xff, 0x3b, 0xff, 0x3b, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x0a, 0xff, 0x0a, 0xff, 0xfb, 0xfe, 0xfb, 0xfe, 0xf5, 0xfe, 0xf5, 0xfe, 0xf6, 0xfe, 0xf6, 0xfe, 0x00, 0xff, 0x00, 0xff, 0x13, 0xff, 0x13, 0xff, 0x2e, 0xff, 0x2e, 0xff, 0x50, 0xff, 0x50, 0xff, 0x78, 0xff, 0x78, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0xda, 0xff, 0xda, 0xff, 0x0d, 0x00, 0x0d, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x71, 0x00, 0x71, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xf1, 0x00, 0xf1, 0x00, 0x10, 0x01, 0x10, 0x01, 0x29, 0x01, 0x29, 0x01, 0x38, 0x01, 0x38, 0x01, 0x3f, 0x01, 0x3f, 0x01, 0x3e, 0x01, 0x3e, 0x01, 0x31, 0x01, 0x31, 0x01, 0x1c, 0x01, 0x1c, 0x01, 0x01, 0x01, 0x01, 0x01, 0xe3, 0x00, 0xe3, 0x00, 0xc2, 0x00, 0xc2, 0x00, 0x9d, 0x00, 0x9d, 0x00, 0x75, 0x00, 0x75, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xad, 0xff, 0xad, 0xff, 0x89, 0xff, 0x89, 0xff, 0x69, 0xff, 0x69, 0xff, 0x50, 0xff, 0x50, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x2e, 0xff, 0x2e, 0xff, 0x27, 0xff, 0x27, 0xff, 0x27, 0xff, 0x27, 0xff, 0x2f, 0xff, 0x2f, 0xff, 0x3c, 0xff, 0x3c, 0xff, 0x50, 0xff, 0x50, 0xff, 0x6a, 0xff, 0x6a, 0xff, 0x89, 0xff, 0x89, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0xc8, 0xff, 0xc8, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0x01, 0x00, 0x01, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x41, 0x00, 0x41, 0x00, 0x44, 0x00, 0x44, 0x00, 0x41, 0x00, 0x41, 0x00, 0x39, 0x00, 0x39, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x16, 0x00, 0x16, 0x00, 0xff, 0xff, 0xff, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xa3, 0xff, 0xa3, 0xff, 0x8f, 0xff, 0x8f, 0xff, 0x7b, 0xff, 0x7b, 0xff, 0x69, 0xff, 0x69, 0xff, 0x5a, 0xff, 0x5a, 0xff, 0x53, 0xff, 0x53, 0xff, 0x53, 0xff, 0x53, 0xff, 0x5a, 0xff, 0x5a, 0xff, 0x68, 0xff, 0x68, 0xff, 0x7a, 0xff, 0x7a, 0xff, 0x95, 0xff, 0x95, 0xff, 0xb7, 0xff, 0xb7, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0x07, 0x00, 0x07, 0x00, 0x32, 0x00, 0x32, 0x00, 0x60, 0x00, 0x60, 0x00, 0x90, 0x00, 0x90, 0x00, 0xbf, 0x00, 0xbf, 0x00, 0xec, 0x00, 0xec, 0x00, 0x13, 0x01, 0x13, 0x01, 0x35, 0x01, 0x35, 0x01, 0x4f, 0x01, 0x4f, 0x01, 0x5f, 0x01, 0x5f, 0x01, 0x67, 0x01, 0x67, 0x01, 0x66, 0x01, 0x66, 0x01, 0x5b, 0x01, 0x5b, 0x01, 0x45, 0x01, 0x45, 0x01, 0x25, 0x01, 0x25, 0x01, 0xfe, 0x00, 0xfe, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0x60, 0x00, 0x60, 0x00, 0x20, 0x00, 0x20, 0x00, 0xdb, 0xff, 0xdb, 0xff, 0x95, 0xff, 0x95, 0xff, 0x52, 0xff, 0x52, 0xff, 0x12, 0xff, 0x12, 0xff, 0xd7, 0xfe, 0xd7, 0xfe, 0xa1, 0xfe, 0xa1, 0xfe, 0x78, 0xfe, 0x78, 0xfe, 0x5a, 0xfe, 0x5a, 0xfe, 0x46, 0xfe, 0x46, 0xfe, 0x3b, 0xfe, 0x3b, 0xfe, 0x3c, 0xfe, 0x3c, 0xfe, 0x4b, 0xfe, 0x4b, 0xfe, 0x65, 0xfe, 0x65, 0xfe, 0x8b, 0xfe, 0x8b, 0xfe, 0xbc, 0xfe, 0xbc, 0xfe, 0xf5, 0xfe, 0xf5, 0xfe, 0x35, 0xff, 0x35, 0xff, 0x7c, 0xff, 0x7c, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0x13, 0x00, 0x13, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0xee, 0x00, 0xee, 0x00, 0x2c, 0x01, 0x2c, 0x01, 0x64, 0x01, 0x64, 0x01, 0x92, 0x01, 0x92, 0x01, 0xb6, 0x01, 0xb6, 0x01, 0xce, 0x01, 0xce, 0x01, 0xd9, 0x01, 0xd9, 0x01, 0xd7, 0x01, 0xd7, 0x01, 0xc8, 0x01, 0xc8, 0x01, 0xad, 0x01, 0xad, 0x01, 0x86, 0x01, 0x86, 0x01, 0x55, 0x01, 0x55, 0x01, 0x1a, 0x01, 0x1a, 0x01, 0xdb, 0x00, 0xdb, 0x00, 0x98, 0x00, 0x98, 0x00, 0x51, 0x00, 0x51, 0x00, 0x06, 0x00, 0x06, 0x00, 0xbb, 0xff, 0xbb, 0xff, 0x77, 0xff, 0x77, 0xff, 0x39, 0xff, 0x39, 0xff, 0x02, 0xff, 0x02, 0xff, 0xd0, 0xfe, 0xd0, 0xfe, 0xa5, 0xfe, 0xa5, 0xfe, 0x81, 0xfe, 0x81, 0xfe, 0x66, 0xfe, 0x66, 0xfe, 0x55, 0xfe, 0x55, 0xfe, 0x52, 0xfe, 0x52, 0xfe, 0x59, 0xfe, 0x59, 0xfe, 0x6b, 0xfe, 0x6b, 0xfe, 0x87, 0xfe, 0x87, 0xfe, 0xab, 0xfe, 0xab, 0xfe, 0xd7, 0xfe, 0xd7, 0xfe, 0x0c, 0xff, 0x0c, 0xff, 0x4c, 0xff, 0x4c, 0xff, 0x91, 0xff, 0x91, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0x1b, 0x00, 0x1b, 0x00, 0x5e, 0x00, 0x5e, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xdb, 0x00, 0xdb, 0x00, 0x0c, 0x01, 0x0c, 0x01, 0x34, 0x01, 0x34, 0x01, 0x50, 0x01, 0x50, 0x01, 0x61, 0x01, 0x61, 0x01, 0x69, 0x01, 0x69, 0x01, 0x6a, 0x01, 0x6a, 0x01, 0x63, 0x01, 0x63, 0x01, 0x53, 0x01, 0x53, 0x01, 0x3c, 0x01, 0x3c, 0x01, 0x1e, 0x01, 0x1e, 0x01, 0xf8, 0x00, 0xf8, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0x9e, 0x00, 0x9e, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x36, 0x00, 0x36, 0x00, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0x90, 0xff, 0x90, 0xff, 0x5c, 0xff, 0x5c, 0xff, 0x2e, 0xff, 0x2e, 0xff, 0x08, 0xff, 0x08, 0xff, 0xe9, 0xfe, 0xe9, 0xfe, 0xd5, 0xfe, 0xd5, 0xfe, 0xcb, 0xfe, 0xcb, 0xfe, 0xc9, 0xfe, 0xc9, 0xfe, 0xce, 0xfe, 0xce, 0xfe, 0xd9, 0xfe, 0xd9, 0xfe, 0xec, 0xfe, 0xec, 0xfe, 0x05, 0xff, 0x05, 0xff, 0x27, 0xff, 0x27, 0xff, 0x4f, 0xff, 0x4f, 0xff, 0x7c, 0xff, 0x7c, 0xff, 0xad, 0xff, 0xad, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0x15, 0x00, 0x15, 0x00, 0x47, 0x00, 0x47, 0x00, 0x76, 0x00, 0x76, 0x00, 0x9f, 0x00, 0x9f, 0x00, 0xc6, 0x00, 0xc6, 0x00, 0xe5, 0x00, 0xe5, 0x00, 0xff, 0x00, 0xff, 0x00, 0x14, 0x01, 0x14, 0x01, 0x20, 0x01, 0x20, 0x01, 0x24, 0x01, 0x24, 0x01, 0x1e, 0x01, 0x1e, 0x01, 0x11, 0x01, 0x11, 0x01, 0xfd, 0x00, 0xfd, 0x00, 0xe5, 0x00, 0xe5, 0x00, 0xca, 0x00, 0xca, 0x00, 0xac, 0x00, 0xac, 0x00, 0x8c, 0x00, 0x8c, 0x00, 0x66, 0x00, 0x66, 0x00, 0x40, 0x00, 0x40, 0x00, 0x19, 0x00, 0x19, 0x00, 0xf1, 0xff, 0xf1, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0x82, 0xff, 0x82, 0xff, 0x63, 0xff, 0x63, 0xff, 0x49, 0xff, 0x49, 0xff, 0x34, 0xff, 0x34, 0xff, 0x24, 0xff, 0x24, 0xff, 0x1a, 0xff, 0x1a, 0xff, 0x17, 0xff, 0x17, 0xff, 0x1d, 0xff, 0x1d, 0xff, 0x2a, 0xff, 0x2a, 0xff, 0x40, 0xff, 0x40, 0xff, 0x57, 0xff, 0x57, 0xff, 0x70, 0xff, 0x70, 0xff, 0x8b, 0xff, 0x8b, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0xca, 0xff, 0xca, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0x05, 0x00, 0x05, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x36, 0x00, 0x36, 0x00, 0x48, 0x00, 0x48, 0x00, 0x57, 0x00, 0x57, 0x00, 0x62, 0x00, 0x62, 0x00, 0x68, 0x00, 0x68, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x66, 0x00, 0x66, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x54, 0x00, 0x54, 0x00, 0x49, 0x00, 0x49, 0x00, 0x42, 0x00, 0x42, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x33, 0x00, 0x33, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x11, 0x00, 0x11, 0x00, 0x07, 0x00, 0x07, 0x00, 0xfe, 0xff, 0xfe, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xec, 0xff, 0xec, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xde, 0xff, 0xde, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xde, 0xff, 0xde, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0xef, 0xff, 0xef, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0x01, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x15, 0x00, 0x15, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x24, 0x00, 0x24, 0x00, 0x28, 0x00, 0x28, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x29, 0x00, 0x29, 0x00, 0x26, 0x00, 0x26, 0x00, 0x21, 0x00, 0x21, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x13, 0x00, 0x13, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x02, 0x00, 0xf6, 0xff, 0xf6, 0xff, 0xea, 0xff, 0xea, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xda, 0xff, 0xda, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xde, 0xff, 0xde, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xef, 0xff, 0xef, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x07, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x14, 0x00, 0x18, 0x00, 0x18, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x21, 0x00, 0x21, 0x00, 0x23, 0x00, 0x23, 0x00, 0x24, 0x00, 0x24, 0x00, 0x23, 0x00, 0x23, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x16, 0x00, 0x16, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x03, 0x00, 0xf9, 0xff, 0xf9, 0xff, 0xed, 0xff, 0xed, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xda, 0xff, 0xda, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xc8, 0xff, 0xc8, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xce, 0xff, 0xce, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x17, 0x00, 0x17, 0x00, 0x25, 0x00, 0x25, 0x00, 0x32, 0x00, 0x32, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x47, 0x00, 0x47, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x56, 0x00, 0x56, 0x00, 0x59, 0x00, 0x59, 0x00, 0x58, 0x00, 0x58, 0x00, 0x54, 0x00, 0x54, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x41, 0x00, 0x41, 0x00, 0x31, 0x00, 0x31, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x06, 0x00, 0x06, 0x00, 0xef, 0xff, 0xef, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0x8a, 0xff, 0x8a, 0xff, 0x79, 0xff, 0x79, 0xff, 0x6d, 0xff, 0x6d, 0xff, 0x67, 0xff, 0x67, 0xff, 0x66, 0xff, 0x66, 0xff, 0x68, 0xff, 0x68, 0xff, 0x70, 0xff, 0x70, 0xff, 0x7b, 0xff, 0x7b, 0xff, 0x88, 0xff, 0x88, 0xff, 0x99, 0xff, 0x99, 0xff, 0xae, 0xff, 0xae, 0xff, 0xc8, 0xff, 0xc8, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1c, 0x00, 0x1c, 0x00, 0x39, 0x00, 0x39, 0x00, 0x54, 0x00, 0x54, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x87, 0x00, 0x87, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xb3, 0x00, 0xb3, 0x00, 0xb9, 0x00, 0xb9, 0x00, 0xba, 0x00, 0xba, 0x00, 0xb9, 0x00, 0xb9, 0x00, 0xb3, 0x00, 0xb3, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0x99, 0x00, 0x99, 0x00, 0x80, 0x00, 0x80, 0x00, 0x64, 0x00, 0x64, 0x00, 0x45, 0x00, 0x45, 0x00, 0x22, 0x00, 0x22, 0x00, 0xfe, 0xff, 0xfe, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xb7, 0xff, 0xb7, 0xff, 0x96, 0xff, 0x96, 0xff, 0x79, 0xff, 0x79, 0xff, 0x5e, 0xff, 0x5e, 0xff, 0x47, 0xff, 0x47, 0xff, 0x34, 0xff, 0x34, 0xff, 0x2a, 0xff, 0x2a, 0xff, 0x26, 0xff, 0x26, 0xff, 0x27, 0xff, 0x27, 0xff, 0x2f, 0xff, 0x2f, 0xff, 0x3b, 0xff, 0x3b, 0xff, 0x4b, 0xff, 0x4b, 0xff, 0x60, 0xff, 0x60, 0xff, 0x79, 0xff, 0x79, 0xff, 0x96, 0xff, 0x96, 0xff, 0xb4, 0xff, 0xb4, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x15, 0x00, 0x27, 0x00, 0x27, 0x00, 0x35, 0x00, 0x35, 0x00, 0x40, 0x00, 0x40, 0x00, 0x47, 0x00, 0x47, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4d, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x48, 0x00, 0x48, 0x00, 0x45, 0x00, 0x45, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x35, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x28, 0x00, 0x28, 0x00, 0x20, 0x00, 0x20, 0x00, 0x19, 0x00, 0x19, 0x00, 0x12, 0x00, 0x12, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xed, 0xff, 0xed, 0xff, 0xee, 0xff, 0xee, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x40, 0x00, 0x40, 0x00, 0x52, 0x00, 0x52, 0x00, 0x63, 0x00, 0x63, 0x00, 0x70, 0x00, 0x70, 0x00, 0x79, 0x00, 0x79, 0x00, 0x7f, 0x00, 0x7f, 0x00, 0x83, 0x00, 0x83, 0x00, 0x80, 0x00, 0x80, 0x00, 0x76, 0x00, 0x76, 0x00, 0x66, 0x00, 0x66, 0x00, 0x51, 0x00, 0x51, 0x00, 0x38, 0x00, 0x38, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0xfa, 0xff, 0xfa, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0x91, 0xff, 0x91, 0xff, 0x7b, 0xff, 0x7b, 0xff, 0x68, 0xff, 0x68, 0xff, 0x5a, 0xff, 0x5a, 0xff, 0x4e, 0xff, 0x4e, 0xff, 0x46, 0xff, 0x46, 0xff, 0x43, 0xff, 0x43, 0xff, 0x44, 0xff, 0x44, 0xff, 0x49, 0xff, 0x49, 0xff, 0x52, 0xff, 0x52, 0xff, 0x5e, 0xff, 0x5e, 0xff, 0x6e, 0xff, 0x6e, 0xff, 0x81, 0xff, 0x81, 0xff, 0x9a, 0xff, 0x9a, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xda, 0xff, 0xda, 0xff, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x27, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x74, 0x00, 0x74, 0x00, 0x98, 0x00, 0x98, 0x00, 0xb9, 0x00, 0xb9, 0x00, 0xd4, 0x00, 0xd4, 0x00, 0xe9, 0x00, 0xe9, 0x00, 0xf6, 0x00, 0xf6, 0x00, 0xfa, 0x00, 0xfa, 0x00, 0xf7, 0x00, 0xf7, 0x00, 0xed, 0x00, 0xed, 0x00, 0xdc, 0x00, 0xdc, 0x00, 0xc4, 0x00, 0xc4, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x51, 0x00, 0x51, 0x00, 0x24, 0x00, 0x24, 0x00, 0xf6, 0xff, 0xf6, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0x9f, 0xff, 0x9f, 0xff, 0x79, 0xff, 0x79, 0xff, 0x57, 0xff, 0x57, 0xff, 0x38, 0xff, 0x38, 0xff, 0x1e, 0xff, 0x1e, 0xff, 0x0a, 0xff, 0x0a, 0xff, 0xfa, 0xfe, 0xfa, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe, 0xf6, 0xfe, 0xf6, 0xfe, 0x02, 0xff, 0x02, 0xff, 0x13, 0xff, 0x13, 0xff, 0x2a, 0xff, 0x2a, 0xff, 0x47, 0xff, 0x47, 0xff, 0x67, 0xff, 0x67, 0xff, 0x8a, 0xff, 0x8a, 0xff, 0xae, 0xff, 0xae, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2c, 0x00, 0x2c, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x84, 0x00, 0x84, 0x00, 0xad, 0x00, 0xad, 0x00, 0xd1, 0x00, 0xd1, 0x00, 0xf1, 0x00, 0xf1, 0x00, 0x0d, 0x01, 0x0d, 0x01, 0x23, 0x01, 0x23, 0x01, 0x34, 0x01, 0x34, 0x01, 0x3d, 0x01, 0x3d, 0x01, 0x3f, 0x01, 0x3f, 0x01, 0x3b, 0x01, 0x3b, 0x01, 0x30, 0x01, 0x30, 0x01, 0x1d, 0x01, 0x1d, 0x01, 0x03, 0x01, 0x03, 0x01, 0xe4, 0x00, 0xe4, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0x9f, 0x00, 0x9f, 0x00, 0x78, 0x00, 0x78, 0x00, 0x50, 0x00, 0x50, 0x00, 0x26, 0x00, 0x26, 0x00, 0xfc, 0xff, 0xfc, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xad, 0xff, 0xad, 0xff, 0x8a, 0xff, 0x8a, 0xff, 0x6b, 0xff, 0x6b, 0xff, 0x50, 0xff, 0x50, 0xff, 0x36, 0xff, 0x36, 0xff, 0x20, 0xff, 0x20, 0xff, 0x0d, 0xff, 0x0d, 0xff, 0x00, 0xff, 0x00, 0xff, 0xf8, 0xfe, 0xf8, 0xfe, 0xf6, 0xfe, 0xf6, 0xfe, 0xf6, 0xfe, 0xf6, 0xfe, 0xfb, 0xfe, 0xfb, 0xfe, 0x05, 0xff, 0x05, 0xff, 0x12, 0xff, 0x12, 0xff, 0x24, 0xff, 0x24, 0xff, 0x3b, 0xff, 0x3b, 0xff, 0x59, 0xff, 0x59, 0xff, 0x78, 0xff, 0x78, 0xff, 0x99, 0xff, 0x99, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0x03, 0x00, 0x03, 0x00, 0x26, 0x00, 0x26, 0x00, 0x48, 0x00, 0x48, 0x00, 0x65, 0x00, 0x65, 0x00, 0x80, 0x00, 0x80, 0x00, 0x96, 0x00, 0x96, 0x00, 0xa8, 0x00, 0xa8, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc7, 0x00, 0xc7, 0x00, 0xc6, 0x00, 0xc6, 0x00, 0xbf, 0x00, 0xbf, 0x00, 0xb6, 0x00, 0xb6, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x8a, 0x00, 0x8a, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0x68, 0x00, 0x68, 0x00, 0x54, 0x00, 0x54, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x25, 0x00, 0x25, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf8, 0xff, 0xf8, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xce, 0xff, 0xce, 0xff, 0xba, 0xff, 0xba, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0x95, 0xff, 0x95, 0xff, 0x85, 0xff, 0x85, 0xff, 0x7a, 0xff, 0x7a, 0xff, 0x75, 0xff, 0x75, 0xff, 0x72, 0xff, 0x72, 0xff, 0x70, 0xff, 0x70, 0xff, 0x72, 0xff, 0x72, 0xff, 0x78, 0xff, 0x78, 0xff, 0x81, 0xff, 0x81, 0xff, 0x8b, 0xff, 0x8b, 0xff, 0x97, 0xff, 0x97, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0x0d, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x34, 0x00, 0x34, 0x00, 0x48, 0x00, 0x48, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x8c, 0x00, 0x8c, 0x00, 0x99, 0x00, 0x99, 0x00, 0xa1, 0x00, 0xa1, 0x00, 0xa6, 0x00, 0xa6, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0xa8, 0x00, 0xa8, 0x00, 0xa4, 0x00, 0xa4, 0x00, 0x9e, 0x00, 0x9e, 0x00, 0x93, 0x00, 0x93, 0x00, 0x86, 0x00, 0x86, 0x00, 0x77, 0x00, 0x77, 0x00, 0x67, 0x00, 0x67, 0x00, 0x55, 0x00, 0x55, 0x00, 0x41, 0x00, 0x41, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x15, 0x00, 0x15, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0x9a, 0xff, 0x9a, 0xff, 0x85, 0xff, 0x85, 0xff, 0x72, 0xff, 0x72, 0xff, 0x61, 0xff, 0x61, 0xff, 0x53, 0xff, 0x53, 0xff, 0x48, 0xff, 0x48, 0xff, 0x40, 0xff, 0x40, 0xff, 0x3a, 0xff, 0x3a, 0xff, 0x37, 0xff, 0x37, 0xff, 0x38, 0xff, 0x38, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x4c, 0xff, 0x4c, 0xff, 0x5f, 0xff, 0x5f, 0xff, 0x76, 0xff, 0x76, 0xff, 0x8d, 0xff, 0x8d, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0xba, 0xff, 0xba, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0x0f, 0x00, 0x0f, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x67, 0x00, 0x67, 0x00, 0x80, 0x00, 0x80, 0x00, 0x97, 0x00, 0x97, 0x00, 0xae, 0x00, 0xae, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xd8, 0x00, 0xd8, 0x00, 0xe4, 0x00, 0xe4, 0x00, 0xea, 0x00, 0xea, 0x00, 0xee, 0x00, 0xee, 0x00, 0xee, 0x00, 0xee, 0x00, 0xe8, 0x00, 0xe8, 0x00, 0xde, 0x00, 0xde, 0x00, 0xce, 0x00, 0xce, 0x00, 0xb9, 0x00, 0xb9, 0x00, 0x9f, 0x00, 0x9f, 0x00, 0x81, 0x00, 0x81, 0x00, 0x62, 0x00, 0x62, 0x00, 0x40, 0x00, 0x40, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0xfc, 0xff, 0xfc, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0x83, 0xff, 0x83, 0xff, 0x6a, 0xff, 0x6a, 0xff, 0x53, 0xff, 0x53, 0xff, 0x40, 0xff, 0x40, 0xff, 0x2f, 0xff, 0x2f, 0xff, 0x23, 0xff, 0x23, 0xff, 0x1b, 0xff, 0x1b, 0xff, 0x19, 0xff, 0x19, 0xff, 0x1b, 0xff, 0x1b, 0xff, 0x20, 0xff, 0x20, 0xff, 0x2b, 0xff, 0x2b, 0xff, 0x3b, 0xff, 0x3b, 0xff, 0x4f, 0xff, 0x4f, 0xff, 0x64, 0xff, 0x64, 0xff, 0x7b, 0xff, 0x7b, 0xff, 0x96, 0xff, 0x96, 0xff, 0xb6, 0xff, 0xb6, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0x01, 0x00, 0x01, 0x00, 0x26, 0x00, 0x26, 0x00, 0x46, 0x00, 0x46, 0x00, 0x62, 0x00, 0x62, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x92, 0x00, 0x92, 0x00, 0xa6, 0x00, 0xa6, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xbd, 0x00, 0xbd, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc1, 0x00, 0xc1, 0x00, 0xba, 0x00, 0xba, 0x00, 0xad, 0x00, 0xad, 0x00, 0x9d, 0x00, 0x9d, 0x00, 0x8b, 0x00, 0x8b, 0x00, 0x78, 0x00, 0x78, 0x00, 0x63, 0x00, 0x63, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x39, 0x00, 0x39, 0x00, 0x24, 0x00, 0x24, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf9, 0xff, 0xf9, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xa3, 0xff, 0xa3, 0xff, 0x97, 0xff, 0x97, 0xff, 0x8c, 0xff, 0x8c, 0xff, 0x82, 0xff, 0x82, 0xff, 0x7c, 0xff, 0x7c, 0xff, 0x7a, 0xff, 0x7a, 0xff, 0x7c, 0xff, 0x7c, 0xff, 0x80, 0xff, 0x80, 0xff, 0x86, 0xff, 0x86, 0xff, 0x90, 0xff, 0x90, 0xff, 0x9c, 0xff, 0x9c, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0xb7, 0xff, 0xb7, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0x04, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x14, 0x00, 0x16, 0x00, 0x16, 0x00, 0x15, 0x00, 0x15, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x15, 0x00, 0x15, 0x00, 0x19, 0x00, 0x19, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x25, 0x00, 0x25, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x34, 0x00, 0x34, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x47, 0x00, 0x47, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4d, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x46, 0x00, 0x46, 0x00, 0x40, 0x00, 0x40, 0x00, 0x37, 0x00, 0x37, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x25, 0x00, 0x25, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x11, 0x00, 0x11, 0x00, 0x06, 0x00, 0x06, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0xa0, 0xff, 0xa0, 0xff, 0x98, 0xff, 0x98, 0xff, 0x95, 0xff, 0x95, 0xff, 0x98, 0xff, 0x98, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0xa2, 0xff, 0xa2, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xea, 0xff, 0xea, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x18, 0x00, 0x24, 0x00, 0x24, 0x00, 0x30, 0x00, 0x30, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x56, 0x00, 0x56, 0x00, 0x60, 0x00, 0x60, 0x00, 0x65, 0x00, 0x65, 0x00, 0x69, 0x00, 0x69, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x68, 0x00, 0x68, 0x00, 0x66, 0x00, 0x66, 0x00, 0x63, 0x00, 0x63, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x51, 0x00, 0x51, 0x00, 0x46, 0x00, 0x46, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x21, 0x00, 0x21, 0x00, 0x13, 0x00, 0x13, 0x00, 0x07, 0x00, 0x07, 0x00, 0xfb, 0xff, 0xfb, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xc8, 0xff, 0xc8, 0xff, 0xc4, 0xff, 0xc4, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xad, 0xff, 0xad, 0xff, 0xac, 0xff, 0xac, 0xff, 0xac, 0xff, 0xac, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xef, 0xff, 0xef, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0x06, 0x00, 0x06, 0x00, 0x14, 0x00, 0x14, 0x00, 0x23, 0x00, 0x23, 0x00, 0x30, 0x00, 0x30, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x57, 0x00, 0x57, 0x00, 0x61, 0x00, 0x61, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x76, 0x00, 0x76, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x83, 0x00, 0x83, 0x00, 0x85, 0x00, 0x85, 0x00, 0x82, 0x00, 0x82, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x75, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x61, 0x00, 0x54, 0x00, 0x54, 0x00, 0x46, 0x00, 0x46, 0x00, 0x36, 0x00, 0x36, 0x00, 0x26, 0x00, 0x26, 0x00, 0x15, 0x00, 0x15, 0x00, 0x05, 0x00, 0x05, 0x00, 0xf4, 0xff, 0xf4, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xce, 0xff, 0xce, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xb6, 0xff, 0xb6, 0xff, 0xad, 0xff, 0xad, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0xa5, 0xff, 0xa5, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0xa6, 0xff, 0xa6, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0xad, 0xff, 0xad, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xea, 0xff, 0xea, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0x05, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x18, 0x00, 0x18, 0x00, 0x21, 0x00, 0x21, 0x00, 0x24, 0x00, 0x24, 0x00, 0x23, 0x00, 0x23, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x16, 0x00, 0x16, 0x00, 0x11, 0x00, 0x11, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x04, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xca, 0xff, 0xca, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xb7, 0xff, 0xb7, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xea, 0xff, 0xea, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0x07, 0x00, 0x07, 0x00, 0x19, 0x00, 0x19, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x66, 0x00, 0x66, 0x00, 0x72, 0x00, 0x72, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x82, 0x00, 0x82, 0x00, 0x86, 0x00, 0x86, 0x00, 0x89, 0x00, 0x89, 0x00, 0x89, 0x00, 0x89, 0x00, 0x87, 0x00, 0x87, 0x00, 0x83, 0x00, 0x83, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0x77, 0x00, 0x77, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x5e, 0x00, 0x5e, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x35, 0x00, 0x35, 0x00, 0x20, 0x00, 0x20, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0xf4, 0xff, 0xf4, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0x98, 0xff, 0x98, 0xff, 0x81, 0xff, 0x81, 0xff, 0x6a, 0xff, 0x6a, 0xff, 0x52, 0xff, 0x52, 0xff, 0x3d, 0xff, 0x3d, 0xff, 0x2b, 0xff, 0x2b, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x17, 0xff, 0x17, 0xff, 0x16, 0xff, 0x16, 0xff, 0x1c, 0xff, 0x1c, 0xff, 0x27, 0xff, 0x27, 0xff, 0x37, 0xff, 0x37, 0xff, 0x48, 0xff, 0x48, 0xff, 0x5d, 0xff, 0x5d, 0xff, 0x78, 0xff, 0x78, 0xff, 0x96, 0xff, 0x96, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0x10, 0x00, 0x10, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x47, 0x00, 0x47, 0x00, 0x5e, 0x00, 0x5e, 0x00, 0x73, 0x00, 0x73, 0x00, 0x85, 0x00, 0x85, 0x00, 0x93, 0x00, 0x93, 0x00, 0x9f, 0x00, 0x9f, 0x00, 0xab, 0x00, 0xab, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xba, 0x00, 0xba, 0x00, 0xbb, 0x00, 0xbb, 0x00, 0xb9, 0x00, 0xb9, 0x00, 0xb5, 0x00, 0xb5, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0xa7, 0x00, 0xa7, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0x8c, 0x00, 0x8c, 0x00, 0x77, 0x00, 0x77, 0x00, 0x61, 0x00, 0x61, 0x00, 0x49, 0x00, 0x49, 0x00, 0x30, 0x00, 0x30, 0x00, 0x14, 0x00, 0x14, 0x00, 0xf9, 0xff, 0xf9, 0xff, 0xde, 0xff, 0xde, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0x9f, 0xff, 0x9f, 0xff, 0x92, 0xff, 0x92, 0xff, 0x87, 0xff, 0x87, 0xff, 0x80, 0xff, 0x80, 0xff, 0x7d, 0xff, 0x7d, 0xff, 0x7e, 0xff, 0x7e, 0xff, 0x85, 0xff, 0x85, 0xff, 0x8e, 0xff, 0x8e, 0xff, 0x98, 0xff, 0x98, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0x06, 0x00, 0x06, 0x00, 0x16, 0x00, 0x16, 0x00, 0x24, 0x00, 0x24, 0x00, 0x32, 0x00, 0x32, 0x00, 0x40, 0x00, 0x40, 0x00, 0x4d, 0x00, 0x4d, 0x00, 0x58, 0x00, 0x58, 0x00, 0x5e, 0x00, 0x5e, 0x00, 0x61, 0x00, 0x61, 0x00, 0x61, 0x00, 0x61, 0x00, 0x5e, 0x00, 0x5e, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x57, 0x00, 0x57, 0x00, 0x52, 0x00, 0x52, 0x00, 0x4d, 0x00, 0x4d, 0x00, 0x44, 0x00, 0x44, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x22, 0x00, 0x22, 0x00, 0x15, 0x00, 0x15, 0x00, 0x08, 0x00, 0x08, 0x00, 0xfa, 0xff, 0xfa, 0xff, 0xed, 0xff, 0xed, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xce, 0xff, 0xce, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0xa6, 0xff, 0xa6, 0xff, 0xa0, 0xff, 0xa0, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0x9c, 0xff, 0x9c, 0xff, 0x9a, 0xff, 0x9a, 0xff, 0x97, 0xff, 0x97, 0xff, 0x96, 0xff, 0x96, 0xff, 0x9a, 0xff, 0x9a, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0xad, 0xff, 0xad, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0x0c, 0x00, 0x0c, 0x00, 0x23, 0x00, 0x23, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x51, 0x00, 0x51, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x83, 0x00, 0x83, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0xae, 0x00, 0xae, 0x00, 0xbd, 0x00, 0xbd, 0x00, 0xca, 0x00, 0xca, 0x00, 0xd3, 0x00, 0xd3, 0x00, 0xd9, 0x00, 0xd9, 0x00, 0xda, 0x00, 0xda, 0x00, 0xd6, 0x00, 0xd6, 0x00, 0xcf, 0x00, 0xcf, 0x00, 0xc4, 0x00, 0xc4, 0x00, 0xb5, 0x00, 0xb5, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0x8b, 0x00, 0x8b, 0x00, 0x71, 0x00, 0x71, 0x00, 0x52, 0x00, 0x52, 0x00, 0x32, 0x00, 0x32, 0x00, 0x11, 0x00, 0x11, 0x00, 0xef, 0xff, 0xef, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0x84, 0xff, 0x84, 0xff, 0x63, 0xff, 0x63, 0xff, 0x43, 0xff, 0x43, 0xff, 0x26, 0xff, 0x26, 0xff, 0x0d, 0xff, 0x0d, 0xff, 0xf6, 0xfe, 0xf6, 0xfe, 0xe6, 0xfe, 0xe6, 0xfe, 0xdb, 0xfe, 0xdb, 0xfe, 0xd4, 0xfe, 0xd4, 0xfe, 0xd3, 0xfe, 0xd3, 0xfe, 0xda, 0xfe, 0xda, 0xfe, 0xe9, 0xfe, 0xe9, 0xfe, 0xfd, 0xfe, 0xfd, 0xfe, 0x17, 0xff, 0x17, 0xff, 0x34, 0xff, 0x34, 0xff, 0x56, 0xff, 0x56, 0xff, 0x7c, 0xff, 0x7c, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0xce, 0xff, 0xce, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0x25, 0x00, 0x25, 0x00, 0x50, 0x00, 0x50, 0x00, 0x78, 0x00, 0x78, 0x00, 0x9f, 0x00, 0x9f, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf9, 0x00, 0xf9, 0x00, 0x0a, 0x01, 0x0a, 0x01, 0x16, 0x01, 0x16, 0x01, 0x1a, 0x01, 0x1a, 0x01, 0x18, 0x01, 0x18, 0x01, 0x13, 0x01, 0x13, 0x01, 0x07, 0x01, 0x07, 0x01, 0xf6, 0x00, 0xf6, 0x00, 0xdf, 0x00, 0xdf, 0x00, 0xc6, 0x00, 0xc6, 0x00, 0xab, 0x00, 0xab, 0x00, 0x8a, 0x00, 0x8a, 0x00, 0x62, 0x00, 0x62, 0x00, 0x37, 0x00, 0x37, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0xe1, 0xff, 0xe1, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0x98, 0xff, 0x98, 0xff, 0x78, 0xff, 0x78, 0xff, 0x5a, 0xff, 0x5a, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x29, 0xff, 0x29, 0xff, 0x18, 0xff, 0x18, 0xff, 0x0c, 0xff, 0x0c, 0xff, 0x04, 0xff, 0x04, 0xff, 0x02, 0xff, 0x02, 0xff, 0x08, 0xff, 0x08, 0xff, 0x17, 0xff, 0x17, 0xff, 0x2a, 0xff, 0x2a, 0xff, 0x40, 0xff, 0x40, 0xff, 0x58, 0xff, 0x58, 0xff, 0x73, 0xff, 0x73, 0xff, 0x8e, 0xff, 0x8e, 0xff, 0xab, 0xff, 0xab, 0xff, 0xca, 0xff, 0xca, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0x08, 0x00, 0x08, 0x00, 0x25, 0x00, 0x25, 0x00, 0x43, 0x00, 0x43, 0x00, 0x5e, 0x00, 0x5e, 0x00, 0x75, 0x00, 0x75, 0x00, 0x89, 0x00, 0x89, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xc7, 0x00, 0xc7, 0x00, 0xca, 0x00, 0xca, 0x00, 0xc9, 0x00, 0xc9, 0x00, 0xc2, 0x00, 0xc2, 0x00, 0xb9, 0x00, 0xb9, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0x94, 0x00, 0x94, 0x00, 0x82, 0x00, 0x82, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x54, 0x00, 0x54, 0x00, 0x39, 0x00, 0x39, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x01, 0x00, 0x01, 0x00, 0xe2, 0xff, 0xe2, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xa3, 0xff, 0xa3, 0xff, 0x85, 0xff, 0x85, 0xff, 0x68, 0xff, 0x68, 0xff, 0x4c, 0xff, 0x4c, 0xff, 0x34, 0xff, 0x34, 0xff, 0x21, 0xff, 0x21, 0xff, 0x13, 0xff, 0x13, 0xff, 0x08, 0xff, 0x08, 0xff, 0x03, 0xff, 0x03, 0xff, 0x01, 0xff, 0x01, 0xff, 0x00, 0xff, 0x00, 0xff, 0x03, 0xff, 0x03, 0xff, 0x0a, 0xff, 0x0a, 0xff, 0x15, 0xff, 0x15, 0xff, 0x23, 0xff, 0x23, 0xff, 0x36, 0xff, 0x36, 0xff, 0x4d, 0xff, 0x4d, 0xff, 0x68, 0xff, 0x68, 0xff, 0x85, 0xff, 0x85, 0xff, 0xa3, 0xff, 0xa3, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0x0a, 0x00, 0x0a, 0x00, 0x32, 0x00, 0x32, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x85, 0x00, 0x85, 0x00, 0xac, 0x00, 0xac, 0x00, 0xce, 0x00, 0xce, 0x00, 0xed, 0x00, 0xed, 0x00, 0x0b, 0x01, 0x0b, 0x01, 0x27, 0x01, 0x27, 0x01, 0x41, 0x01, 0x41, 0x01, 0x57, 0x01, 0x57, 0x01, 0x66, 0x01, 0x66, 0x01, 0x6f, 0x01, 0x6f, 0x01, 0x6f, 0x01, 0x6f, 0x01, 0x66, 0x01, 0x66, 0x01, 0x59, 0x01, 0x59, 0x01, 0x48, 0x01, 0x48, 0x01, 0x31, 0x01, 0x31, 0x01, 0x16, 0x01, 0x16, 0x01, 0xf5, 0x00, 0xf5, 0x00, 0xcd, 0x00, 0xcd, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0x74, 0x00, 0x74, 0x00, 0x43, 0x00, 0x43, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xda, 0xff, 0xda, 0xff, 0xa6, 0xff, 0xa6, 0xff, 0x74, 0xff, 0x74, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x0b, 0xff, 0x0b, 0xff, 0xdd, 0xfe, 0xdd, 0xfe, 0xb6, 0xfe, 0xb6, 0xfe, 0x95, 0xfe, 0x95, 0xfe, 0x77, 0xfe, 0x77, 0xfe, 0x5f, 0xfe, 0x5f, 0xfe, 0x4e, 0xfe, 0x4e, 0xfe, 0x43, 0xfe, 0x43, 0xfe, 0x3d, 0xfe, 0x3d, 0xfe, 0x41, 0xfe, 0x41, 0xfe, 0x4c, 0xfe, 0x4c, 0xfe, 0x5f, 0xfe, 0x5f, 0xfe, 0x7a, 0xfe, 0x7a, 0xfe, 0x9e, 0xfe, 0x9e, 0xfe, 0xcb, 0xfe, 0xcb, 0xfe, 0xfc, 0xfe, 0xfc, 0xfe, 0x31, 0xff, 0x31, 0xff, 0x6a, 0xff, 0x6a, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0x27, 0x00, 0x27, 0x00, 0x65, 0x00, 0x65, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0xdc, 0x00, 0xdc, 0x00, 0x12, 0x01, 0x12, 0x01, 0x43, 0x01, 0x43, 0x01, 0x6d, 0x01, 0x6d, 0x01, 0x8e, 0x01, 0x8e, 0x01, 0xa9, 0x01, 0xa9, 0x01, 0xbe, 0x01, 0xbe, 0x01, 0xcb, 0x01, 0xcb, 0x01, 0xd0, 0x01, 0xd0, 0x01, 0xcd, 0x01, 0xcd, 0x01, 0xc1, 0x01, 0xc1, 0x01, 0xad, 0x01, 0xad, 0x01, 0x91, 0x01, 0x91, 0x01, 0x6d, 0x01, 0x6d, 0x01, 0x42, 0x01, 0x42, 0x01, 0x11, 0x01, 0x11, 0x01, 0xda, 0x00, 0xda, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0x66, 0x00, 0x66, 0x00, 0x29, 0x00, 0x29, 0x00, 0xee, 0xff, 0xee, 0xff, 0xb4, 0xff, 0xb4, 0xff, 0x7a, 0xff, 0x7a, 0xff, 0x45, 0xff, 0x45, 0xff, 0x14, 0xff, 0x14, 0xff, 0xea, 0xfe, 0xea, 0xfe, 0xc8, 0xfe, 0xc8, 0xfe, 0xad, 0xfe, 0xad, 0xfe, 0x9d, 0xfe, 0x9d, 0xfe, 0x94, 0xfe, 0x94, 0xfe, 0x8f, 0xfe, 0x8f, 0xfe, 0x91, 0xfe, 0x91, 0xfe, 0x9e, 0xfe, 0x9e, 0xfe, 0xb4, 0xfe, 0xb4, 0xfe, 0xcd, 0xfe, 0xcd, 0xfe, 0xeb, 0xfe, 0xeb, 0xfe, 0x0c, 0xff, 0x0c, 0xff, 0x30, 0xff, 0x30, 0xff, 0x55, 0xff, 0x55, 0xff, 0x79, 0xff, 0x79, 0xff, 0xa0, 0xff, 0xa0, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0x1c, 0x00, 0x1c, 0x00, 0x45, 0x00, 0x45, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x8b, 0x00, 0x8b, 0x00, 0xa5, 0x00, 0xa5, 0x00, 0xbb, 0x00, 0xbb, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xd8, 0x00, 0xd8, 0x00, 0xdf, 0x00, 0xdf, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xdc, 0x00, 0xdc, 0x00, 0xd4, 0x00, 0xd4, 0x00, 0xc9, 0x00, 0xc9, 0x00, 0xba, 0x00, 0xba, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0x95, 0x00, 0x95, 0x00, 0x80, 0x00, 0x80, 0x00, 0x69, 0x00, 0x69, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x37, 0x00, 0x37, 0x00, 0x22, 0x00, 0x22, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xee, 0xff, 0xee, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xde, 0xff, 0xde, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xce, 0xff, 0xce, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xce, 0xff, 0xce, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xee, 0xff, 0xee, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0x02, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x10, 0x00, 0x15, 0x00, 0x15, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x20, 0x00, 0x20, 0x00, 0x23, 0x00, 0x23, 0x00, 0x25, 0x00, 0x25, 0x00, 0x23, 0x00, 0x23, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x14, 0x00, 0x14, 0x00, 0x09, 0x00, 0x09, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0xde, 0xff, 0xde, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xed, 0xff, 0xed, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0x01, 0x00, 0x01, 0x00, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x11, 0x00, 0x19, 0x00, 0x19, 0x00, 0x21, 0x00, 0x21, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x35, 0x00, 0x40, 0x00, 0x40, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x54, 0x00, 0x54, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x66, 0x00, 0x66, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x76, 0x00, 0x76, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0x81, 0x00, 0x81, 0x00, 0x80, 0x00, 0x80, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x74, 0x00, 0x74, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x63, 0x00, 0x63, 0x00, 0x57, 0x00, 0x57, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x39, 0x00, 0x39, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00, 0x01, 0x00, 0x01, 0x00, 0xef, 0xff, 0xef, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0xa5, 0xff, 0xa5, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0x97, 0xff, 0x97, 0xff, 0x92, 0xff, 0x92, 0xff, 0x8d, 0xff, 0x8d, 0xff, 0x88, 0xff, 0x88, 0xff, 0x84, 0xff, 0x84, 0xff, 0x83, 0xff, 0x83, 0xff, 0x84, 0xff, 0x84, 0xff, 0x89, 0xff, 0x89, 0xff, 0x92, 0xff, 0x92, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0xab, 0xff, 0xab, 0xff, 0xba, 0xff, 0xba, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0x0e, 0x00, 0x0e, 0x00, 0x21, 0x00, 0x21, 0x00, 0x33, 0x00, 0x33, 0x00, 0x42, 0x00, 0x42, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x58, 0x00, 0x58, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x60, 0x00, 0x5e, 0x00, 0x5e, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x52, 0x00, 0x52, 0x00, 0x47, 0x00, 0x47, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x30, 0x00, 0x30, 0x00, 0x22, 0x00, 0x22, 0x00, 0x14, 0x00, 0x14, 0x00, 0x04, 0x00, 0x04, 0x00, 0xf5, 0xff, 0xf5, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xca, 0xff, 0xca, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0xae, 0xff, 0xae, 0xff, 0xad, 0xff, 0xad, 0xff, 0xae, 0xff, 0xae, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x0a, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x15, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x28, 0x00, 0x28, 0x00, 0x31, 0x00, 0x31, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x46, 0x00, 0x46, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x49, 0x00, 0x49, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x34, 0x00, 0x34, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x20, 0x00, 0x20, 0x00, 0x14, 0x00, 0x14, 0x00, 0x06, 0x00, 0x06, 0x00, 0xfa, 0xff, 0xfa, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xca, 0xff, 0xca, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xda, 0xff, 0xda, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0xda, 0xff, 0xda, 0xff, 0xde, 0xff, 0xde, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xec, 0xff, 0xec, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0x03, 0x00, 0x03, 0x00, 0x10, 0x00, 0x10, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x22, 0x00, 0x22, 0x00, 0x29, 0x00, 0x29, 0x00, 0x32, 0x00, 0x32, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x45, 0x00, 0x45, 0x00, 0x49, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x49, 0x00, 0x49, 0x00, 0x44, 0x00, 0x44, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x32, 0x00, 0x32, 0x00, 0x23, 0x00, 0x23, 0x00, 0x10, 0x00, 0x10, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xec, 0xff, 0xec, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xc8, 0xff, 0xc8, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0xad, 0xff, 0xad, 0xff, 0xac, 0xff, 0xac, 0xff, 0xab, 0xff, 0xab, 0xff, 0xaa, 0xff, 0xaa, 0xff, 0xaa, 0xff, 0xaa, 0xff, 0xae, 0xff, 0xae, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xc8, 0xff, 0xc8, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0x06, 0x00, 0x06, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x35, 0x00, 0x35, 0x00, 0x46, 0x00, 0x46, 0x00, 0x54, 0x00, 0x54, 0x00, 0x62, 0x00, 0x62, 0x00, 0x73, 0x00, 0x73, 0x00, 0x81, 0x00, 0x81, 0x00, 0x8c, 0x00, 0x8c, 0x00, 0x92, 0x00, 0x92, 0x00, 0x91, 0x00, 0x91, 0x00, 0x8d, 0x00, 0x8d, 0x00, 0x85, 0x00, 0x85, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0x71, 0x00, 0x71, 0x00, 0x62, 0x00, 0x62, 0x00, 0x51, 0x00, 0x51, 0x00, 0x41, 0x00, 0x41, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x07, 0x00, 0x07, 0x00, 0xf0, 0xff, 0xf0, 0xff, 0xda, 0xff, 0xda, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0xa2, 0xff, 0xa2, 0xff, 0x91, 0xff, 0x91, 0xff, 0x83, 0xff, 0x83, 0xff, 0x77, 0xff, 0x77, 0xff, 0x6e, 0xff, 0x6e, 0xff, 0x67, 0xff, 0x67, 0xff, 0x62, 0xff, 0x62, 0xff, 0x63, 0xff, 0x63, 0xff, 0x69, 0xff, 0x69, 0xff, 0x6f, 0xff, 0x6f, 0xff, 0x76, 0xff, 0x76, 0xff, 0x80, 0xff, 0x80, 0xff, 0x8e, 0xff, 0x8e, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xed, 0xff, 0xed, 0xff, 0x06, 0x00, 0x06, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x32, 0x00, 0x32, 0x00, 0x44, 0x00, 0x44, 0x00, 0x55, 0x00, 0x55, 0x00, 0x67, 0x00, 0x67, 0x00, 0x78, 0x00, 0x78, 0x00, 0x86, 0x00, 0x86, 0x00, 0x91, 0x00, 0x91, 0x00, 0x98, 0x00, 0x98, 0x00, 0x9d, 0x00, 0x9d, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0xa1, 0x00, 0xa1, 0x00, 0x9d, 0x00, 0x9d, 0x00, 0x93, 0x00, 0x93, 0x00, 0x85, 0x00, 0x85, 0x00, 0x76, 0x00, 0x76, 0x00, 0x65, 0x00, 0x65, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x38, 0x00, 0x38, 0x00, 0x20, 0x00, 0x20, 0x00, 0x07, 0x00, 0x07, 0x00, 0xec, 0xff, 0xec, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0x99, 0xff, 0x99, 0xff, 0x8f, 0xff, 0x8f, 0xff, 0x89, 0xff, 0x89, 0xff, 0x85, 0xff, 0x85, 0xff, 0x81, 0xff, 0x81, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x80, 0xff, 0x80, 0xff, 0x85, 0xff, 0x85, 0xff, 0x8c, 0xff, 0x8c, 0xff, 0x95, 0xff, 0x95, 0xff, 0xa0, 0xff, 0xa0, 0xff, 0xad, 0xff, 0xad, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xde, 0xff, 0xde, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0x05, 0x00, 0x05, 0x00, 0x18, 0x00, 0x18, 0x00, 0x28, 0x00, 0x28, 0x00, 0x36, 0x00, 0x36, 0x00, 0x43, 0x00, 0x43, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x58, 0x00, 0x58, 0x00, 0x5e, 0x00, 0x5e, 0x00, 0x63, 0x00, 0x63, 0x00, 0x65, 0x00, 0x65, 0x00, 0x65, 0x00, 0x65, 0x00, 0x66, 0x00, 0x66, 0x00, 0x63, 0x00, 0x63, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x57, 0x00, 0x57, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x48, 0x00, 0x48, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x36, 0x00, 0x36, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xb7, 0xff, 0xb7, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xb4, 0xff, 0xb4, 0xff, 0xb4, 0xff, 0xb4, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xc8, 0xff, 0xc8, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0x07, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x14, 0x00, 0x18, 0x00, 0x18, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x22, 0x00, 0x22, 0x00, 0x28, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x33, 0x00, 0x33, 0x00, 0x39, 0x00, 0x39, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x44, 0x00, 0x44, 0x00, 0x46, 0x00, 0x46, 0x00, 0x44, 0x00, 0x44, 0x00, 0x40, 0x00, 0x40, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x34, 0x00, 0x34, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x22, 0x00, 0x22, 0x00, 0x16, 0x00, 0x16, 0x00, 0x09, 0x00, 0x09, 0x00, 0xfb, 0xff, 0xfb, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xad, 0xff, 0xad, 0xff, 0x9b, 0xff, 0x9b, 0xff, 0x8b, 0xff, 0x8b, 0xff, 0x7c, 0xff, 0x7c, 0xff, 0x6f, 0xff, 0x6f, 0xff, 0x66, 0xff, 0x66, 0xff, 0x5f, 0xff, 0x5f, 0xff, 0x5b, 0xff, 0x5b, 0xff, 0x5a, 0xff, 0x5a, 0xff, 0x5e, 0xff, 0x5e, 0xff, 0x65, 0xff, 0x65, 0xff, 0x70, 0xff, 0x70, 0xff, 0x7d, 0xff, 0x7d, 0xff, 0x8f, 0xff, 0x8f, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0xba, 0xff, 0xba, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xee, 0xff, 0xee, 0xff, 0x0e, 0x00, 0x0e, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x68, 0x00, 0x68, 0x00, 0x83, 0x00, 0x83, 0x00, 0x99, 0x00, 0x99, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xb8, 0x00, 0xb8, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcc, 0x00, 0xcc, 0x00, 0xc8, 0x00, 0xc8, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0x8e, 0x00, 0x8e, 0x00, 0x75, 0x00, 0x75, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x40, 0x00, 0x40, 0x00, 0x23, 0x00, 0x23, 0x00, 0x06, 0x00, 0x06, 0x00, 0xe6, 0xff, 0xe6, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0x8d, 0xff, 0x8d, 0xff, 0x74, 0xff, 0x74, 0xff, 0x60, 0xff, 0x60, 0xff, 0x51, 0xff, 0x51, 0xff, 0x48, 0xff, 0x48, 0xff, 0x44, 0xff, 0x44, 0xff, 0x43, 0xff, 0x43, 0xff, 0x48, 0xff, 0x48, 0xff, 0x53, 0xff, 0x53, 0xff, 0x65, 0xff, 0x65, 0xff, 0x7b, 0xff, 0x7b, 0xff, 0x95, 0xff, 0x95, 0xff, 0xb1, 0xff, 0xb1, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x19, 0x00, 0x30, 0x00, 0x30, 0x00, 0x45, 0x00, 0x45, 0x00, 0x55, 0x00, 0x55, 0x00, 0x63, 0x00, 0x63, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x72, 0x00, 0x72, 0x00, 0x70, 0x00, 0x70, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x60, 0x00, 0x60, 0x00, 0x55, 0x00, 0x55, 0x00, 0x48, 0x00, 0x48, 0x00, 0x38, 0x00, 0x38, 0x00, 0x27, 0x00, 0x27, 0x00, 0x16, 0x00, 0x16, 0x00, 0x03, 0x00, 0x03, 0x00, 0xed, 0xff, 0xed, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0x97, 0xff, 0x97, 0xff, 0x8c, 0xff, 0x8c, 0xff, 0x84, 0xff, 0x84, 0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0xff, 0x80, 0xff, 0x86, 0xff, 0x86, 0xff, 0x90, 0xff, 0x90, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xc8, 0xff, 0xc8, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0x01, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x38, 0x00, 0x38, 0x00, 0x51, 0x00, 0x51, 0x00, 0x67, 0x00, 0x67, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x8c, 0x00, 0x8c, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0xa7, 0x00, 0xa7, 0x00, 0xae, 0x00, 0xae, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0x98, 0x00, 0x98, 0x00, 0x8c, 0x00, 0x8c, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x57, 0x00, 0x57, 0x00, 0x41, 0x00, 0x41, 0x00, 0x26, 0x00, 0x26, 0x00, 0x09, 0x00, 0x09, 0x00, 0xee, 0xff, 0xee, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0x93, 0xff, 0x93, 0xff, 0x81, 0xff, 0x81, 0xff, 0x73, 0xff, 0x73, 0xff, 0x6a, 0xff, 0x6a, 0xff, 0x64, 0xff, 0x64, 0xff, 0x62, 0xff, 0x62, 0xff, 0x66, 0xff, 0x66, 0xff, 0x73, 0xff, 0x73, 0xff, 0x85, 0xff, 0x85, 0xff, 0x99, 0xff, 0x99, 0xff, 0xae, 0xff, 0xae, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xde, 0xff, 0xde, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0x12, 0x00, 0x12, 0x00, 0x29, 0x00, 0x29, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x66, 0x00, 0x66, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x64, 0x00, 0x64, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x52, 0x00, 0x52, 0x00, 0x44, 0x00, 0x44, 0x00, 0x33, 0x00, 0x33, 0x00, 0x20, 0x00, 0x20, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0xf3, 0xff, 0xf3, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0x99, 0xff, 0x99, 0xff, 0x86, 0xff, 0x86, 0xff, 0x75, 0xff, 0x75, 0xff, 0x68, 0xff, 0x68, 0xff, 0x60, 0xff, 0x60, 0xff, 0x5e, 0xff, 0x5e, 0xff, 0x62, 0xff, 0x62, 0xff, 0x6a, 0xff, 0x6a, 0xff, 0x74, 0xff, 0x74, 0xff, 0x82, 0xff, 0x82, 0xff, 0x92, 0xff, 0x92, 0xff, 0xa5, 0xff, 0xa5, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0x02, 0x00, 0x02, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x41, 0x00, 0x41, 0x00, 0x52, 0x00, 0x52, 0x00, 0x64, 0x00, 0x64, 0x00, 0x77, 0x00, 0x77, 0x00, 0x88, 0x00, 0x88, 0x00, 0x97, 0x00, 0x97, 0x00, 0xa4, 0x00, 0xa4, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0xb8, 0x00, 0xb8, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xb5, 0x00, 0xb5, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0x9b, 0x00, 0x9b, 0x00, 0x8a, 0x00, 0x8a, 0x00, 0x76, 0x00, 0x76, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x45, 0x00, 0x45, 0x00, 0x29, 0x00, 0x29, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0xf2, 0xff, 0xf2, 0xff, 0xda, 0xff, 0xda, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0x8c, 0xff, 0x8c, 0xff, 0x77, 0xff, 0x77, 0xff, 0x62, 0xff, 0x62, 0xff, 0x50, 0xff, 0x50, 0xff, 0x41, 0xff, 0x41, 0xff, 0x34, 0xff, 0x34, 0xff, 0x29, 0xff, 0x29, 0xff, 0x1e, 0xff, 0x1e, 0xff, 0x19, 0xff, 0x19, 0xff, 0x19, 0xff, 0x19, 0xff, 0x1c, 0xff, 0x1c, 0xff, 0x23, 0xff, 0x23, 0xff, 0x30, 0xff, 0x30, 0xff, 0x43, 0xff, 0x43, 0xff, 0x5b, 0xff, 0x5b, 0xff, 0x75, 0xff, 0x75, 0xff, 0x91, 0xff, 0x91, 0xff, 0xad, 0xff, 0xad, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0x0c, 0x00, 0x0c, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x66, 0x00, 0x66, 0x00, 0x7f, 0x00, 0x7f, 0x00, 0x97, 0x00, 0x97, 0x00, 0xab, 0x00, 0xab, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xca, 0x00, 0xca, 0x00, 0xd4, 0x00, 0xd4, 0x00, 0xda, 0x00, 0xda, 0x00, 0xde, 0x00, 0xde, 0x00, 0xdd, 0x00, 0xdd, 0x00, 0xd8, 0x00, 0xd8, 0x00, 0xcf, 0x00, 0xcf, 0x00, 0xc2, 0x00, 0xc2, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0x97, 0x00, 0x97, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x64, 0x00, 0x64, 0x00, 0x49, 0x00, 0x49, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x12, 0x00, 0x12, 0x00, 0xf6, 0xff, 0xf6, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xa3, 0xff, 0xa3, 0xff, 0x8d, 0xff, 0x8d, 0xff, 0x79, 0xff, 0x79, 0xff, 0x6a, 0xff, 0x6a, 0xff, 0x61, 0xff, 0x61, 0xff, 0x5a, 0xff, 0x5a, 0xff, 0x59, 0xff, 0x59, 0xff, 0x5a, 0xff, 0x5a, 0xff, 0x60, 0xff, 0x60, 0xff, 0x6a, 0xff, 0x6a, 0xff, 0x75, 0xff, 0x75, 0xff, 0x84, 0xff, 0x84, 0xff, 0x96, 0xff, 0x96, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xec, 0xff, 0xec, 0xff, 0x04, 0x00, 0x04, 0x00, 0x19, 0x00, 0x19, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x48, 0x00, 0x48, 0x00, 0x52, 0x00, 0x52, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x61, 0x00, 0x61, 0x00, 0x68, 0x00, 0x68, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x72, 0x00, 0x72, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x67, 0x00, 0x67, 0x00, 0x63, 0x00, 0x63, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x52, 0x00, 0x52, 0x00, 0x48, 0x00, 0x48, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x16, 0x00, 0x16, 0x00, 0x02, 0x00, 0x02, 0x00, 0xef, 0xff, 0xef, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xab, 0xff, 0xab, 0xff, 0xa0, 0xff, 0xa0, 0xff, 0x99, 0xff, 0x99, 0xff, 0x92, 0xff, 0x92, 0xff, 0x8c, 0xff, 0x8c, 0xff, 0x88, 0xff, 0x88, 0xff, 0x87, 0xff, 0x87, 0xff, 0x8a, 0xff, 0x8a, 0xff, 0x91, 0xff, 0x91, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0x06, 0x00, 0x06, 0x00, 0x14, 0x00, 0x14, 0x00, 0x23, 0x00, 0x23, 0x00, 0x32, 0x00, 0x32, 0x00, 0x41, 0x00, 0x41, 0x00, 0x4d, 0x00, 0x4d, 0x00, 0x58, 0x00, 0x58, 0x00, 0x62, 0x00, 0x62, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x70, 0x00, 0x70, 0x00, 0x74, 0x00, 0x74, 0x00, 0x76, 0x00, 0x76, 0x00, 0x72, 0x00, 0x72, 0x00, 0x69, 0x00, 0x69, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x15, 0x00, 0x15, 0x00, 0x03, 0x00, 0x03, 0x00, 0xf3, 0xff, 0xf3, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0x03, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x12, 0x00, 0x12, 0x00, 0x18, 0x00, 0x18, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x18, 0x00, 0x18, 0x00, 0x14, 0x00, 0x14, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x07, 0x00, 0x03, 0x00, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xec, 0xff, 0xec, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xde, 0xff, 0xde, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xec, 0xff, 0xec, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x38, 0x00, 0x38, 0x00, 0x40, 0x00, 0x40, 0x00, 0x47, 0x00, 0x47, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x52, 0x00, 0x52, 0x00, 0x54, 0x00, 0x54, 0x00, 0x52, 0x00, 0x52, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x42, 0x00, 0x42, 0x00, 0x37, 0x00, 0x37, 0x00, 0x27, 0x00, 0x27, 0x00, 0x14, 0x00, 0x14, 0x00, 0x01, 0x00, 0x01, 0x00, 0xf3, 0xff, 0xf3, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0xba, 0xff, 0xba, 0xff, 0xb6, 0xff, 0xb6, 0xff, 0xb4, 0xff, 0xb4, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xce, 0xff, 0xce, 0xff, 0xda, 0xff, 0xda, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, 0x00, 0x11, 0x00, 0x24, 0x00, 0x24, 0x00, 0x36, 0x00, 0x36, 0x00, 0x46, 0x00, 0x46, 0x00, 0x54, 0x00, 0x54, 0x00, 0x60, 0x00, 0x60, 0x00, 0x69, 0x00, 0x69, 0x00, 0x72, 0x00, 0x72, 0x00, 0x78, 0x00, 0x78, 0x00, 0x79, 0x00, 0x79, 0x00, 0x77, 0x00, 0x77, 0x00, 0x74, 0x00, 0x74, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x28, 0x00, 0x28, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xff, 0xec, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xad, 0xff, 0xad, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0x91, 0xff, 0x91, 0xff, 0x85, 0xff, 0x85, 0xff, 0x7b, 0xff, 0x7b, 0xff, 0x76, 0xff, 0x76, 0xff, 0x75, 0xff, 0x75, 0xff, 0x79, 0xff, 0x79, 0xff, 0x80, 0xff, 0x80, 0xff, 0x88, 0xff, 0x88, 0xff, 0x92, 0xff, 0x92, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0xad, 0xff, 0xad, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xef, 0xff, 0xef, 0xff, 0x03, 0x00, 0x03, 0x00, 0x14, 0x00, 0x14, 0x00, 0x25, 0x00, 0x25, 0x00, 0x32, 0x00, 0x32, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x47, 0x00, 0x47, 0x00, 0x50, 0x00, 0x50, 0x00, 0x56, 0x00, 0x56, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x64, 0x00, 0x64, 0x00, 0x67, 0x00, 0x67, 0x00, 0x65, 0x00, 0x65, 0x00, 0x61, 0x00, 0x61, 0x00, 0x59, 0x00, 0x59, 0x00, 0x50, 0x00, 0x50, 0x00, 0x48, 0x00, 0x48, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x35, 0x00, 0x35, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x23, 0x00, 0x23, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x18, 0x00, 0x18, 0x00, 0x10, 0x00, 0x10, 0x00, 0x09, 0x00, 0x09, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0xfb, 0xff, 0xfb, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xee, 0xff, 0xee, 0xff, 0xec, 0xff, 0xec, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xda, 0xff, 0xda, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xc4, 0xff, 0xc4, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xda, 0xff, 0xda, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xec, 0xff, 0xec, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0x07, 0x00, 0x07, 0x00, 0x12, 0x00, 0x12, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x26, 0x00, 0x26, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x30, 0x00, 0x30, 0x00, 0x34, 0x00, 0x34, 0x00, 0x39, 0x00, 0x39, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x35, 0x00, 0x35, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x11, 0x00, 0x11, 0x00, 0x06, 0x00, 0x06, 0x00, 0xf8, 0xff, 0xf8, 0xff, 0xea, 0xff, 0xea, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xce, 0xff, 0xce, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0x02, 0x00, 0x02, 0x00, 0x14, 0x00, 0x14, 0x00, 0x24, 0x00, 0x24, 0x00, 0x31, 0x00, 0x31, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x46, 0x00, 0x46, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x51, 0x00, 0x51, 0x00, 0x55, 0x00, 0x55, 0x00, 0x57, 0x00, 0x57, 0x00, 0x54, 0x00, 0x54, 0x00, 0x50, 0x00, 0x50, 0x00, 0x48, 0x00, 0x48, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x30, 0x00, 0x30, 0x00, 0x22, 0x00, 0x22, 0x00, 0x14, 0x00, 0x14, 0x00, 0x04, 0x00, 0x04, 0x00, 0xf3, 0xff, 0xf3, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xac, 0xff, 0xac, 0xff, 0x9f, 0xff, 0x9f, 0xff, 0x91, 0xff, 0x91, 0xff, 0x86, 0xff, 0x86, 0xff, 0x7d, 0xff, 0x7d, 0xff, 0x79, 0xff, 0x79, 0xff, 0x79, 0xff, 0x79, 0xff, 0x7a, 0xff, 0x7a, 0xff, 0x7d, 0xff, 0x7d, 0xff, 0x84, 0xff, 0x84, 0xff, 0x90, 0xff, 0x90, 0xff, 0x9f, 0xff, 0x9f, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xde, 0xff, 0xde, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0x0c, 0x00, 0x0c, 0x00, 0x21, 0x00, 0x21, 0x00, 0x34, 0x00, 0x34, 0x00, 0x46, 0x00, 0x46, 0x00, 0x59, 0x00, 0x59, 0x00, 0x67, 0x00, 0x67, 0x00, 0x73, 0x00, 0x73, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x85, 0x00, 0x85, 0x00, 0x8b, 0x00, 0x8b, 0x00, 0x8d, 0x00, 0x8d, 0x00, 0x8d, 0x00, 0x8d, 0x00, 0x8a, 0x00, 0x8a, 0x00, 0x85, 0x00, 0x85, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x73, 0x00, 0x73, 0x00, 0x65, 0x00, 0x65, 0x00, 0x54, 0x00, 0x54, 0x00, 0x45, 0x00, 0x45, 0x00, 0x36, 0x00, 0x36, 0x00, 0x26, 0x00, 0x26, 0x00, 0x13, 0x00, 0x13, 0x00, 0x01, 0x00, 0x01, 0x00, 0xef, 0xff, 0xef, 0xff, 0xde, 0xff, 0xde, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xae, 0xff, 0xae, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0x97, 0xff, 0x97, 0xff, 0x8f, 0xff, 0x8f, 0xff, 0x88, 0xff, 0x88, 0xff, 0x83, 0xff, 0x83, 0xff, 0x84, 0xff, 0x84, 0xff, 0x8b, 0xff, 0x8b, 0xff, 0x95, 0xff, 0x95, 0xff, 0x9b, 0xff, 0x9b, 0xff, 0xa3, 0xff, 0xa3, 0xff, 0xad, 0xff, 0xad, 0xff, 0xba, 0xff, 0xba, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xea, 0xff, 0xea, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0x09, 0x00, 0x09, 0x00, 0x18, 0x00, 0x18, 0x00, 0x26, 0x00, 0x26, 0x00, 0x31, 0x00, 0x31, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x42, 0x00, 0x42, 0x00, 0x46, 0x00, 0x46, 0x00, 0x47, 0x00, 0x47, 0x00, 0x47, 0x00, 0x47, 0x00, 0x49, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x48, 0x00, 0x48, 0x00, 0x46, 0x00, 0x46, 0x00, 0x42, 0x00, 0x42, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x34, 0x00, 0x34, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x23, 0x00, 0x23, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x14, 0x00, 0x14, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xee, 0xff, 0xee, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xce, 0xff, 0xce, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xca, 0xff, 0xca, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0x09, 0x00, 0x09, 0x00, 0x11, 0x00, 0x11, 0x00, 0x16, 0x00, 0x16, 0x00, 0x19, 0x00, 0x19, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x20, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x20, 0x00, 0x21, 0x00, 0x21, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x17, 0x00, 0x11, 0x00, 0x11, 0x00, 0x09, 0x00, 0x09, 0x00, 0x03, 0x00, 0x03, 0x00, 0xfb, 0xff, 0xfb, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xda, 0xff, 0xda, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xea, 0xff, 0xea, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x05, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x12, 0x00, 0x12, 0x00, 0x13, 0x00, 0x13, 0x00, 0x14, 0x00, 0x14, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x16, 0x00, 0x14, 0x00, 0x14, 0x00, 0x11, 0x00, 0x11, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x05, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x00, 0xfe, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xec, 0xff, 0xec, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0xed, 0xff, 0xed, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x11, 0x00, 0x11, 0x00, 0x15, 0x00, 0x15, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x20, 0x00, 0x20, 0x00, 0x27, 0x00, 0x27, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x33, 0x00, 0x33, 0x00, 0x39, 0x00, 0x39, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x38, 0x00, 0x38, 0x00, 0x31, 0x00, 0x31, 0x00, 0x28, 0x00, 0x28, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x12, 0x00, 0x12, 0x00, 0x09, 0x00, 0x09, 0x00, 0x01, 0x00, 0x01, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xef, 0xff, 0xef, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0xa2, 0xff, 0xa2, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0xa2, 0xff, 0xa2, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0xae, 0xff, 0xae, 0xff, 0xb6, 0xff, 0xb6, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xda, 0xff, 0xda, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0x08, 0x00, 0x08, 0x00, 0x19, 0x00, 0x19, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x4d, 0x00, 0x4d, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0x86, 0x00, 0x86, 0x00, 0x8e, 0x00, 0x8e, 0x00, 0x92, 0x00, 0x92, 0x00, 0x94, 0x00, 0x94, 0x00, 0x91, 0x00, 0x91, 0x00, 0x8a, 0x00, 0x8a, 0x00, 0x80, 0x00, 0x80, 0x00, 0x73, 0x00, 0x73, 0x00, 0x64, 0x00, 0x64, 0x00, 0x52, 0x00, 0x52, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x18, 0x00, 0x18, 0x00, 0x02, 0x00, 0x02, 0x00, 0xeb, 0xff, 0xeb, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xba, 0xff, 0xba, 0xff, 0xa6, 0xff, 0xa6, 0xff, 0x95, 0xff, 0x95, 0xff, 0x87, 0xff, 0x87, 0xff, 0x79, 0xff, 0x79, 0xff, 0x6d, 0xff, 0x6d, 0xff, 0x68, 0xff, 0x68, 0xff, 0x69, 0xff, 0x69, 0xff, 0x6e, 0xff, 0x6e, 0xff, 0x75, 0xff, 0x75, 0xff, 0x7e, 0xff, 0x7e, 0xff, 0x8d, 0xff, 0x8d, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xea, 0xff, 0xea, 0xff, 0x02, 0x00, 0x02, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x35, 0x00, 0x35, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x66, 0x00, 0x66, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0x8b, 0x00, 0x8b, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0xa5, 0x00, 0xa5, 0x00, 0xab, 0x00, 0xab, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0x98, 0x00, 0x98, 0x00, 0x8d, 0x00, 0x8d, 0x00, 0x81, 0x00, 0x81, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x43, 0x00, 0x43, 0x00, 0x28, 0x00, 0x28, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0xf5, 0xff, 0xf5, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xc4, 0xff, 0xc4, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0x8d, 0xff, 0x8d, 0xff, 0x7a, 0xff, 0x7a, 0xff, 0x6b, 0xff, 0x6b, 0xff, 0x60, 0xff, 0x60, 0xff, 0x5a, 0xff, 0x5a, 0xff, 0x57, 0xff, 0x57, 0xff, 0x59, 0xff, 0x59, 0xff, 0x62, 0xff, 0x62, 0xff, 0x71, 0xff, 0x71, 0xff, 0x83, 0xff, 0x83, 0xff, 0x95, 0xff, 0x95, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0x0d, 0x00, 0x0d, 0x00, 0x27, 0x00, 0x27, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x55, 0x00, 0x55, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x88, 0x00, 0x88, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xb3, 0x00, 0xb3, 0x00, 0xb7, 0x00, 0xb7, 0x00, 0xb6, 0x00, 0xb6, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0xa1, 0x00, 0xa1, 0x00, 0x8c, 0x00, 0x8c, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x52, 0x00, 0x52, 0x00, 0x35, 0x00, 0x35, 0x00, 0x19, 0x00, 0x19, 0x00, 0xff, 0xff, 0xff, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xb4, 0xff, 0xb4, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0x8b, 0xff, 0x8b, 0xff, 0x7b, 0xff, 0x7b, 0xff, 0x6b, 0xff, 0x6b, 0xff, 0x5d, 0xff, 0x5d, 0xff, 0x50, 0xff, 0x50, 0xff, 0x48, 0xff, 0x48, 0xff, 0x49, 0xff, 0x49, 0xff, 0x4f, 0xff, 0x4f, 0xff, 0x5b, 0xff, 0x5b, 0xff, 0x69, 0xff, 0x69, 0xff, 0x78, 0xff, 0x78, 0xff, 0x8d, 0xff, 0x8d, 0xff, 0xa6, 0xff, 0xa6, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x1d, 0x00, 0x1d, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x58, 0x00, 0x58, 0x00, 0x72, 0x00, 0x72, 0x00, 0x88, 0x00, 0x88, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0xa6, 0x00, 0xa6, 0x00, 0xb0, 0x00, 0xb0, 0x00, 0xb6, 0x00, 0xb6, 0x00, 0xb8, 0x00, 0xb8, 0x00, 0xb5, 0x00, 0xb5, 0x00, 0xae, 0x00, 0xae, 0x00, 0xa1, 0x00, 0xa1, 0x00, 0x8f, 0x00, 0x8f, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x67, 0x00, 0x67, 0x00, 0x51, 0x00, 0x51, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x26, 0x00, 0x26, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0xf1, 0xff, 0xf1, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xba, 0xff, 0xba, 0xff, 0xa2, 0xff, 0xa2, 0xff, 0x8b, 0xff, 0x8b, 0xff, 0x77, 0xff, 0x77, 0xff, 0x68, 0xff, 0x68, 0xff, 0x5c, 0xff, 0x5c, 0xff, 0x52, 0xff, 0x52, 0xff, 0x4b, 0xff, 0x4b, 0xff, 0x48, 0xff, 0x48, 0xff, 0x4b, 0xff, 0x4b, 0xff, 0x51, 0xff, 0x51, 0xff, 0x5c, 0xff, 0x5c, 0xff, 0x69, 0xff, 0x69, 0xff, 0x79, 0xff, 0x79, 0xff, 0x8d, 0xff, 0x8d, 0xff, 0xa2, 0xff, 0xa2, 0xff, 0xba, 0xff, 0xba, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0x0e, 0x00, 0x0e, 0x00, 0x28, 0x00, 0x28, 0x00, 0x41, 0x00, 0x41, 0x00, 0x59, 0x00, 0x59, 0x00, 0x71, 0x00, 0x71, 0x00, 0x85, 0x00, 0x85, 0x00, 0x95, 0x00, 0x95, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0xac, 0x00, 0xac, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xa3, 0x00, 0xa3, 0x00, 0x98, 0x00, 0x98, 0x00, 0x88, 0x00, 0x88, 0x00, 0x77, 0x00, 0x77, 0x00, 0x65, 0x00, 0x65, 0x00, 0x52, 0x00, 0x52, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x23, 0x00, 0x23, 0x00, 0x09, 0x00, 0x09, 0x00, 0xee, 0xff, 0xee, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0x9b, 0xff, 0x9b, 0xff, 0x91, 0xff, 0x91, 0xff, 0x89, 0xff, 0x89, 0xff, 0x87, 0xff, 0x87, 0xff, 0x86, 0xff, 0x86, 0xff, 0x84, 0xff, 0x84, 0xff, 0x83, 0xff, 0x83, 0xff, 0x86, 0xff, 0x86, 0xff, 0x8d, 0xff, 0x8d, 0xff, 0x98, 0xff, 0x98, 0xff, 0xa5, 0xff, 0xa5, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xed, 0xff, 0xed, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x0d, 0x00, 0x0d, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x29, 0x00, 0x29, 0x00, 0x33, 0x00, 0x33, 0x00, 0x39, 0x00, 0x39, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x38, 0x00, 0x38, 0x00, 0x33, 0x00, 0x33, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x24, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x16, 0x00, 0x16, 0x00, 0x10, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x08, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0x02, 0x00, 0x02, 0x00, 0x05, 0x00, 0x05, 0x00, 0x09, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x09, 0x00, 0x02, 0x00, 0x02, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xde, 0xff, 0xde, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xea, 0xff, 0xea, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x07, 0x00, 0x07, 0x00, 0x10, 0x00, 0x10, 0x00, 0x18, 0x00, 0x18, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x24, 0x00, 0x24, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x34, 0x00, 0x34, 0x00, 0x39, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x37, 0x00, 0x37, 0x00, 0x35, 0x00, 0x35, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x25, 0x00, 0x25, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x05, 0x00, 0x05, 0x00, 0xfb, 0xff, 0xfb, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xec, 0xff, 0xec, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xde, 0xff, 0xde, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xce, 0xff, 0xce, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0x03, 0x00, 0x03, 0x00, 0x11, 0x00, 0x11, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x22, 0x00, 0x22, 0x00, 0x28, 0x00, 0x28, 0x00, 0x30, 0x00, 0x30, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x43, 0x00, 0x43, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x53, 0x00, 0x53, 0x00, 0x59, 0x00, 0x59, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x60, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x54, 0x00, 0x54, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x43, 0x00, 0x43, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x30, 0x00, 0x30, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0xf9, 0xff, 0xf9, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xc8, 0xff, 0xc8, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0xa6, 0xff, 0xa6, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xec, 0xff, 0xec, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0x0d, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x00, 0x31, 0x00, 0x31, 0x00, 0x41, 0x00, 0x41, 0x00, 0x51, 0x00, 0x51, 0x00, 0x60, 0x00, 0x60, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0x85, 0x00, 0x85, 0x00, 0x8b, 0x00, 0x8b, 0x00, 0x8c, 0x00, 0x8c, 0x00, 0x88, 0x00, 0x88, 0x00, 0x80, 0x00, 0x80, 0x00, 0x75, 0x00, 0x75, 0x00, 0x65, 0x00, 0x65, 0x00, 0x52, 0x00, 0x52, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x21, 0x00, 0x21, 0x00, 0x07, 0x00, 0x07, 0x00, 0xed, 0xff, 0xed, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xa5, 0xff, 0xa5, 0xff, 0x8f, 0xff, 0x8f, 0xff, 0x7d, 0xff, 0x7d, 0xff, 0x70, 0xff, 0x70, 0xff, 0x68, 0xff, 0x68, 0xff, 0x64, 0xff, 0x64, 0xff, 0x62, 0xff, 0x62, 0xff, 0x65, 0xff, 0x65, 0xff, 0x6c, 0xff, 0x6c, 0xff, 0x79, 0xff, 0x79, 0xff, 0x8a, 0xff, 0x8a, 0xff, 0x9c, 0xff, 0x9c, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0xef, 0xff, 0xef, 0xff, 0x07, 0x00, 0x07, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x35, 0x00, 0x35, 0x00, 0x49, 0x00, 0x49, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x70, 0x00, 0x70, 0x00, 0x81, 0x00, 0x81, 0x00, 0x8e, 0x00, 0x8e, 0x00, 0x96, 0x00, 0x96, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9a, 0x00, 0x9b, 0x00, 0x9b, 0x00, 0x98, 0x00, 0x98, 0x00, 0x92, 0x00, 0x92, 0x00, 0x89, 0x00, 0x89, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x5e, 0x00, 0x5e, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x34, 0x00, 0x34, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x02, 0x00, 0x02, 0x00, 0xed, 0xff, 0xed, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0xa0, 0xff, 0xa0, 0xff, 0x90, 0xff, 0x90, 0xff, 0x83, 0xff, 0x83, 0xff, 0x7b, 0xff, 0x7b, 0xff, 0x76, 0xff, 0x76, 0xff, 0x76, 0xff, 0x76, 0xff, 0x77, 0xff, 0x77, 0xff, 0x7a, 0xff, 0x7a, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x8a, 0xff, 0x8a, 0xff, 0x99, 0xff, 0x99, 0xff, 0xab, 0xff, 0xab, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0x08, 0x00, 0x08, 0x00, 0x18, 0x00, 0x18, 0x00, 0x25, 0x00, 0x25, 0x00, 0x31, 0x00, 0x31, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x47, 0x00, 0x47, 0x00, 0x50, 0x00, 0x50, 0x00, 0x55, 0x00, 0x55, 0x00, 0x57, 0x00, 0x57, 0x00, 0x59, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x59, 0x00, 0x59, 0x00, 0x57, 0x00, 0x57, 0x00, 0x52, 0x00, 0x52, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x41, 0x00, 0x41, 0x00, 0x35, 0x00, 0x35, 0x00, 0x29, 0x00, 0x29, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xff, 0xf5, 0xff, 0xea, 0xff, 0xea, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xc4, 0xff, 0xc4, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xc4, 0xff, 0xc4, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xea, 0xff, 0xea, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0x01, 0x00, 0x01, 0x00, 0x07, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x17, 0x00, 0x17, 0x00, 0x23, 0x00, 0x23, 0x00, 0x30, 0x00, 0x30, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x45, 0x00, 0x45, 0x00, 0x48, 0x00, 0x48, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x48, 0x00, 0x48, 0x00, 0x43, 0x00, 0x43, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x39, 0x00, 0x39, 0x00, 0x36, 0x00, 0x36, 0x00, 0x32, 0x00, 0x32, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x22, 0x00, 0x22, 0x00, 0x17, 0x00, 0x17, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x04, 0x00, 0x04, 0x00, 0xfa, 0xff, 0xfa, 0xff, 0xed, 0xff, 0xed, 0xff, 0xde, 0xff, 0xde, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xba, 0xff, 0xba, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0x9a, 0xff, 0x9a, 0xff, 0x93, 0xff, 0x93, 0xff, 0x8f, 0xff, 0x8f, 0xff, 0x8f, 0xff, 0x8f, 0xff, 0x91, 0xff, 0x91, 0xff, 0x90, 0xff, 0x90, 0xff, 0x90, 0xff, 0x90, 0xff, 0x91, 0xff, 0x91, 0xff, 0x96, 0xff, 0x96, 0xff, 0xa0, 0xff, 0xa0, 0xff, 0xae, 0xff, 0xae, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0xca, 0xff, 0xca, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xea, 0xff, 0xea, 0xff, 0x01, 0x00, 0x01, 0x00, 0x18, 0x00, 0x18, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x66, 0x00, 0x66, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x73, 0x00, 0x73, 0x00, 0x76, 0x00, 0x76, 0x00, 0x75, 0x00, 0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x62, 0x00, 0x62, 0x00, 0x58, 0x00, 0x58, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xff, 0xff, 0xff, 0xff, 0xee, 0xff, 0xee, 0xff, 0xde, 0xff, 0xde, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0x9a, 0xff, 0x9a, 0xff, 0x91, 0xff, 0x91, 0xff, 0x8d, 0xff, 0x8d, 0xff, 0x8c, 0xff, 0x8c, 0xff, 0x8f, 0xff, 0x8f, 0xff, 0x93, 0xff, 0x93, 0xff, 0x9b, 0xff, 0x9b, 0xff, 0xa5, 0xff, 0xa5, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0x03, 0x00, 0x03, 0x00, 0x13, 0x00, 0x13, 0x00, 0x22, 0x00, 0x22, 0x00, 0x31, 0x00, 0x31, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x45, 0x00, 0x45, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x4d, 0x00, 0x4d, 0x00, 0x4d, 0x00, 0x4d, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x46, 0x00, 0x46, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x14, 0x00, 0x14, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0xfe, 0xff, 0xfe, 0xff, 0xee, 0xff, 0xee, 0xff, 0xde, 0xff, 0xde, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0xb1, 0xff, 0xb1, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xea, 0xff, 0xea, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0x0a, 0x00, 0x0a, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x64, 0x00, 0x64, 0x00, 0x69, 0x00, 0x69, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x68, 0x00, 0x68, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x47, 0x00, 0x47, 0x00, 0x34, 0x00, 0x34, 0x00, 0x24, 0x00, 0x24, 0x00, 0x14, 0x00, 0x14, 0x00, 0x01, 0x00, 0x01, 0x00, 0xed, 0xff, 0xed, 0xff, 0xda, 0xff, 0xda, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xba, 0xff, 0xba, 0xff, 0xae, 0xff, 0xae, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0x95, 0xff, 0x95, 0xff, 0x8b, 0xff, 0x8b, 0xff, 0x89, 0xff, 0x89, 0xff, 0x89, 0xff, 0x89, 0xff, 0x8b, 0xff, 0x8b, 0xff, 0x8e, 0xff, 0x8e, 0xff, 0x93, 0xff, 0x93, 0xff, 0x9a, 0xff, 0x9a, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0xb1, 0xff, 0xb1, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xca, 0xff, 0xca, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x13, 0x00, 0x13, 0x00, 0x26, 0x00, 0x26, 0x00, 0x37, 0x00, 0x37, 0x00, 0x47, 0x00, 0x47, 0x00, 0x58, 0x00, 0x58, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x77, 0x00, 0x77, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x80, 0x00, 0x80, 0x00, 0x7f, 0x00, 0x7f, 0x00, 0x7a, 0x00, 0x7a, 0x00, 0x75, 0x00, 0x75, 0x00, 0x71, 0x00, 0x71, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x32, 0x00, 0x32, 0x00, 0x25, 0x00, 0x25, 0x00, 0x16, 0x00, 0x16, 0x00, 0x07, 0x00, 0x07, 0x00, 0xf6, 0xff, 0xf6, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xaa, 0xff, 0xaa, 0xff, 0x9f, 0xff, 0x9f, 0xff, 0x99, 0xff, 0x99, 0xff, 0x99, 0xff, 0x99, 0xff, 0x9b, 0xff, 0x9b, 0xff, 0x9f, 0xff, 0x9f, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0xa3, 0xff, 0xa3, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0xae, 0xff, 0xae, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0x05, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x14, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x34, 0x00, 0x34, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x36, 0x00, 0x37, 0x00, 0x37, 0x00, 0x38, 0x00, 0x38, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x37, 0x00, 0x37, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x35, 0x00, 0x35, 0x00, 0x30, 0x00, 0x30, 0x00, 0x27, 0x00, 0x27, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x16, 0x00, 0x16, 0x00, 0x13, 0x00, 0x13, 0x00, 0x12, 0x00, 0x12, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x09, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x02, 0x00, 0x02, 0x00, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xec, 0xff, 0xec, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xde, 0xff, 0xde, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xde, 0xff, 0xde, 0xff, 0xde, 0xff, 0xde, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xda, 0xff, 0xda, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xda, 0xff, 0xda, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xec, 0xff, 0xec, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0x05, 0x00, 0x05, 0x00, 0x12, 0x00, 0x12, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x22, 0x00, 0x22, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x34, 0x00, 0x34, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x39, 0x00, 0x39, 0x00, 0x33, 0x00, 0x33, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x26, 0x00, 0x26, 0x00, 0x23, 0x00, 0x23, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x15, 0x00, 0x15, 0x00, 0x10, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x09, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xff, 0xfb, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xef, 0xff, 0xef, 0xff, 0xee, 0xff, 0xee, 0xff, 0xef, 0xff, 0xef, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x03, 0x00, 0x06, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x18, 0x00, 0x23, 0x00, 0x23, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x35, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x48, 0x00, 0x48, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x52, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x48, 0x00, 0x48, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x33, 0x00, 0x33, 0x00, 0x26, 0x00, 0x26, 0x00, 0x18, 0x00, 0x18, 0x00, 0x06, 0x00, 0x06, 0x00, 0xf4, 0xff, 0xf4, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xb6, 0xff, 0xb6, 0xff, 0xaa, 0xff, 0xaa, 0xff, 0xa2, 0xff, 0xa2, 0xff, 0x9f, 0xff, 0x9f, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0xb7, 0xff, 0xb7, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xce, 0xff, 0xce, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0x05, 0x00, 0x05, 0x00, 0x15, 0x00, 0x15, 0x00, 0x22, 0x00, 0x22, 0x00, 0x30, 0x00, 0x30, 0x00, 0x40, 0x00, 0x40, 0x00, 0x51, 0x00, 0x51, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x66, 0x00, 0x66, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x67, 0x00, 0x67, 0x00, 0x60, 0x00, 0x60, 0x00, 0x59, 0x00, 0x59, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x44, 0x00, 0x44, 0x00, 0x39, 0x00, 0x39, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x14, 0x00, 0x14, 0x00, 0x09, 0x00, 0x09, 0x00, 0xfc, 0xff, 0xfc, 0xff, 0xed, 0xff, 0xed, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0x97, 0xff, 0x97, 0xff, 0x85, 0xff, 0x85, 0xff, 0x74, 0xff, 0x74, 0xff, 0x69, 0xff, 0x69, 0xff, 0x63, 0xff, 0x63, 0xff, 0x5f, 0xff, 0x5f, 0xff, 0x5f, 0xff, 0x5f, 0xff, 0x62, 0xff, 0x62, 0xff, 0x69, 0xff, 0x69, 0xff, 0x73, 0xff, 0x73, 0xff, 0x81, 0xff, 0x81, 0xff, 0x93, 0xff, 0x93, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xee, 0xff, 0xee, 0xff, 0x07, 0x00, 0x07, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x42, 0x00, 0x42, 0x00, 0x55, 0x00, 0x55, 0x00, 0x67, 0x00, 0x67, 0x00, 0x76, 0x00, 0x76, 0x00, 0x84, 0x00, 0x84, 0x00, 0x8d, 0x00, 0x8d, 0x00, 0x95, 0x00, 0x95, 0x00, 0x9b, 0x00, 0x9b, 0x00, 0x9f, 0x00, 0x9f, 0x00, 0xa2, 0x00, 0xa2, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0x96, 0x00, 0x96, 0x00, 0x88, 0x00, 0x88, 0x00, 0x75, 0x00, 0x75, 0x00, 0x61, 0x00, 0x61, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x25, 0x00, 0x25, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0xf5, 0xff, 0xf5, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0x97, 0xff, 0x97, 0xff, 0x89, 0xff, 0x89, 0xff, 0x80, 0xff, 0x80, 0xff, 0x7a, 0xff, 0x7a, 0xff, 0x79, 0xff, 0x79, 0xff, 0x7a, 0xff, 0x7a, 0xff, 0x7d, 0xff, 0x7d, 0xff, 0x82, 0xff, 0x82, 0xff, 0x89, 0xff, 0x89, 0xff, 0x91, 0xff, 0x91, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0xac, 0xff, 0xac, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0x0c, 0x00, 0x0c, 0x00, 0x20, 0x00, 0x20, 0x00, 0x31, 0x00, 0x31, 0x00, 0x40, 0x00, 0x40, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x54, 0x00, 0x54, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x60, 0x00, 0x60, 0x00, 0x65, 0x00, 0x65, 0x00, 0x67, 0x00, 0x67, 0x00, 0x66, 0x00, 0x66, 0x00, 0x62, 0x00, 0x62, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x54, 0x00, 0x54, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x30, 0x00, 0x30, 0x00, 0x24, 0x00, 0x24, 0x00, 0x16, 0x00, 0x16, 0x00, 0x06, 0x00, 0x06, 0x00, 0xf6, 0xff, 0xf6, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xb7, 0xff, 0xb7, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0xac, 0xff, 0xac, 0xff, 0xae, 0xff, 0xae, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xda, 0xff, 0xda, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0x02, 0x00, 0x02, 0x00, 0x10, 0x00, 0x10, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x35, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x44, 0x00, 0x44, 0x00, 0x4a, 0x00, 0x4a, 0x00, 0x51, 0x00, 0x51, 0x00, 0x56, 0x00, 0x56, 0x00, 0x58, 0x00, 0x58, 0x00, 0x55, 0x00, 0x55, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x45, 0x00, 0x45, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x34, 0x00, 0x34, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x10, 0x00, 0x10, 0x00, 0x03, 0x00, 0x03, 0x00, 0xf5, 0xff, 0xf5, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xc4, 0xff, 0xc4, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xba, 0xff, 0xba, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xce, 0xff, 0xce, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xed, 0xff, 0xed, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x08, 0x00, 0x08, 0x00, 0x12, 0x00, 0x12, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x20, 0x00, 0x20, 0x00, 0x25, 0x00, 0x25, 0x00, 0x29, 0x00, 0x29, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x26, 0x00, 0x26, 0x00, 0x20, 0x00, 0x20, 0x00, 0x18, 0x00, 0x18, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x05, 0x00, 0x05, 0x00, 0xfc, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xde, 0xff, 0xde, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xde, 0xff, 0xde, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0xef, 0xff, 0xef, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0x03, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x12, 0x00, 0x12, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x21, 0x00, 0x21, 0x00, 0x26, 0x00, 0x26, 0x00, 0x29, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x29, 0x00, 0x29, 0x00, 0x27, 0x00, 0x27, 0x00, 0x24, 0x00, 0x24, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x14, 0x00, 0x14, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x09, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x07, 0x00, 0x02, 0x00, 0x02, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xed, 0xff, 0xed, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xda, 0xff, 0xda, 0xff, 0xda, 0xff, 0xda, 0xff, 0xda, 0xff, 0xda, 0xff, 0xda, 0xff, 0xda, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xde, 0xff, 0xde, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xed, 0xff, 0xed, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0x06, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x16, 0x00, 0x16, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x27, 0x00, 0x27, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x31, 0x00, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x22, 0x00, 0x22, 0x00, 0x16, 0x00, 0x16, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xba, 0xff, 0xba, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xbb, 0xff, 0xbb, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0x05, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x14, 0x00, 0x19, 0x00, 0x19, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x23, 0x00, 0x23, 0x00, 0x28, 0x00, 0x28, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x31, 0x00, 0x31, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x33, 0x00, 0x33, 0x00, 0x31, 0x00, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x27, 0x00, 0x27, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xec, 0xff, 0xec, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xc4, 0xff, 0xc4, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xc8, 0xff, 0xc8, 0xff, 0xca, 0xff, 0xca, 0xff, 0xca, 0xff, 0xca, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xce, 0xff, 0xce, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xee, 0xff, 0xee, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x03, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x11, 0x00, 0x11, 0x00, 0x14, 0x00, 0x14, 0x00, 0x19, 0x00, 0x19, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x21, 0x00, 0x21, 0x00, 0x24, 0x00, 0x24, 0x00, 0x26, 0x00, 0x26, 0x00, 0x29, 0x00, 0x29, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x30, 0x00, 0x30, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x28, 0x00, 0x28, 0x00, 0x26, 0x00, 0x26, 0x00, 0x26, 0x00, 0x26, 0x00, 0x25, 0x00, 0x25, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x18, 0x00, 0x18, 0x00, 0x10, 0x00, 0x10, 0x00, 0x08, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0xfa, 0xff, 0xfa, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xee, 0xff, 0xee, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xce, 0xff, 0xce, 0xff, 0xc8, 0xff, 0xc8, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0xba, 0xff, 0xba, 0xff, 0xb6, 0xff, 0xb6, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xb7, 0xff, 0xb7, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xee, 0xff, 0xee, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0x08, 0x00, 0x08, 0x00, 0x17, 0x00, 0x17, 0x00, 0x28, 0x00, 0x28, 0x00, 0x39, 0x00, 0x39, 0x00, 0x49, 0x00, 0x49, 0x00, 0x57, 0x00, 0x57, 0x00, 0x62, 0x00, 0x62, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x75, 0x00, 0x75, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0x78, 0x00, 0x78, 0x00, 0x71, 0x00, 0x71, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x60, 0x00, 0x60, 0x00, 0x55, 0x00, 0x55, 0x00, 0x49, 0x00, 0x49, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xed, 0xff, 0xed, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xa8, 0xff, 0xa8, 0xff, 0x9f, 0xff, 0x9f, 0xff, 0x99, 0xff, 0x99, 0xff, 0x98, 0xff, 0x98, 0xff, 0x9a, 0xff, 0x9a, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0xa2, 0xff, 0xa2, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0x04, 0x00, 0x04, 0x00, 0x14, 0x00, 0x14, 0x00, 0x24, 0x00, 0x24, 0x00, 0x32, 0x00, 0x32, 0x00, 0x40, 0x00, 0x40, 0x00, 0x4d, 0x00, 0x4d, 0x00, 0x58, 0x00, 0x58, 0x00, 0x62, 0x00, 0x62, 0x00, 0x69, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x65, 0x00, 0x65, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x43, 0x00, 0x43, 0x00, 0x38, 0x00, 0x38, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0xfe, 0xff, 0xfe, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xb6, 0xff, 0xb6, 0xff, 0xb4, 0xff, 0xb4, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0xb2, 0xff, 0xb7, 0xff, 0xb7, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xc4, 0xff, 0xc4, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xde, 0xff, 0xde, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xec, 0xff, 0xec, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x04, 0x00, 0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x09, 0x00, 0x05, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x00, 0xfc, 0xff, 0xfc, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x11, 0x00, 0x11, 0x00, 0x12, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xed, 0xff, 0xed, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xde, 0xff, 0xde, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xbf, 0xff, 0xbf, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0xc4, 0xff, 0xc4, 0xff, 0xca, 0xff, 0xca, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xec, 0xff, 0xec, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0x06, 0x00, 0x06, 0x00, 0x12, 0x00, 0x12, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x34, 0x00, 0x34, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x46, 0x00, 0x46, 0x00, 0x4d, 0x00, 0x4d, 0x00, 0x54, 0x00, 0x54, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x64, 0x00, 0x64, 0x00, 0x67, 0x00, 0x67, 0x00, 0x68, 0x00, 0x68, 0x00, 0x65, 0x00, 0x65, 0x00, 0x61, 0x00, 0x61, 0x00, 0x5a, 0x00, 0x5a, 0x00, 0x54, 0x00, 0x54, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x45, 0x00, 0x45, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x24, 0x00, 0x24, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0xce, 0xff, 0xce, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xb9, 0xff, 0xb9, 0xff, 0xb1, 0xff, 0xb1, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0xa2, 0xff, 0xa2, 0xff, 0xa3, 0xff, 0xa3, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0xac, 0xff, 0xac, 0xff, 0xb1, 0xff, 0xb1, 0xff, 0xb7, 0xff, 0xb7, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0x06, 0x00, 0x06, 0x00, 0x12, 0x00, 0x12, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x28, 0x00, 0x28, 0x00, 0x32, 0x00, 0x32, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x42, 0x00, 0x42, 0x00, 0x49, 0x00, 0x49, 0x00, 0x50, 0x00, 0x50, 0x00, 0x58, 0x00, 0x58, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x58, 0x00, 0x58, 0x00, 0x55, 0x00, 0x55, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x45, 0x00, 0x45, 0x00, 0x39, 0x00, 0x39, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0xfb, 0xff, 0xfb, 0xff, 0xec, 0xff, 0xec, 0xff, 0xde, 0xff, 0xde, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xba, 0xff, 0xba, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0xa7, 0xff, 0xa7, 0xff, 0xa1, 0xff, 0xa1, 0xff, 0x9c, 0xff, 0x9c, 0xff, 0x98, 0xff, 0x98, 0xff, 0x93, 0xff, 0x93, 0xff, 0x92, 0xff, 0x92, 0xff, 0x97, 0xff, 0x97, 0xff, 0x9f, 0xff, 0x9f, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0x06, 0x00, 0x06, 0x00, 0x17, 0x00, 0x17, 0x00, 0x27, 0x00, 0x27, 0x00, 0x39, 0x00, 0x39, 0x00, 0x48, 0x00, 0x48, 0x00, 0x54, 0x00, 0x54, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x64, 0x00, 0x64, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x71, 0x00, 0x71, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x69, 0x00, 0x5e, 0x00, 0x5e, 0x00, 0x50, 0x00, 0x50, 0x00, 0x41, 0x00, 0x41, 0x00, 0x32, 0x00, 0x32, 0x00, 0x21, 0x00, 0x21, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0xc8, 0xff, 0xc8, 0xff, 0xb8, 0xff, 0xb8, 0xff, 0xab, 0xff, 0xab, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0x91, 0xff, 0x91, 0xff, 0x88, 0xff, 0x88, 0xff, 0x83, 0xff, 0x83, 0xff, 0x82, 0xff, 0x82, 0xff, 0x86, 0xff, 0x86, 0xff, 0x8b, 0xff, 0x8b, 0xff, 0x92, 0xff, 0x92, 0xff, 0x9f, 0xff, 0x9f, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0x08, 0x00, 0x08, 0x00, 0x15, 0x00, 0x15, 0x00, 0x21, 0x00, 0x21, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x37, 0x00, 0x37, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x48, 0x00, 0x48, 0x00, 0x50, 0x00, 0x50, 0x00, 0x56, 0x00, 0x56, 0x00, 0x58, 0x00, 0x58, 0x00, 0x57, 0x00, 0x57, 0x00, 0x55, 0x00, 0x55, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x43, 0x00, 0x43, 0x00, 0x34, 0x00, 0x34, 0x00, 0x24, 0x00, 0x24, 0x00, 0x15, 0x00, 0x15, 0x00, 0x04, 0x00, 0x04, 0x00, 0xf2, 0xff, 0xf2, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xbc, 0xff, 0xbc, 0xff, 0xb3, 0xff, 0xb3, 0xff, 0xab, 0xff, 0xab, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0x98, 0xff, 0x98, 0xff, 0x95, 0xff, 0x95, 0xff, 0x96, 0xff, 0x96, 0xff, 0x9b, 0xff, 0x9b, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0xb1, 0xff, 0xb1, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0x09, 0x00, 0x09, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x40, 0x00, 0x40, 0x00, 0x50, 0x00, 0x50, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x64, 0x00, 0x64, 0x00, 0x69, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x69, 0x00, 0x69, 0x00, 0x64, 0x00, 0x64, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x54, 0x00, 0x54, 0x00, 0x49, 0x00, 0x49, 0x00, 0x3d, 0x00, 0x3d, 0x00, 0x31, 0x00, 0x31, 0x00, 0x24, 0x00, 0x24, 0x00, 0x17, 0x00, 0x17, 0x00, 0x08, 0x00, 0x08, 0x00, 0xf9, 0xff, 0xf9, 0xff, 0xec, 0xff, 0xec, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xca, 0xff, 0xca, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xb7, 0xff, 0xb7, 0xff, 0xb0, 0xff, 0xb0, 0xff, 0xab, 0xff, 0xab, 0xff, 0xa5, 0xff, 0xa5, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0xa6, 0xff, 0xa6, 0xff, 0xa9, 0xff, 0xa9, 0xff, 0xaf, 0xff, 0xaf, 0xff, 0xb6, 0xff, 0xb6, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xce, 0xff, 0xce, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0x08, 0x00, 0x08, 0x00, 0x15, 0x00, 0x15, 0x00, 0x21, 0x00, 0x21, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x37, 0x00, 0x37, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x46, 0x00, 0x46, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x52, 0x00, 0x54, 0x00, 0x54, 0x00, 0x53, 0x00, 0x53, 0x00, 0x51, 0x00, 0x51, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x43, 0x00, 0x43, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x34, 0x00, 0x34, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x21, 0x00, 0x21, 0x00, 0x16, 0x00, 0x16, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x02, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xef, 0xff, 0xef, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xed, 0xff, 0xed, 0xff, 0xec, 0xff, 0xec, 0xff, 0xee, 0xff, 0xee, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xef, 0xff, 0xef, 0xff, 0xec, 0xff, 0xec, 0xff, 0xea, 0xff, 0xea, 0xff, 0xea, 0xff, 0xea, 0xff, 0xea, 0xff, 0xea, 0xff, 0xea, 0xff, 0xea, 0xff, 0xec, 0xff, 0xec, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0x01, 0x00, 0x01, 0x00, 0x07, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x15, 0x00, 0x15, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x20, 0x00, 0x20, 0x00, 0x24, 0x00, 0x24, 0x00, 0x27, 0x00, 0x27, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x28, 0x00, 0x28, 0x00, 0x27, 0x00, 0x27, 0x00, 0x26, 0x00, 0x26, 0x00, 0x23, 0x00, 0x23, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x16, 0x00, 0x16, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x05, 0x00, 0x05, 0x00, 0xfb, 0xff, 0xfb, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0xde, 0xff, 0xde, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xce, 0xff, 0xce, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xc3, 0xff, 0xc3, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xca, 0xff, 0xca, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xde, 0xff, 0xde, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x14, 0x00, 0x19, 0x00, 0x19, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x21, 0x00, 0x21, 0x00, 0x26, 0x00, 0x26, 0x00, 0x28, 0x00, 0x28, 0x00, 0x27, 0x00, 0x27, 0x00, 0x26, 0x00, 0x26, 0x00, 0x25, 0x00, 0x25, 0x00, 0x23, 0x00, 0x23, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x19, 0x00, 0x19, 0x00, 0x14, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xff, 0xf6, 0xff, 0xec, 0xff, 0xec, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0xda, 0xff, 0xda, 0xff, 0xde, 0xff, 0xde, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xef, 0xff, 0xef, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x09, 0x00, 0x10, 0x00, 0x10, 0x00, 0x16, 0x00, 0x16, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x26, 0x00, 0x26, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x35, 0x00, 0x37, 0x00, 0x37, 0x00, 0x36, 0x00, 0x36, 0x00, 0x31, 0x00, 0x31, 0x00, 0x29, 0x00, 0x29, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x17, 0x00, 0x17, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x02, 0x00, 0x02, 0x00, 0xf7, 0xff, 0xf7, 0xff, 0xec, 0xff, 0xec, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xd6, 0xff, 0xd6, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xc4, 0xff, 0xc4, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xed, 0xff, 0xed, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0x02, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x15, 0x00, 0x15, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x27, 0x00, 0x27, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x31, 0x00, 0x32, 0x00, 0x32, 0x00, 0x33, 0x00, 0x33, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x34, 0x00, 0x30, 0x00, 0x30, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x27, 0x00, 0x27, 0x00, 0x22, 0x00, 0x22, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x17, 0x00, 0x11, 0x00, 0x11, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x04, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xee, 0xff, 0xee, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xd8, 0xff, 0xd8, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xc2, 0xff, 0xc2, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0xc5, 0xff, 0xc5, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xec, 0xff, 0xec, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0x03, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x19, 0x00, 0x19, 0x00, 0x22, 0x00, 0x22, 0x00, 0x29, 0x00, 0x29, 0x00, 0x30, 0x00, 0x30, 0x00, 0x35, 0x00, 0x35, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x41, 0x00, 0x41, 0x00, 0x43, 0x00, 0x43, 0x00, 0x45, 0x00, 0x45, 0x00, 0x45, 0x00, 0x45, 0x00, 0x44, 0x00, 0x44, 0x00, 0x43, 0x00, 0x43, 0x00, 0x43, 0x00, 0x43, 0x00, 0x42, 0x00, 0x42, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x34, 0x00, 0x34, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x23, 0x00, 0x23, 0x00, 0x19, 0x00, 0x19, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xed, 0xff, 0xed, 0xff, 0xde, 0xff, 0xde, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xc6, 0xff, 0xc8, 0xff, 0xc8, 0xff, 0xca, 0xff, 0xca, 0xff, 0xce, 0xff, 0xce, 0xff, 0xd3, 0xff, 0xd3, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xea, 0xff, 0xea, 0xff, 0xef, 0xff, 0xef, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0x02, 0x00, 0x02, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x17, 0x00, 0x17, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x21, 0x00, 0x21, 0x00, 0x24, 0x00, 0x24, 0x00, 0x27, 0x00, 0x27, 0x00, 0x2a, 0x00, 0x2a, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x28, 0x00, 0x28, 0x00, 0x23, 0x00, 0x23, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x17, 0x00, 0x12, 0x00, 0x12, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x02, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x06, 0x00, 0x06, 0x00, 0x07, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0xec, 0xff, 0xec, 0xff, 0xee, 0xff, 0xee, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x09, 0x00, 0x09, 0x00, 0x10, 0x00, 0x10, 0x00, 0x15, 0x00, 0x15, 0x00, 0x18, 0x00, 0x18, 0x00, 0x19, 0x00, 0x19, 0x00, 0x18, 0x00, 0x18, 0x00, 0x17, 0x00, 0x17, 0x00, 0x16, 0x00, 0x16, 0x00, 0x14, 0x00, 0x14, 0x00, 0x13, 0x00, 0x13, 0x00, 0x13, 0x00, 0x13, 0x00, 0x10, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x07, 0x00, 0x07, 0x00, 0x03, 0x00, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xef, 0xff, 0xef, 0xff, 0xed, 0xff, 0xed, 0xff, 0xec, 0xff, 0xec, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xde, 0xff, 0xde, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xe3, 0xff, 0xe3, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0xea, 0xff, 0xea, 0xff, 0xef, 0xff, 0xef, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x03, 0x00, 0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x07, 0x00, 0x07, 0x00, 0x03, 0x00, 0x03, 0x00, 0xfb, 0xff, 0xfb, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xde, 0xff, 0xde, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xc8, 0xff, 0xc8, 0xff, 0xca, 0xff, 0xca, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xd9, 0xff, 0xd9, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xef, 0xff, 0xef, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0x01, 0x00, 0x01, 0x00, 0x09, 0x00, 0x09, 0x00, 0x14, 0x00, 0x14, 0x00, 0x23, 0x00, 0x23, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x31, 0x00, 0x31, 0x00, 0x30, 0x00, 0x30, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x25, 0x00, 0x25, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x13, 0x00, 0x13, 0x00, 0x08, 0x00, 0x08, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xef, 0xff, 0xef, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xd5, 0xff, 0xd5, 0xff, 0xce, 0xff, 0xce, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xcf, 0xff, 0xcf, 0xff, 0xd0, 0xff, 0xd0, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xd4, 0xff, 0xd4, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0x02, 0x00, 0x02, 0x00, 0x05, 0x00, 0x05, 0x00, 0x07, 0x00, 0x07, 0x00, 0x09, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x14, 0x00, 0x1a, 0x00, 0x1a, 0x00, 0x1d, 0x00, 0x1d, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x16, 0x00, 0x16, 0x00, 0x11, 0x00, 0x11, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xf8, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xed, 0xff, 0xed, 0xff, 0xea, 0xff, 0xea, 0xff, 0xea, 0xff, 0xea, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xca, 0xff, 0xca, 0xff, 0xd1, 0xff, 0xd1, 0xff, 0xde, 0xff, 0xde, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x15, 0x00, 0x15, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x47, 0x00, 0x47, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x55, 0x00, 0x55, 0x00, 0x59, 0x00, 0x59, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5c, 0x00, 0x5b, 0x00, 0x5b, 0x00, 0x58, 0x00, 0x58, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x45, 0x00, 0x45, 0x00, 0x41, 0x00, 0x41, 0x00, 0x42, 0x00, 0x42, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x42, 0x00, 0x42, 0x00, 0x49, 0x00, 0x49, 0x00, 0x42, 0x00, 0x42, 0x00, 0x39, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0x33, 0x00, 0x33, 0x00, 0x28, 0x00, 0x28, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x33, 0x00, 0x33, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x11, 0x00, 0x11, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x08, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xea, 0xff, 0xea, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0x04, 0x00, 0x04, 0x00, 0x18, 0x00, 0x18, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x28, 0x00, 0x28, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x59, 0x00, 0x59, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x75, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x66, 0x00, 0x74, 0x00, 0x74, 0x00, 0x87, 0x00, 0x87, 0x00, 0x81, 0x00, 0x81, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x69, 0x00, 0x6a, 0x00, 0x6a, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x74, 0x00, 0x65, 0x00, 0x65, 0x00, 0x51, 0x00, 0x51, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x50, 0x00, 0x45, 0x00, 0x45, 0x00, 0x37, 0x00, 0x37, 0x00, 0x21, 0x00, 0x21, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x15, 0x00, 0x15, 0x00, 0xfd, 0xff, 0xfd, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xee, 0xff, 0xee, 0xff, 0xec, 0xff, 0xec, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xec, 0xff, 0xec, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0x05, 0x00, 0x05, 0x00, 0xfe, 0xff, 0xfe, 0xff, 0x0b, 0x00, 0x0b, 0x00, 0x24, 0x00, 0x24, 0x00, 0x25, 0x00, 0x25, 0x00, 0x2c, 0x00, 0x2c, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x57, 0x00, 0x57, 0x00, 0x39, 0x00, 0x39, 0x00, 0x35, 0x00, 0x35, 0x00, 0x5d, 0x00, 0x5d, 0x00, 0x7f, 0x00, 0x7f, 0x00, 0x6b, 0x00, 0x6b, 0x00, 0x4e, 0x00, 0x4e, 0x00, 0x84, 0x00, 0x84, 0x00, 0xde, 0x00, 0xde, 0x00, 0xab, 0x00, 0xab, 0x00, 0x89, 0xff, 0x89, 0xff, 0x52, 0xfd, 0x52, 0xfd, 0xba, 0xfa, 0xba, 0xfa, 0x11, 0xfa, 0x11, 0xfa, 0x79, 0xfc, 0x79, 0xfc, 0x96, 0xff, 0x96, 0xff, 0xee, 0x00, 0xee, 0x00, 0x69, 0x00, 0x69, 0x00, 0x63, 0xfe, 0x63, 0xfe, 0xa0, 0xfb, 0xa0, 0xfb, 0xdd, 0xf9, 0xdd, 0xf9, 0x58, 0xf9, 0x58, 0xf9, 0xec, 0xf8, 0xed, 0xf8, 0x22, 0xf9, 0x22, 0xf9, 0x2b, 0xfb, 0x2b, 0xfb, 0x4b, 0xfe, 0x4b, 0xfe, 0xaa, 0x00, 0xaa, 0x00, 0x0c, 0x01, 0x0c, 0x01, 0x5a, 0xff, 0x5a, 0xff, 0xcc, 0xfc, 0xcc, 0xfc, 0x43, 0xfb, 0x44, 0xfb, 0x0b, 0xfc, 0x0b, 0xfc, 0xb1, 0xfe, 0xb2, 0xfe, 0x15, 0x01, 0x15, 0x01, 0x81, 0x01, 0x81, 0x01, 0x2d, 0x00, 0x2d, 0x00, 0x02, 0xfe, 0x02, 0xfe, 0xdd, 0xfb, 0xdd, 0xfb, 0xed, 0xfa, 0xed, 0xfa, 0x80, 0xfb, 0x81, 0xfb, 0x7f, 0xfc, 0x7f, 0xfc, 0x1a, 0xfd, 0x1a, 0xfd, 0x75, 0xfd, 0x75, 0xfd, 0x8c, 0xfd, 0x8c, 0xfd, 0x22, 0xfd, 0x22, 0xfd, 0xa2, 0xfc, 0xa2, 0xfc, 0xf1, 0xfc, 0xf1, 0xfc, 0x38, 0xfe, 0x38, 0xfe, 0xcb, 0xff, 0xcb, 0xff, 0x06, 0x01, 0x07, 0x01, 0x92, 0x01, 0x92, 0x01, 0x93, 0x01, 0x93, 0x01, 0x11, 0x02, 0x11, 0x02, 0xc7, 0x03, 0xc7, 0x03, 0xdb, 0x05, 0xdb, 0x05, 0x16, 0x07, 0x16, 0x07, 0x51, 0x07, 0x51, 0x07, 0x18, 0x07, 0x18, 0x07, 0xfa, 0x06, 0xfa, 0x06, 0x08, 0x07, 0x08, 0x07, 0xf5, 0x06, 0xf5, 0x06, 0xd8, 0x06, 0xd8, 0x06, 0x09, 0x07, 0x09, 0x07, 0x4c, 0x07, 0x4c, 0x07, 0xff, 0x06, 0xff, 0x06, 0x8c, 0x05, 0x8b, 0x05, 0xfa, 0x02, 0xfa, 0x02, 0xa8, 0x00, 0xa8, 0x00, 0x29, 0x00, 0x28, 0x00, 0x52, 0x01, 0x51, 0x01, 0xa4, 0x02, 0xa3, 0x02, 0x03, 0x03, 0x02, 0x03, 0x4e, 0x02, 0x4d, 0x02, 0x10, 0x01, 0x10, 0x01, 0xe1, 0xff, 0xe1, 0xff, 0x2d, 0xff, 0x2d, 0xff, 0x64, 0xff, 0x64, 0xff, 0x9d, 0x00, 0x9d, 0x00, 0x6c, 0x02, 0x6c, 0x02, 0x44, 0x04, 0x43, 0x04, 0x7c, 0x05, 0x7c, 0x05, 0xb4, 0x05, 0xb3, 0x05, 0x75, 0x05, 0x74, 0x05, 0x84, 0x05, 0x83, 0x05, 0x16, 0x06, 0x16, 0x06, 0x35, 0x07, 0x35, 0x07, 0xcb, 0x08, 0xcb, 0x08, 0x6a, 0x0a, 0x6a, 0x0a, 0xaa, 0x0b, 0xa9, 0x0b, 0x4b, 0x0c, 0x4b, 0x0c, 0x50, 0x0c, 0x4f, 0x0c, 0x34, 0x0c, 0x34, 0x0c, 0x6c, 0x0c, 0x6b, 0x0c, 0xfc, 0x0c, 0xfc, 0x0c, 0x99, 0x0d, 0x99, 0x0d, 0x9b, 0x0d, 0x9a, 0x0d, 0x7c, 0x0c, 0x7b, 0x0c, 0x8e, 0x0a, 0x8e, 0x0a, 0x64, 0x08, 0x64, 0x08, 0x4f, 0x06, 0x4e, 0x06, 0xe7, 0x04, 0xe6, 0x04, 0x8f, 0x04, 0x8f, 0x04, 0x8b, 0x04, 0x8a, 0x04, 0xb7, 0x03, 0xb6, 0x03, 0xa6, 0x01, 0xa6, 0x01, 0xb9, 0xfe, 0xb9, 0xfe, 0xe5, 0xfb, 0xe5, 0xfb, 0x3f, 0xfa, 0x3e, 0xfa, 0x23, 0xfa, 0x23, 0xfa, 0x03, 0xfb, 0x02, 0xfb, 0xf5, 0xfb, 0xf4, 0xfb, 0x3b, 0xfc, 0x3a, 0xfc, 0x7b, 0xfb, 0x7a, 0xfb, 0xc9, 0xf9, 0xc8, 0xf9, 0xaf, 0xf7, 0xaf, 0xf7, 0x22, 0xf6, 0x21, 0xf6, 0xe7, 0xf5, 0xe6, 0xf5, 0xfc, 0xf6, 0xfb, 0xf6, 0x97, 0xf8, 0x97, 0xf8, 0xc5, 0xf9, 0xc5, 0xf9, 0xf9, 0xf9, 0xf8, 0xf9, 0x40, 0xf9, 0x40, 0xf9, 0x35, 0xf8, 0x35, 0xf8, 0x8b, 0xf7, 0x8b, 0xf7, 0x9b, 0xf7, 0x9b, 0xf7, 0x33, 0xf8, 0x33, 0xf8, 0xd7, 0xf8, 0xd7, 0xf8, 0xf0, 0xf8, 0xf1, 0xf8, 0x09, 0xf8, 0x0a, 0xf8, 0x77, 0xf6, 0x78, 0xf6, 0x48, 0xf5, 0x49, 0xf5, 0x5a, 0xf5, 0x5b, 0xf5, 0xb5, 0xf6, 0xb6, 0xf6, 0x89, 0xf8, 0x8a, 0xf8, 0xa0, 0xf9, 0xa1, 0xf9, 0x5a, 0xf9, 0x5b, 0xf9, 0x24, 0xf8, 0x25, 0xf8, 0xe7, 0xf6, 0xe8, 0xf6, 0x6f, 0xf6, 0x70, 0xf6, 0x1c, 0xf7, 0x1d, 0xf7, 0xa8, 0xf8, 0xa9, 0xf8, 0x5a, 0xfa, 0x5a, 0xfa, 0x8d, 0xfb, 0x8d, 0xfb, 0xeb, 0xfb, 0xeb, 0xfb, 0x7b, 0xfb, 0x7b, 0xfb, 0xb2, 0xfa, 0xb2, 0xfa, 0x2c, 0xfa, 0x2c, 0xfa, 0x48, 0xfa, 0x48, 0xfa, 0x1a, 0xfb, 0x19, 0xfb, 0x7e, 0xfc, 0x7d, 0xfc, 0x12, 0xfe, 0x11, 0xfe, 0x50, 0xff, 0x4f, 0xff, 0xe2, 0xff, 0xe1, 0xff, 0xec, 0xff, 0xea, 0xff, 0xea, 0xff, 0xe9, 0xff, 0x55, 0x00, 0x54, 0x00, 0x3a, 0x01, 0x39, 0x01, 0x2f, 0x02, 0x2d, 0x02, 0x9d, 0x02, 0x9b, 0x02, 0x4c, 0x02, 0x4d, 0x02, 0xaf, 0x01, 0xb6, 0x01, 0x7d, 0x01, 0x8b, 0x01, 0x0a, 0x02, 0x1e, 0x02, 0x2a, 0x03, 0x3f, 0x03, 0x6b, 0x04, 0x7d, 0x04, 0x3f, 0x05, 0x4b, 0x05, 0x34, 0x05, 0x3a, 0x05, 0x4e, 0x04, 0x4f, 0x04, 0x0d, 0x03, 0x0e, 0x03, 0xfe, 0x01, 0x05, 0x02, 0x7e, 0x01, 0x8e, 0x01, 0xb3, 0x01, 0xcb, 0x01, 0x63, 0x02, 0x7e, 0x02, 0x00, 0x03, 0x18, 0x03, 0x13, 0x03, 0x21, 0x03, 0x86, 0x02, 0x87, 0x02, 0x78, 0x01, 0x6f, 0x01, 0x22, 0x00, 0x13, 0x00, 0xeb, 0xfe, 0xdb, 0xfe, 0x3e, 0xfe, 0x32, 0xfe, 0x1c, 0xfe, 0x14, 0xfe, 0x26, 0xfe, 0x20, 0xfe, 0x08, 0xfe, 0x00, 0xfe, 0x9a, 0xfd, 0x90, 0xfd, 0xe8, 0xfc, 0xdb, 0xfc, 0x36, 0xfc, 0x29, 0xfc, 0xc0, 0xfb, 0xb7, 0xfb, 0x75, 0xfb, 0x74, 0xfb, 0x18, 0xfb, 0x1e, 0xfb, 0x8c, 0xfa, 0x97, 0xfa, 0xd2, 0xf9, 0xde, 0xf9, 0x07, 0xf9, 0x11, 0xf9, 0x76, 0xf8, 0x7d, 0xf8, 0x62, 0xf8, 0x66, 0xf8, 0xc7, 0xf8, 0xc9, 0xf8, 0x64, 0xf9, 0x65, 0xf9, 0xe0, 0xf9, 0xde, 0xf9, 0xed, 0xf9, 0xe9, 0xf9, 0x75, 0xf9, 0x6c, 0xf9, 0xaa, 0xf8, 0x9b, 0xf8, 0xfb, 0xf7, 0xe8, 0xf7, 0xd5, 0xf7, 0xbe, 0xf7, 0x56, 0xf8, 0x3a, 0xf8, 0x55, 0xf9, 0x35, 0xf9, 0x8a, 0xfa, 0x66, 0xfa, 0x92, 0xfb, 0x6b, 0xfb, 0x20, 0xfc, 0xf7, 0xfb, 0x40, 0xfc, 0x17, 0xfc, 0x47, 0xfc, 0x20, 0xfc, 0x6b, 0xfc, 0x48, 0xfc, 0xc4, 0xfc, 0xa6, 0xfc, 0x60, 0xfd, 0x48, 0xfd, 0x21, 0xfe, 0x12, 0xfe, 0xe4, 0xfe, 0xe0, 0xfe, 0xaa, 0xff, 0xb0, 0xff, 0x78, 0x00, 0x86, 0x00, 0x42, 0x01, 0x56, 0x01, 0x06, 0x02, 0x1f, 0x02, 0xc5, 0x02, 0xe1, 0x02, 0x66, 0x03, 0x87, 0x03, 0xd0, 0x03, 0xf6, 0x03, 0x03, 0x04, 0x2c, 0x04, 0x1d, 0x04, 0x49, 0x04, 0x56, 0x04, 0x86, 0x04, 0xdd, 0x04, 0x13, 0x05, 0xbd, 0x05, 0xf3, 0x05, 0xcd, 0x06, 0xfd, 0x06, 0xbc, 0x07, 0xe1, 0x07, 0x3f, 0x08, 0x59, 0x08, 0x57, 0x08, 0x6c, 0x08, 0x2f, 0x08, 0x47, 0x08, 0xff, 0x07, 0x1e, 0x08, 0x02, 0x08, 0x24, 0x08, 0x5a, 0x08, 0x78, 0x08, 0xf5, 0x08, 0x0a, 0x09, 0xa0, 0x09, 0xa9, 0x09, 0x29, 0x0a, 0x27, 0x0a, 0x69, 0x0a, 0x61, 0x0a, 0x4d, 0x0a, 0x48, 0x0a, 0xe5, 0x09, 0xeb, 0x09, 0x4f, 0x09, 0x61, 0x09, 0xa2, 0x08, 0xbd, 0x08, 0xf5, 0x07, 0x10, 0x08, 0x65, 0x07, 0x75, 0x07, 0x09, 0x07, 0x0a, 0x07, 0xda, 0x06, 0xd1, 0x06, 0xb4, 0x06, 0xac, 0x06, 0x6e, 0x06, 0x6d, 0x06, 0xf4, 0x05, 0xfd, 0x05, 0x43, 0x05, 0x54, 0x05, 0x67, 0x04, 0x7a, 0x04, 0x76, 0x03, 0x83, 0x03, 0x7e, 0x02, 0x81, 0x02, 0x99, 0x01, 0x8f, 0x01, 0xe5, 0x00, 0xd2, 0x00, 0x71, 0x00, 0x5e, 0x00, 0x2c, 0x00, 0x24, 0x00, 0xe8, 0xff, 0xf0, 0xff, 0x83, 0xff, 0x93, 0xff, 0xfd, 0xfe, 0x0a, 0xff, 0x5c, 0xfe, 0x5c, 0xfe, 0xad, 0xfd, 0x9c, 0xfd, 0xff, 0xfc, 0xe2, 0xfc, 0x5e, 0xfc, 0x3f, 0xfc, 0xd9, 0xfb, 0xbe, 0xfb, 0x91, 0xfb, 0x7b, 0xfb, 0x93, 0xfb, 0x7c, 0xfb, 0xc1, 0xfb, 0xa2, 0xfb, 0xf8, 0xfb, 0xcb, 0xfb, 0x0d, 0xfc, 0xd1, 0xfb, 0xe4, 0xfb, 0x9a, 0xfb, 0x93, 0xfb, 0x3e, 0xfb, 0x40, 0xfb, 0xe3, 0xfa, 0xf9, 0xfa, 0x98, 0xfa, 0xda, 0xfa, 0x76, 0xfa, 0xf9, 0xfa, 0x92, 0xfa, 0x4b, 0xfb, 0xe2, 0xfa, 0xc6, 0xfb, 0x5e, 0xfb, 0x55, 0xfc, 0xf3, 0xfb, 0xc9, 0xfc, 0x70, 0xfc, 0x01, 0xfd, 0xb0, 0xfc, 0x0d, 0xfd, 0xc1, 0xfc, 0x13, 0xfd, 0xc8, 0xfc, 0x33, 0xfd, 0xeb, 0xfc, 0x76, 0xfd, 0x36, 0xfd, 0xc5, 0xfd, 0x95, 0xfd, 0x1b, 0xfe, 0xfc, 0xfd, 0x8c, 0xfe, 0x7c, 0xfe, 0x23, 0xff, 0x1a, 0xff, 0xcd, 0xff, 0xc6, 0xff, 0x62, 0x00, 0x55, 0x00, 0xbb, 0x00, 0xa6, 0x00, 0xde, 0x00, 0xc0, 0x00, 0xfb, 0x00, 0xd8, 0x00, 0x35, 0x01, 0x13, 0x01, 0x90, 0x01, 0x6e, 0x01, 0xfe, 0x01, 0xd7, 0x01, 0x8b, 0x02, 0x58, 0x02, 0x46, 0x03, 0x02, 0x03, 0x21, 0x04, 0xcc, 0x03, 0xf1, 0x04, 0x90, 0x04, 0x7a, 0x05, 0x12, 0x05, 0xa2, 0x05, 0x35, 0x05, 0x9a, 0x05, 0x2a, 0x05, 0xac, 0x05, 0x3b, 0x05, 0xf3, 0x05, 0x84, 0x05, 0x5f, 0x06, 0xf9, 0x05, 0xd8, 0x06, 0x80, 0x06, 0x42, 0x07, 0xfd, 0x06, 0x97, 0x07, 0x62, 0x07, 0xd6, 0x07, 0xaf, 0x07, 0xe7, 0x07, 0xca, 0x07, 0xbb, 0x07, 0xa8, 0x07, 0x67, 0x07, 0x62, 0x07, 0x00, 0x07, 0x0f, 0x07, 0x93, 0x06, 0xc0, 0x06, 0x2c, 0x06, 0x7f, 0x06, 0xca, 0x05, 0x49, 0x06, 0x6d, 0x05, 0x17, 0x06, 0x1a, 0x05, 0xe6, 0x05, 0xbc, 0x04, 0x9c, 0x05, 0x35, 0x04, 0x1e, 0x05, 0x83, 0x03, 0x71, 0x04, 0xad, 0x02, 0xa8, 0x03, 0xc9, 0x01, 0xdb, 0x02, 0xf9, 0x00, 0x27, 0x02, 0x47, 0x00, 0x8b, 0x01, 0xa7, 0xff, 0xf6, 0x00, 0x1a, 0xff, 0x65, 0x00, 0x9f, 0xfe, 0xdd, 0xff, 0x21, 0xfe, 0x50, 0xff, 0x94, 0xfd, 0xb7, 0xfe, 0xf3, 0xfc, 0x11, 0xfe, 0x3b, 0xfc, 0x5c, 0xfd, 0x78, 0xfb, 0xa1, 0xfc, 0xc2, 0xfa, 0xf3, 0xfb, 0x2e, 0xfa, 0x62, 0xfb, 0xd0, 0xf9, 0xf9, 0xfa, 0xa7, 0xf9, 0xba, 0xfa, 0x9b, 0xf9, 0x95, 0xfa, 0x8b, 0xf9, 0x70, 0xfa, 0x5f, 0xf9, 0x38, 0xfa, 0x16, 0xf9, 0xe5, 0xf9, 0xc8, 0xf8, 0x88, 0xf9, 0x90, 0xf8, 0x39, 0xf9, 0x72, 0xf8, 0x01, 0xf9, 0x71, 0xf8, 0xeb, 0xf8, 0x98, 0xf8, 0x01, 0xf9, 0xeb, 0xf8, 0x43, 0xf9, 0x5b, 0xf9, 0x9b, 0xf9, 0xd1, 0xf9, 0xee, 0xf9, 0x3a, 0xfa, 0x2b, 0xfa, 0x8c, 0xfa, 0x4c, 0xfa, 0xcd, 0xfa, 0x5c, 0xfa, 0x11, 0xfb, 0x74, 0xfa, 0x5f, 0xfb, 0xa5, 0xfa, 0xc1, 0xfb, 0xf5, 0xfa, 0x3b, 0xfc, 0x65, 0xfb, 0xcf, 0xfc, 0xf1, 0xfb, 0x73, 0xfd, 0x8a, 0xfc, 0x19, 0xfe, 0x20, 0xfd, 0xae, 0xfe, 0xa6, 0xfd, 0x26, 0xff, 0x14, 0xfe, 0x84, 0xff, 0x71, 0xfe, 0xd3, 0xff, 0xc8, 0xfe, 0x28, 0x00, 0x2b, 0xff, 0x99, 0x00, 0xac, 0xff, 0x26, 0x01, 0x47, 0x00, 0xca, 0x01, 0xf2, 0x00, 0x76, 0x02, 0x9c, 0x01, 0x12, 0x03, 0x33, 0x02, 0x98, 0x03, 0xb3, 0x02, 0x02, 0x04, 0x1c, 0x03, 0x51, 0x04, 0x6b, 0x03, 0x8d, 0x04, 0xa6, 0x03, 0xc9, 0x04, 0xd8, 0x03, 0x18, 0x05, 0x10, 0x04, 0x83, 0x05, 0x5c, 0x04, 0xfe, 0x05, 0xb6, 0x04, 0x72, 0x06, 0x0f, 0x05, 0xc8, 0x06, 0x57, 0x05, 0xfa, 0x06, 0x84, 0x05, 0x0e, 0x07, 0x95, 0x05, 0x05, 0x07, 0x86, 0x05, 0xe8, 0x06, 0x5f, 0x05, 0xbe, 0x06, 0x2e, 0x05, 0x92, 0x06, 0xfd, 0x04, 0x6f, 0x06, 0xe1, 0x04, 0x5c, 0x06, 0xdd, 0x04, 0x46, 0x06, 0xe1, 0x04, 0x1a, 0x06, 0xd8, 0x04, 0xd1, 0x05, 0xb9, 0x04, 0x65, 0x05, 0x79, 0x04, 0xd1, 0x04, 0x15, 0x04, 0x26, 0x04, 0x9e, 0x03, 0x74, 0x03, 0x25, 0x03, 0xcb, 0x02, 0xb7, 0x02, 0x3c, 0x02, 0x5f, 0x02, 0xc0, 0x01, 0x16, 0x02, 0x44, 0x01, 0xc7, 0x01, 0xbd, 0x00, 0x6a, 0x01, 0x28, 0x00, 0xfe, 0x00, 0x84, 0xff, 0x7f, 0x00, 0xd7, 0xfe, 0xf0, 0xff, 0x26, 0xfe, 0x54, 0xff, 0x79, 0xfd, 0xb1, 0xfe, 0xe1, 0xfc, 0x17, 0xfe, 0x63, 0xfc, 0x8e, 0xfd, 0xf3, 0xfb, 0x0f, 0xfd, 0x87, 0xfb, 0x95, 0xfc, 0x1e, 0xfb, 0x21, 0xfc, 0xb8, 0xfa, 0xb2, 0xfb, 0x57, 0xfa, 0x46, 0xfb, 0xfa, 0xf9, 0xda, 0xfa, 0x9c, 0xf9, 0x68, 0xfa, 0x43, 0xf9, 0xf3, 0xf9, 0xfb, 0xf8, 0x8d, 0xf9, 0xd1, 0xf8, 0x47, 0xf9, 0xc6, 0xf8, 0x2c, 0xf9, 0xd5, 0xf8, 0x3b, 0xf9, 0xea, 0xf8, 0x60, 0xf9, 0xf5, 0xf8, 0x83, 0xf9, 0xf4, 0xf8, 0x9d, 0xf9, 0xef, 0xf8, 0xb0, 0xf9, 0xeb, 0xf8, 0xc1, 0xf9, 0xf2, 0xf8, 0xdb, 0xf9, 0x13, 0xf9, 0x0e, 0xfa, 0x50, 0xf9, 0x5d, 0xfa, 0xa3, 0xf9, 0xc5, 0xfa, 0x0c, 0xfa, 0x45, 0xfb, 0x81, 0xfa, 0xd0, 0xfb, 0xf8, 0xfa, 0x57, 0xfc, 0x6e, 0xfb, 0xd1, 0xfc, 0xe3, 0xfb, 0x40, 0xfd, 0x58, 0xfc, 0xaa, 0xfd, 0xd2, 0xfc, 0x16, 0xfe, 0x54, 0xfd, 0x88, 0xfe, 0xe0, 0xfd, 0xfe, 0xfe, 0x76, 0xfe, 0x76, 0xff, 0x14, 0xff, 0xf2, 0xff, 0xb5, 0xff, 0x70, 0x00, 0x52, 0x00, 0xed, 0x00, 0xe2, 0x00, 0x63, 0x01, 0x5e, 0x01, 0xc8, 0x01, 0xc6, 0x01, 0x1a, 0x02, 0x1c, 0x02, 0x5c, 0x02, 0x6d, 0x02, 0x96, 0x02, 0xc8, 0x02, 0xd5, 0x02, 0x33, 0x03, 0x21, 0x03, 0xa3, 0x03, 0x79, 0x03, 0x0c, 0x04, 0xd5, 0x03, 0x61, 0x04, 0x2b, 0x04, 0x95, 0x04, 0x6a, 0x04, 0xa4, 0x04, 0x89, 0x04, 0x9d, 0x04, 0x8f, 0x04, 0x93, 0x04, 0x8e, 0x04, 0x86, 0x04, 0x8a, 0x04, 0x77, 0x04, 0x84, 0x04, 0x6f, 0x04, 0x84, 0x04, 0x6c, 0x04, 0x86, 0x04, 0x67, 0x04, 0x85, 0x04, 0x5d, 0x04, 0x7c, 0x04, 0x40, 0x04, 0x63, 0x04, 0x08, 0x04, 0x32, 0x04, 0xbc, 0x03, 0xed, 0x03, 0x6b, 0x03, 0xa1, 0x03, 0x1f, 0x03, 0x56, 0x03, 0xdd, 0x02, 0x0f, 0x03, 0xa4, 0x02, 0xcc, 0x02, 0x6d, 0x02, 0x87, 0x02, 0x34, 0x02, 0x3d, 0x02, 0xef, 0x01, 0xe8, 0x01, 0x95, 0x01, 0x81, 0x01, 0x27, 0x01, 0x0c, 0x01, 0xaf, 0x00, 0x92, 0x00, 0x34, 0x00, 0x19, 0x00, 0xc1, 0xff, 0xa2, 0xff, 0x5f, 0xff, 0x35, 0xff, 0x08, 0xff, 0xca, 0xfe, 0xb4, 0xfe, 0x5e, 0xfe, 0x64, 0xfe, 0xf8, 0xfd, 0x18, 0xfe, 0x9a, 0xfd, 0xc8, 0xfd, 0x3b, 0xfd, 0x74, 0xfd, 0xd9, 0xfc, 0x1e, 0xfd, 0x76, 0xfc, 0xc3, 0xfc, 0x0e, 0xfc, 0x69, 0xfc, 0xa9, 0xfb, 0x1d, 0xfc, 0x50, 0xfb, 0xe7, 0xfb, 0x0a, 0xfb, 0xcc, 0xfb, 0xdc, 0xfa, 0xc9, 0xfb, 0xc5, 0xfa, 0xd2, 0xfb, 0xbd, 0xfa, 0xdd, 0xfb, 0xbb, 0xfa, 0xdd, 0xfb, 0xb2, 0xfa, 0xcd, 0xfb, 0x9b, 0xfa, 0xbc, 0xfb, 0x85, 0xfa, 0xb7, 0xfb, 0x80, 0xfa, 0xbe, 0xfb, 0x8c, 0xfa, 0xcf, 0xfb, 0xa4, 0xfa, 0xeb, 0xfb, 0xc7, 0xfa, 0x10, 0xfc, 0xee, 0xfa, 0x39, 0xfc, 0x14, 0xfb, 0x65, 0xfc, 0x42, 0xfb, 0x96, 0xfc, 0x80, 0xfb, 0xc0, 0xfc, 0xc5, 0xfb, 0xe8, 0xfc, 0x0e, 0xfc, 0x1a, 0xfd, 0x5f, 0xfc, 0x5f, 0xfd, 0xb8, 0xfc, 0xb1, 0xfd, 0x12, 0xfd, 0x0e, 0xfe, 0x6a, 0xfd, 0x79, 0xfe, 0xc9, 0xfd, 0xea, 0xfe, 0x2e, 0xfe, 0x5a, 0xff, 0x97, 0xfe, 0xcb, 0xff, 0x0d, 0xff, 0x39, 0x00, 0x8d, 0xff, 0x9f, 0x00, 0x08, 0x00, 0x06, 0x01, 0x7d, 0x00, 0x75, 0x01, 0xec, 0x00, 0xee, 0x01, 0x59, 0x01, 0x71, 0x02, 0xc8, 0x01, 0xf7, 0x02, 0x3d, 0x02, 0x7b, 0x03, 0xb6, 0x02, 0xf3, 0x03, 0x27, 0x03, 0x56, 0x04, 0x85, 0x03, 0xa9, 0x04, 0xd2, 0x03, 0xf1, 0x04, 0x0c, 0x04, 0x2b, 0x05, 0x31, 0x04, 0x5f, 0x05, 0x49, 0x04, 0x9b, 0x05, 0x6c, 0x04, 0xdf, 0x05, 0xa0, 0x04, 0x1d, 0x06, 0xda, 0x04, 0x51, 0x06, 0x14, 0x05, 0x78, 0x06, 0x44, 0x05, 0x88, 0x06, 0x5d, 0x05, 0x85, 0x06, 0x62, 0x05, 0x76, 0x06, 0x5f, 0x05, 0x5c, 0x06, 0x58, 0x05, 0x39, 0x06, 0x4e, 0x05, 0x14, 0x06, 0x46, 0x05, 0xe8, 0x05, 0x3e, 0x05, 0xab, 0x05, 0x2c, 0x05, 0x63, 0x05, 0x14, 0x05, 0x19, 0x05, 0xfc, 0x04, 0xca, 0x04, 0xdd, 0x04, 0x75, 0x04, 0xb4, 0x04, 0x19, 0x04, 0x82, 0x04, 0xb2, 0x03, 0x46, 0x04, 0x3d, 0x03, 0xfd, 0x03, 0xbb, 0x02, 0xa9, 0x03, 0x3a, 0x02, 0x56, 0x03, 0xc2, 0x01, 0x0b, 0x03, 0x5d, 0x01, 0xcb, 0x02, 0x03, 0x01, 0x8a, 0x02, 0xaa, 0x00, 0x38, 0x02, 0x42, 0x00, 0xc9, 0x01, 0xbe, 0xff, 0x3f, 0x01, 0x26, 0xff, 0xac, 0x00, 0x90, 0xfe, 0x27, 0x00, 0x08, 0xfe, 0xb6, 0xff, 0x97, 0xfd, 0x58, 0xff, 0x44, 0xfd, 0x0e, 0xff, 0x02, 0xfd, 0xcc, 0xfe, 0xc0, 0xfc, 0x84, 0xfe, 0x73, 0xfc, 0x2c, 0xfe, 0x1c, 0xfc, 0xc8, 0xfd, 0xb9, 0xfb, 0x5d, 0xfd, 0x53, 0xfb, 0xfe, 0xfc, 0xfd, 0xfa, 0xc0, 0xfc, 0xbc, 0xfa, 0x9e, 0xfc, 0x92, 0xfa, 0x8d, 0xfc, 0x85, 0xfa, 0x86, 0xfc, 0x8f, 0xfa, 0x84, 0xfc, 0x97, 0xfa, 0x7c, 0xfc, 0x96, 0xfa, 0x72, 0xfc, 0x8e, 0xfa, 0x70, 0xfc, 0x88, 0xfa, 0x77, 0xfc, 0x8d, 0xfa, 0x86, 0xfc, 0xaa, 0xfa, 0xa3, 0xfc, 0xe0, 0xfa, 0xcb, 0xfc, 0x24, 0xfb, 0xf9, 0xfc, 0x6f, 0xfb, 0x2c, 0xfd, 0xb7, 0xfb, 0x61, 0xfd, 0xf8, 0xfb, 0x98, 0xfd, 0x33, 0xfc, 0xcd, 0xfd, 0x6c, 0xfc, 0xfb, 0xfd, 0xa9, 0xfc, 0x1c, 0xfe, 0xec, 0xfc, 0x31, 0xfe, 0x2f, 0xfd, 0x3c, 0xfe, 0x70, 0xfd, 0x46, 0xfe, 0xb4, 0xfd, 0x60, 0xfe, 0xff, 0xfd, 0x90, 0xfe, 0x56, 0xfe, 0xd5, 0xfe, 0xb0, 0xfe, 0x21, 0xff, 0x04, 0xff, 0x64, 0xff, 0x49, 0xff, 0x91, 0xff, 0x80, 0xff, 0xa7, 0xff, 0xb5, 0xff, 0xb5, 0xff, 0xf1, 0xff, 0xc8, 0xff, 0x38, 0x00, 0xf1, 0xff, 0x86, 0x00, 0x31, 0x00, 0xd1, 0x00, 0x7d, 0x00, 0x13, 0x01, 0xc0, 0x00, 0x4d, 0x01, 0xf0, 0x00, 0x7e, 0x01, 0x0a, 0x01, 0xa5, 0x01, 0x17, 0x01, 0xc7, 0x01, 0x28, 0x01, 0xe9, 0x01, 0x44, 0x01, 0x12, 0x02, 0x6a, 0x01, 0x41, 0x02, 0x96, 0x01, 0x76, 0x02, 0xc3, 0x01, 0xa1, 0x02, 0xea, 0x01, 0xbe, 0x02, 0x0c, 0x02, 0xcd, 0x02, 0x27, 0x02, 0xd6, 0x02, 0x3b, 0x02, 0xde, 0x02, 0x49, 0x02, 0xe7, 0x02, 0x52, 0x02, 0xef, 0x02, 0x58, 0x02, 0xef, 0x02, 0x50, 0x02, 0xe1, 0x02, 0x37, 0x02, 0xc4, 0x02, 0x11, 0x02, 0xa8, 0x02, 0xf2, 0x01, 0x93, 0x02, 0xe6, 0x01, 0x85, 0x02, 0xeb, 0x01, 0x79, 0x02, 0xf5, 0x01, 0x60, 0x02, 0xec, 0x01, 0x2a, 0x02, 0xc0, 0x01, 0xd5, 0x01, 0x72, 0x01, 0x6d, 0x01, 0x15, 0x01, 0xff, 0x00, 0xb8, 0x00, 0x98, 0x00, 0x65, 0x00, 0x46, 0x00, 0x28, 0x00, 0x0a, 0x00, 0xff, 0xff, 0xd3, 0xff, 0xd9, 0xff, 0x92, 0xff, 0xa9, 0xff, 0x3a, 0xff, 0x66, 0xff, 0xca, 0xfe, 0x10, 0xff, 0x50, 0xfe, 0xb6, 0xfe, 0xe3, 0xfd, 0x6d, 0xfe, 0x94, 0xfd, 0x3a, 0xfe, 0x5e, 0xfd, 0x0f, 0xfe, 0x3e, 0xfd, 0xe6, 0xfd, 0x29, 0xfd, 0xbb, 0xfd, 0x16, 0xfd, 0x8e, 0xfd, 0x02, 0xfd, 0x66, 0xfd, 0xea, 0xfc, 0x41, 0xfd, 0xd2, 0xfc, 0x1d, 0xfd, 0xbf, 0xfc, 0xf3, 0xfc, 0xb5, 0xfc, 0xc4, 0xfc, 0xb7, 0xfc, 0x94, 0xfc, 0xcf, 0xfc, 0x70, 0xfc, 0xf9, 0xfc, 0x5d, 0xfc, 0x30, 0xfd, 0x5c, 0xfc, 0x6a, 0xfd, 0x68, 0xfc, 0xa0, 0xfd, 0x77, 0xfc, 0xcf, 0xfd, 0x81, 0xfc, 0xfa, 0xfd, 0x80, 0xfc, 0x23, 0xfe, 0x73, 0xfc, 0x49, 0xfe, 0x5d, 0xfc, 0x6c, 0xfe, 0x4a, 0xfc, 0x91, 0xfe, 0x4b, 0xfc, 0xc2, 0xfe, 0x68, 0xfc, 0x06, 0xff, 0x9d, 0xfc, 0x5c, 0xff, 0xde, 0xfc, 0xba, 0xff, 0x1b, 0xfd, 0x0d, 0x00, 0x49, 0xfd, 0x54, 0x00, 0x74, 0xfd, 0x91, 0x00, 0xa9, 0xfd, 0xd0, 0x00, 0xf2, 0xfd, 0x19, 0x01, 0x50, 0xfe, 0x75, 0x01, 0xc1, 0xfe, 0xe4, 0x01, 0x3c, 0xff, 0x57, 0x02, 0xb1, 0xff, 0xc2, 0x02, 0x16, 0x00, 0x1b, 0x03, 0x69, 0x00, 0x5f, 0x03, 0xb1, 0x00, 0x95, 0x03, 0xfa, 0x00, 0xbf, 0x03, 0x4c, 0x01, 0xe5, 0x03, 0xa7, 0x01, 0x17, 0x04, 0x0b, 0x02, 0x57, 0x04, 0x6f, 0x02, 0x9b, 0x04, 0xc8, 0x02, 0xd8, 0x04, 0x13, 0x03, 0x00, 0x05, 0x4d, 0x03, 0x0e, 0x05, 0x78, 0x03, 0x0b, 0x05, 0x9e, 0x03, 0x09, 0x05, 0xcf, 0x03, 0x0d, 0x05, 0x0a, 0x04, 0x11, 0x05, 0x47, 0x04, 0x0c, 0x05, 0x78, 0x04, 0xf5, 0x04, 0x90, 0x04, 0xcc, 0x04, 0x90, 0x04, 0x99, 0x04, 0x80, 0x04, 0x67, 0x04, 0x71, 0x04, 0x3f, 0x04, 0x6f, 0x04, 0x20, 0x04, 0x78, 0x04, 0xfd, 0x03, 0x82, 0x04, 0xcb, 0x03, 0x7e, 0x04, 0x87, 0x03, 0x66, 0x04, 0x37, 0x03, 0x41, 0x04, 0xe8, 0x02, 0x19, 0x04, 0xa5, 0x02, 0xf5, 0x03, 0x69, 0x02, 0xd3, 0x03, 0x28, 0x02, 0xa6, 0x03, 0xe5, 0x01, 0x70, 0x03, 0xa4, 0x01, 0x3b, 0x03, 0x5a, 0x01, 0x01, 0x03, 0x05, 0x01, 0xc4, 0x02, 0xaa, 0x00, 0x87, 0x02, 0x4f, 0x00, 0x4c, 0x02, 0xfa, 0xff, 0x15, 0x02, 0xab, 0xff, 0xde, 0x01, 0x5a, 0xff, 0xa0, 0x01, 0xf9, 0xfe, 0x52, 0x01, 0x8d, 0xfe, 0xfa, 0x00, 0x27, 0xfe, 0xa6, 0x00, 0xcf, 0xfd, 0x61, 0x00, 0x89, 0xfd, 0x2b, 0x00, 0x4c, 0xfd, 0xfb, 0xff, 0x0b, 0xfd, 0xc4, 0xff, 0xc1, 0xfc, 0x83, 0xff, 0x79, 0xfc, 0x3f, 0xff, 0x3b, 0xfc, 0x00, 0xff, 0x0e, 0xfc, 0xcc, 0xfe, 0xf7, 0xfb, 0xa9, 0xfe, 0xe9, 0xfb, 0x8d, 0xfe, 0xd4, 0xfb, 0x68, 0xfe, 0xb3, 0xfb, 0x34, 0xfe, 0x8a, 0xfb, 0xf3, 0xfd, 0x68, 0xfb, 0xb4, 0xfd, 0x5f, 0xfb, 0x88, 0xfd, 0x75, 0xfb, 0x78, 0xfd, 0x9f, 0xfb, 0x78, 0xfd, 0xcf, 0xfb, 0x76, 0xfd, 0x01, 0xfc, 0x6c, 0xfd, 0x2c, 0xfc, 0x55, 0xfd, 0x50, 0xfc, 0x30, 0xfd, 0x75, 0xfc, 0x08, 0xfd, 0xa5, 0xfc, 0xe3, 0xfc, 0xe8, 0xfc, 0xcd, 0xfc, 0x41, 0xfd, 0xcc, 0xfc, 0xb0, 0xfd, 0xe7, 0xfc, 0x28, 0xfe, 0x16, 0xfd, 0x9b, 0xfe, 0x4a, 0xfd, 0xfd, 0xfe, 0x70, 0xfd, 0x4f, 0xff, 0x81, 0xfd, 0x97, 0xff, 0x88, 0xfd, 0xe6, 0xff, 0x97, 0xfd, 0x47, 0x00, 0xc0, 0xfd, 0xb8, 0x00, 0x0c, 0xfe, 0x2a, 0x01, 0x72, 0xfe, 0x85, 0x01, 0xd6, 0xfe, 0xbd, 0x01, 0x28, 0xff, 0xdb, 0x01, 0x6b, 0xff, 0xed, 0x01, 0xa7, 0xff, 0x00, 0x02, 0xe5, 0xff, 0x1d, 0x02, 0x2c, 0x00, 0x40, 0x02, 0x7d, 0x00, 0x61, 0x02, 0xd3, 0x00, 0x81, 0x02, 0x2e, 0x01, 0xa0, 0x02, 0x90, 0x01, 0xb7, 0x02, 0xec, 0x01, 0xc2, 0x02, 0x33, 0x02, 0xc9, 0x02, 0x67, 0x02, 0xd5, 0x02, 0x94, 0x02, 0xe7, 0x02, 0xbd, 0x02, 0xfc, 0x02, 0xe1, 0x02, 0x0f, 0x03, 0x01, 0x03, 0x1b, 0x03, 0x1d, 0x03, 0x21, 0x03, 0x33, 0x03, 0x1f, 0x03, 0x41, 0x03, 0x1c, 0x03, 0x4d, 0x03, 0x1b, 0x03, 0x5a, 0x03, 0x19, 0x03, 0x63, 0x03, 0x0f, 0x03, 0x69, 0x03, 0xf6, 0x02, 0x68, 0x03, 0xc7, 0x02, 0x56, 0x03, 0x84, 0x02, 0x31, 0x03, 0x36, 0x02, 0x01, 0x03, 0xec, 0x01, 0xd6, 0x02, 0xb3, 0x01, 0xbb, 0x02, 0x81, 0x01, 0xa9, 0x02, 0x48, 0x01, 0x93, 0x02, 0xff, 0x00, 0x6d, 0x02, 0xa5, 0x00, 0x33, 0x02, 0x3b, 0x00, 0xe7, 0x01, 0xcd, 0xff, 0x94, 0x01, 0x63, 0xff, 0x42, 0x01, 0xfe, 0xfe, 0xef, 0x00, 0x9e, 0xfe, 0x9b, 0x00, 0x47, 0xfe, 0x4a, 0x00, 0xf9, 0xfd, 0xfa, 0xff, 0xaf, 0xfd, 0xa8, 0xff, 0x6a, 0xfd, 0x54, 0xff, 0x2d, 0xfd, 0xfe, 0xfe, 0xf4, 0xfc, 0x9f, 0xfe, 0xbe, 0xfc, 0x3c, 0xfe, 0x92, 0xfc, 0xe0, 0xfd, 0x71, 0xfc, 0x8e, 0xfd, 0x53, 0xfc, 0x40, 0xfd, 0x3d, 0xfc, 0xf3, 0xfc, 0x36, 0xfc, 0xae, 0xfc, 0x40, 0xfc, 0x74, 0xfc, 0x53, 0xfc, 0x47, 0xfc, 0x68, 0xfc, 0x26, 0xfc, 0x7c, 0xfc, 0x08, 0xfc, 0x88, 0xfc, 0xe6, 0xfb, 0x8f, 0xfc, 0xc0, 0xfb, 0x9f, 0xfc, 0xa5, 0xfb, 0xbf, 0xfc, 0x9e, 0xfb, 0xe7, 0xfc, 0xa9, 0xfb, 0x14, 0xfd, 0xc2, 0xfb, 0x48, 0xfd, 0xee, 0xfb, 0x7a, 0xfd, 0x2a, 0xfc, 0xa3, 0xfd, 0x6e, 0xfc, 0xc3, 0xfd, 0xb2, 0xfc, 0xe3, 0xfd, 0xf4, 0xfc, 0x03, 0xfe, 0x31, 0xfd, 0x22, 0xfe, 0x6b, 0xfd, 0x47, 0xfe, 0xb1, 0xfd, 0x71, 0xfe, 0x0b, 0xfe, 0x95, 0xfe, 0x6b, 0xfe, 0xb8, 0xfe, 0xcb, 0xfe, 0xe8, 0xfe, 0x2d, 0xff, 0x27, 0xff, 0x8c, 0xff, 0x6d, 0xff, 0xde, 0xff, 0xb6, 0xff, 0x26, 0x00, 0xfe, 0xff, 0x64, 0x00, 0x3d, 0x00, 0x9a, 0x00, 0x77, 0x00, 0xcf, 0x00, 0xb7, 0x00, 0x0e, 0x01, 0xff, 0x00, 0x57, 0x01, 0x4c, 0x01, 0x9e, 0x01, 0x9e, 0x01, 0xde, 0x01, 0xf3, 0x01, 0x0e, 0x02, 0x3f, 0x02, 0x2f, 0x02, 0x7e, 0x02, 0x4b, 0x02, 0xa9, 0x02, 0x6b, 0x02, 0xc5, 0x02, 0x92, 0x02, 0xdb, 0x02, 0xc1, 0x02, 0xf6, 0x02, 0xf7, 0x02, 0x1a, 0x03, 0x31, 0x03, 0x44, 0x03, 0x70, 0x03, 0x68, 0x03, 0xad, 0x03, 0x7c, 0x03, 0xe1, 0x03, 0x80, 0x03, 0x03, 0x04, 0x73, 0x03, 0x11, 0x04, 0x54, 0x03, 0x0e, 0x04, 0x24, 0x03, 0x02, 0x04, 0xe8, 0x02, 0xf5, 0x03, 0xa4, 0x02, 0xe8, 0x03, 0x60, 0x02, 0xd8, 0x03, 0x20, 0x02, 0xbf, 0x03, 0xe1, 0x01, 0x94, 0x03, 0x9f, 0x01, 0x53, 0x03, 0x5a, 0x01, 0x04, 0x03, 0x17, 0x01, 0xb3, 0x02, 0xd7, 0x00, 0x6a, 0x02, 0x94, 0x00, 0x28, 0x02, 0x48, 0x00, 0xe4, 0x01, 0xf3, 0xff, 0x97, 0x01, 0x9b, 0xff, 0x3d, 0x01, 0x46, 0xff, 0xd5, 0x00, 0xfd, 0xfe, 0x64, 0x00, 0xc3, 0xfe, 0xf2, 0xff, 0x93, 0xfe, 0x85, 0xff, 0x62, 0xfe, 0x1d, 0xff, 0x2b, 0xfe, 0xbd, 0xfe, 0xf0, 0xfd, 0x63, 0xfe, 0xb6, 0xfd, 0x0e, 0xfe, 0x83, 0xfd, 0xb7, 0xfd, 0x61, 0xfd, 0x62, 0xfd, 0x4f, 0xfd, 0x12, 0xfd, 0x47, 0xfd, 0xc7, 0xfc, 0x44, 0xfd, 0x83, 0xfc, 0x44, 0xfd, 0x47, 0xfc, 0x41, 0xfd, 0x12, 0xfc, 0x3c, 0xfd, 0xe2, 0xfb, 0x3a, 0xfd, 0xb8, 0xfb, 0x39, 0xfd, 0x98, 0xfb, 0x35, 0xfd, 0x7e, 0xfb, 0x2e, 0xfd, 0x67, 0xfb, 0x2b, 0xfd, 0x56, 0xfb, 0x32, 0xfd, 0x50, 0xfb, 0x42, 0xfd, 0x53, 0xfb, 0x5f, 0xfd, 0x63, 0xfb, 0x87, 0xfd, 0x83, 0xfb, 0xb1, 0xfd, 0xaa, 0xfb, 0xd8, 0xfd, 0xcf, 0xfb, 0xfe, 0xfd, 0xf2, 0xfb, 0x24, 0xfe, 0x16, 0xfc, 0x47, 0xfe, 0x39, 0xfc, 0x6c, 0xfe, 0x5e, 0xfc, 0x9b, 0xfe, 0x8e, 0xfc, 0xd4, 0xfe, 0xc5, 0xfc, 0x0d, 0xff, 0xfa, 0xfc, 0x45, 0xff, 0x2c, 0xfd, 0x7f, 0xff, 0x61, 0xfd, 0xbc, 0xff, 0x9a, 0xfd, 0x01, 0x00, 0xdb, 0xfd, 0x4e, 0x00, 0x24, 0xfe, 0x98, 0x00, 0x6d, 0xfe, 0xd6, 0x00, 0xad, 0xfe, 0x08, 0x01, 0xe5, 0xfe, 0x31, 0x01, 0x1e, 0xff, 0x58, 0x01, 0x5d, 0xff, 0x89, 0x01, 0xa6, 0xff, 0xc7, 0x01, 0xf8, 0xff, 0x0e, 0x02, 0x4b, 0x00, 0x55, 0x02, 0x99, 0x00, 0x91, 0x02, 0xe0, 0x00, 0xbf, 0x02, 0x21, 0x01, 0xd9, 0x02, 0x5c, 0x01, 0xe7, 0x02, 0x8f, 0x01, 0xed, 0x02, 0xb8, 0x01, 0xf8, 0x02, 0xd9, 0x01, 0x0e, 0x03, 0xf9, 0x01, 0x2c, 0x03, 0x18, 0x02, 0x49, 0x03, 0x38, 0x02, 0x5a, 0x03, 0x56, 0x02, 0x56, 0x03, 0x69, 0x02, 0x3d, 0x03, 0x6f, 0x02, 0x1c, 0x03, 0x72, 0x02, 0x02, 0x03, 0x79, 0x02, 0xed, 0x02, 0x82, 0x02, 0xdb, 0x02, 0x86, 0x02, 0xcc, 0x02, 0x84, 0x02, 0xbb, 0x02, 0x7e, 0x02, 0xa5, 0x02, 0x73, 0x02, 0x89, 0x02, 0x67, 0x02, 0x66, 0x02, 0x58, 0x02, 0x3c, 0x02, 0x43, 0x02, 0x0d, 0x02, 0x27, 0x02, 0xda, 0x01, 0x05, 0x02, 0xa2, 0x01, 0xdf, 0x01, 0x64, 0x01, 0xb4, 0x01, 0x24, 0x01, 0x81, 0x01, 0xe3, 0x00, 0x44, 0x01, 0xa4, 0x00, 0x02, 0x01, 0x68, 0x00, 0xc2, 0x00, 0x2c, 0x00, 0x88, 0x00, 0xeb, 0xff, 0x50, 0x00, 0xa6, 0xff, 0x1a, 0x00, 0x5d, 0xff, 0xe3, 0xff, 0x0e, 0xff, 0xa3, 0xff, 0xba, 0xfe, 0x5d, 0xff, 0x64, 0xfe, 0x11, 0xff, 0x15, 0xfe, 0xcc, 0xfe, 0xd3, 0xfd, 0x98, 0xfe, 0x9d, 0xfd, 0x79, 0xfe, 0x6e, 0xfd, 0x69, 0xfe, 0x3f, 0xfd, 0x5c, 0xfe, 0x11, 0xfd, 0x48, 0xfe, 0xe5, 0xfc, 0x2a, 0xfe, 0xc5, 0xfc, 0x0a, 0xfe, 0xb8, 0xfc, 0xf5, 0xfd, 0xbe, 0xfc, 0xf0, 0xfd, 0xcb, 0xfc, 0xf9, 0xfd, 0xe1, 0xfc, 0x13, 0xfe, 0x01, 0xfd, 0x39, 0xfe, 0x29, 0xfd, 0x63, 0xfe, 0x5d, 0xfd, 0x89, 0xfe, 0x9f, 0xfd, 0xb0, 0xfe, 0xe7, 0xfd, 0xd5, 0xfe, 0x27, 0xfe, 0xf8, 0xfe, 0x5f, 0xfe, 0x1c, 0xff, 0x8e, 0xfe, 0x43, 0xff, 0xb9, 0xfe, 0x6c, 0xff, 0xe5, 0xfe, 0x97, 0xff, 0x1a, 0xff, 0xc6, 0xff, 0x5c, 0xff, 0xfc, 0xff, 0xa8, 0xff, 0x36, 0x00, 0xf6, 0xff, 0x72, 0x00, 0x3a, 0x00, 0xaf, 0x00, 0x70, 0x00, 0xed, 0x00, 0x99, 0x00, 0x28, 0x01, 0xbd, 0x00, 0x5e, 0x01, 0xe4, 0x00, 0x8c, 0x01, 0x14, 0x01, 0xb5, 0x01, 0x4f, 0x01, 0xe0, 0x01, 0x8e, 0x01, 0x12, 0x02, 0xcf, 0x01, 0x4c, 0x02, 0x09, 0x02, 0x85, 0x02, 0x32, 0x02, 0xb2, 0x02, 0x4f, 0x02, 0xd0, 0x02, 0x67, 0x02, 0xe5, 0x02, 0x83, 0x02, 0xf8, 0x02, 0xa5, 0x02, 0x0e, 0x03, 0xca, 0x02, 0x25, 0x03, 0xe8, 0x02, 0x34, 0x03, 0xfe, 0x02, 0x38, 0x03, 0x0e, 0x03, 0x37, 0x03, 0x19, 0x03, 0x34, 0x03, 0x1c, 0x03, 0x2e, 0x03, 0x14, 0x03, 0x21, 0x03, 0xfe, 0x02, 0x07, 0x03, 0xdd, 0x02, 0xe0, 0x02, 0xb6, 0x02, 0xb2, 0x02, 0x92, 0x02, 0x8a, 0x02, 0x71, 0x02, 0x67, 0x02, 0x56, 0x02, 0x46, 0x02, 0x44, 0x02, 0x27, 0x02, 0x32, 0x02, 0x09, 0x02, 0x16, 0x02, 0xed, 0x01, 0xee, 0x01, 0xd3, 0x01, 0xb7, 0x01, 0xb3, 0x01, 0x74, 0x01, 0x87, 0x01, 0x30, 0x01, 0x50, 0x01, 0xf1, 0x00, 0x18, 0x01, 0xbd, 0x00, 0xe9, 0x00, 0x90, 0x00, 0xc2, 0x00, 0x65, 0x00, 0xa0, 0x00, 0x39, 0x00, 0x7f, 0x00, 0x08, 0x00, 0x59, 0x00, 0xd2, 0xff, 0x2c, 0x00, 0x99, 0xff, 0xf8, 0xff, 0x62, 0xff, 0xbf, 0xff, 0x30, 0xff, 0x83, 0xff, 0x0a, 0xff, 0x4b, 0xff, 0xf1, 0xfe, 0x1d, 0xff, 0xe1, 0xfe, 0xf8, 0xfe, 0xd4, 0xfe, 0xd9, 0xfe, 0xc5, 0xfe, 0xbc, 0xfe, 0xb3, 0xfe, 0x9e, 0xfe, 0x9a, 0xfe, 0x80, 0xfe, 0x7c, 0xfe, 0x60, 0xfe, 0x5d, 0xfe, 0x43, 0xfe, 0x3d, 0xfe, 0x28, 0xfe, 0x1c, 0xfe, 0x0c, 0xfe, 0xfb, 0xfd, 0xf2, 0xfd, 0xdb, 0xfd, 0xdb, 0xfd, 0xb7, 0xfd, 0xc4, 0xfd, 0x8e, 0xfd, 0xad, 0xfd, 0x69, 0xfd, 0x9f, 0xfd, 0x4e, 0xfd, 0x9f, 0xfd, 0x39, 0xfd, 0xaa, 0xfd, 0x23, 0xfd, 0xbf, 0xfd, 0x08, 0xfd, 0xd6, 0xfd, 0xed, 0xfc, 0xe9, 0xfd, 0xe0, 0xfc, 0xfc, 0xfd, 0xeb, 0xfc, 0x18, 0xfe, 0x09, 0xfd, 0x40, 0xfe, 0x2f, 0xfd, 0x74, 0xfe, 0x50, 0xfd, 0xa9, 0xfe, 0x6c, 0xfd, 0xdb, 0xfe, 0x91, 0xfd, 0x08, 0xff, 0xc3, 0xfd, 0x37, 0xff, 0x03, 0xfe, 0x6d, 0xff, 0x49, 0xfe, 0xad, 0xff, 0x8e, 0xfe, 0xef, 0xff, 0xcd, 0xfe, 0x29, 0x00, 0x05, 0xff, 0x58, 0x00, 0x40, 0xff, 0x81, 0x00, 0x7f, 0xff, 0xab, 0x00, 0xc3, 0xff, 0xd7, 0x00, 0x09, 0x00, 0x00, 0x01, 0x4b, 0x00, 0x19, 0x01, 0x7f, 0x00, 0x1c, 0x01, 0xa2, 0x00, 0x14, 0x01, 0xc0, 0x00, 0x10, 0x01, 0xdd, 0x00, 0x14, 0x01, 0xf9, 0x00, 0x17, 0x01, 0x17, 0x01, 0x15, 0x01, 0x3a, 0x01, 0x10, 0x01, 0x5e, 0x01, 0x06, 0x01, 0x7c, 0x01, 0x00, 0x01, 0x96, 0x01, 0x01, 0x01, 0xa7, 0x01, 0x05, 0x01, 0xaf, 0x01, 0x07, 0x01, 0xad, 0x01, 0x08, 0x01, 0xaa, 0x01, 0x08, 0x01, 0xa7, 0x01, 0x04, 0x01, 0x9e, 0x01, 0xf7, 0x00, 0x90, 0x01, 0xe4, 0x00, 0x7f, 0x01, 0xd1, 0x00, 0x6a, 0x01, 0xc1, 0x00, 0x52, 0x01, 0xb6, 0x00, 0x39, 0x01, 0xa9, 0x00, 0x1e, 0x01, 0x95, 0x00, 0xff, 0x00, 0x73, 0x00, 0xd9, 0x00, 0x44, 0x00, 0xb1, 0x00, 0x0f, 0x00, 0x89, 0x00, 0xd7, 0xff, 0x62, 0x00, 0xa1, 0xff, 0x41, 0x00, 0x70, 0xff, 0x27, 0x00, 0x46, 0xff, 0x0f, 0x00, 0x21, 0xff, 0xf7, 0xff, 0xff, 0xfe, 0xe0, 0xff, 0xde, 0xfe, 0xc6, 0xff, 0xb8, 0xfe, 0xa9, 0xff, 0x8e, 0xfe, 0x8e, 0xff, 0x6b, 0xfe, 0x75, 0xff, 0x51, 0xfe, 0x5d, 0xff, 0x3a, 0xfe, 0x40, 0xff, 0x1e, 0xfe, 0x22, 0xff, 0x01, 0xfe, 0x02, 0xff, 0xe5, 0xfd, 0xd9, 0xfe, 0xcd, 0xfd, 0xa9, 0xfe, 0xbf, 0xfd, 0x77, 0xfe, 0xb6, 0xfd, 0x47, 0xfe, 0xab, 0xfd, 0x1a, 0xfe, 0x96, 0xfd, 0xf5, 0xfd, 0x80, 0xfd, 0xdc, 0xfd, 0x70, 0xfd, 0xc9, 0xfd, 0x69, 0xfd, 0xc0, 0xfd, 0x73, 0xfd, 0xc5, 0xfd, 0x8f, 0xfd, 0xd2, 0xfd, 0xb9, 0xfd, 0xdd, 0xfd, 0xe1, 0xfd, 0xe0, 0xfd, 0xff, 0xfd, 0xda, 0xfd, 0x0f, 0xfe, 0xca, 0xfd, 0x13, 0xfe, 0xb7, 0xfd, 0x15, 0xfe, 0xa7, 0xfd, 0x22, 0xfe, 0xa4, 0xfd, 0x43, 0xfe, 0xae, 0xfd, 0x77, 0xfe, 0xbd, 0xfd, 0xb1, 0xfe, 0xcf, 0xfd, 0xef, 0xfe, 0xe9, 0xfd, 0x2e, 0xff, 0x06, 0xfe, 0x68, 0xff, 0x20, 0xfe, 0x96, 0xff, 0x3b, 0xfe, 0xc0, 0xff, 0x5d, 0xfe, 0xf0, 0xff, 0x83, 0xfe, 0x29, 0x00, 0xb2, 0xfe, 0x6d, 0x00, 0xec, 0xfe, 0xb6, 0x00, 0x2b, 0xff, 0xf9, 0x00, 0x66, 0xff, 0x2f, 0x01, 0x9e, 0xff, 0x5f, 0x01, 0xd6, 0xff, 0x8e, 0x01, 0x11, 0x00, 0xbf, 0x01, 0x4f, 0x00, 0xf1, 0x01, 0x8c, 0x00, 0x1d, 0x02, 0xc3, 0x00, 0x3d, 0x02, 0xf1, 0x00, 0x52, 0x02, 0x1b, 0x01, 0x63, 0x02, 0x4c, 0x01, 0x7a, 0x02, 0x8c, 0x01, 0x9d, 0x02, 0xd3, 0x01, 0xc4, 0x02, 0x11, 0x02, 0xe2, 0x02, 0x3e, 0x02, 0xef, 0x02, 0x58, 0x02, 0xe9, 0x02, 0x68, 0x02, 0xd8, 0x02, 0x7a, 0x02, 0xc3, 0x02, 0x96, 0x02, 0xb5, 0x02, 0xb1, 0x02, 0xa7, 0x02, 0xc3, 0x02, 0x96, 0x02, 0xd0, 0x02, 0x86, 0x02, 0xda, 0x02, 0x74, 0x02, 0xe4, 0x02, 0x5f, 0x02, 0xf4, 0x02, 0x4a, 0x02, 0x05, 0x03, 0x33, 0x02, 0x09, 0x03, 0x16, 0x02, 0xfc, 0x02, 0xf1, 0x01, 0xe4, 0x02, 0xcb, 0x01, 0xbf, 0x02, 0x9f, 0x01, 0x93, 0x02, 0x6f, 0x01, 0x67, 0x02, 0x3f, 0x01, 0x3c, 0x02, 0x0e, 0x01, 0x0e, 0x02, 0xd6, 0x00, 0xd6, 0x01, 0x96, 0x00, 0x96, 0x01, 0x57, 0x00, 0x4f, 0x01, 0x1e, 0x00, 0x01, 0x01, 0xeb, 0xff, 0xb2, 0x00, 0xbc, 0xff, 0x64, 0x00, 0x87, 0xff, 0x1e, 0x00, 0x4f, 0xff, 0xe2, 0xff, 0x17, 0xff, 0xac, 0xff, 0xe2, 0xfe, 0x77, 0xff, 0xb0, 0xfe, 0x3d, 0xff, 0x83, 0xfe, 0xfa, 0xfe, 0x56, 0xfe, 0xaf, 0xfe, 0x27, 0xfe, 0x68, 0xfe, 0xff, 0xfd, 0x2d, 0xfe, 0xde, 0xfd, 0x00, 0xfe, 0xc4, 0xfd, 0xde, 0xfd, 0xb0, 0xfd, 0xbf, 0xfd, 0xa0, 0xfd, 0x9b, 0xfd, 0x90, 0xfd, 0x79, 0xfd, 0x85, 0xfd, 0x5f, 0xfd, 0x82, 0xfd, 0x50, 0xfd, 0x83, 0xfd, 0x4d, 0xfd, 0x86, 0xfd, 0x53, 0xfd, 0x8f, 0xfd, 0x61, 0xfd, 0xa5, 0xfd, 0x6e, 0xfd, 0xc4, 0xfd, 0x7c, 0xfd, 0xed, 0xfd, 0x8b, 0xfd, 0x17, 0xfe, 0x97, 0xfd, 0x3a, 0xfe, 0xaa, 0xfd, 0x58, 0xfe, 0xc7, 0xfd, 0x76, 0xfe, 0xe9, 0xfd, 0x97, 0xfe, 0x12, 0xfe, 0xc1, 0xfe, 0x3a, 0xfe, 0xf1, 0xfe, 0x5b, 0xfe, 0x1e, 0xff, 0x73, 0xfe, 0x43, 0xff, 0x8b, 0xfe, 0x62, 0xff, 0xa9, 0xfe, 0x7e, 0xff, 0xd2, 0xfe, 0x98, 0xff, 0x0b, 0xff, 0xba, 0xff, 0x4e, 0xff, 0xe6, 0xff, 0x97, 0xff, 0x1a, 0x00, 0xdd, 0xff, 0x51, 0x00, 0x18, 0x00, 0x7e, 0x00, 0x47, 0x00, 0x97, 0x00, 0x72, 0x00, 0xa1, 0x00, 0xa9, 0x00, 0xab, 0x00, 0xf0, 0x00, 0xbe, 0x00, 0x48, 0x01, 0xdf, 0x00, 0xa5, 0x01, 0x08, 0x01, 0xf9, 0x01, 0x2f, 0x01, 0x43, 0x02, 0x4d, 0x01, 0x85, 0x02, 0x65, 0x01, 0xc4, 0x02, 0x78, 0x01, 0x03, 0x03, 0x8a, 0x01, 0x3d, 0x03, 0x95, 0x01, 0x6d, 0x03, 0x98, 0x01, 0x92, 0x03, 0x98, 0x01, 0xb1, 0x03, 0x96, 0x01, 0xd0, 0x03, 0x92, 0x01, 0xed, 0x03, 0x8b, 0x01, 0x09, 0x04, 0x7e, 0x01, 0x1d, 0x04, 0x66, 0x01, 0x25, 0x04, 0x44, 0x01, 0x23, 0x04, 0x1d, 0x01, 0x1a, 0x04, 0xf6, 0x00, 0x0a, 0x04, 0xce, 0x00, 0xf2, 0x03, 0xa2, 0x00, 0xd1, 0x03, 0x70, 0x00, 0xac, 0x03, 0x39, 0x00, 0x89, 0x03, 0x05, 0x00, 0x66, 0x03, 0xd4, 0xff, 0x3d, 0x03, 0xa4, 0xff, 0x08, 0x03, 0x73, 0xff, 0xc0, 0x02, 0x3d, 0xff, 0x6b, 0x02, 0xff, 0xfe, 0x13, 0x02, 0xbf, 0xfe, 0xc0, 0x01, 0x7e, 0xfe, 0x6f, 0x01, 0x41, 0xfe, 0x19, 0x01, 0x09, 0xfe, 0xbf, 0x00, 0xdb, 0xfd, 0x60, 0x00, 0xb9, 0xfd, 0xfe, 0xff, 0x9e, 0xfd, 0x9a, 0xff, 0x82, 0xfd, 0x38, 0xff, 0x61, 0xfd, 0xda, 0xfe, 0x3d, 0xfd, 0x81, 0xfe, 0x1a, 0xfd, 0x31, 0xfe, 0x00, 0xfd, 0xe9, 0xfd, 0xf3, 0xfc, 0xa3, 0xfd, 0xf3, 0xfc, 0x5e, 0xfd, 0xfa, 0xfc, 0x1b, 0xfd, 0x05, 0xfd, 0xdf, 0xfc, 0x10, 0xfd, 0xaf, 0xfc, 0x1a, 0xfd, 0x8b, 0xfc, 0x26, 0xfd, 0x74, 0xfc, 0x37, 0xfd, 0x64, 0xfc, 0x52, 0xfd, 0x52, 0xfc, 0x71, 0xfd, 0x3c, 0xfc, 0x95, 0xfd, 0x29, 0xfc, 0xbe, 0xfd, 0x1e, 0xfc, 0xeb, 0xfd, 0x22, 0xfc, 0x1d, 0xfe, 0x37, 0xfc, 0x57, 0xfe, 0x5d, 0xfc, 0x9c, 0xfe, 0x8a, 0xfc, 0xe7, 0xfe, 0xb1, 0xfc, 0x31, 0xff, 0xce, 0xfc, 0x73, 0xff, 0xe4, 0xfc, 0xaf, 0xff, 0xfe, 0xfc, 0xe9, 0xff, 0x25, 0xfd, 0x27, 0x00, 0x5c, 0xfd, 0x6c, 0x00, 0x9f, 0xfd, 0xbb, 0x00, 0xe9, 0xfd, 0x13, 0x01, 0x36, 0xfe, 0x72, 0x01, 0x86, 0xfe, 0xd2, 0x01, 0xd8, 0xfe, 0x29, 0x02, 0x2a, 0xff, 0x70, 0x02, 0x7e, 0xff, 0xab, 0x02, 0xd6, 0xff, 0xe4, 0x02, 0x34, 0x00, 0x20, 0x03, 0x93, 0x00, 0x5b, 0x03, 0xea, 0x00, 0x91, 0x03, 0x35, 0x01, 0xbd, 0x03, 0x77, 0x01, 0xdd, 0x03, 0xb7, 0x01, 0xf1, 0x03, 0xf9, 0x01, 0xf6, 0x03, 0x3a, 0x02, 0xee, 0x03, 0x74, 0x02, 0xda, 0x03, 0xa3, 0x02, 0xc1, 0x03, 0xc8, 0x02, 0xa7, 0x03, 0xea, 0x02, 0x8d, 0x03, 0x0e, 0x03, 0x73, 0x03, 0x2e, 0x03, 0x4f, 0x03, 0x43, 0x03, 0x20, 0x03, 0x50, 0x03, 0xed, 0x02, 0x56, 0x03, 0xba, 0x02, 0x55, 0x03, 0x86, 0x02, 0x4c, 0x03, 0x51, 0x02, 0x3b, 0x03, 0x18, 0x02, 0x21, 0x03, 0xda, 0x01, 0x02, 0x03, 0x99, 0x01, 0xe3, 0x02, 0x5b, 0x01, 0xc2, 0x02, 0x1f, 0x01, 0x9b, 0x02, 0xe4, 0x00, 0x6d, 0x02, 0xa8, 0x00, 0x37, 0x02, 0x68, 0x00, 0x01, 0x02, 0x2a, 0x00, 0xd1, 0x01, 0xf0, 0xff, 0xa9, 0x01, 0xbc, 0xff, 0x85, 0x01, 0x8e, 0xff, 0x5c, 0x01, 0x64, 0xff, 0x24, 0x01, 0x37, 0xff, 0xdf, 0x00, 0x05, 0xff, 0x97, 0x00, 0xd3, 0xfe, 0x58, 0x00, 0xa8, 0xfe, 0x20, 0x00, 0x81, 0xfe, 0xf5, 0xff, 0x66, 0xfe, 0xd3, 0xff, 0x59, 0xfe, 0xac, 0xff, 0x4f, 0xfe, 0x78, 0xff, 0x43, 0xfe, 0x37, 0xff, 0x3b, 0xfe, 0xed, 0xfe, 0x38, 0xfe, 0x9f, 0xfe, 0x37, 0xfe, 0x5c, 0xfe, 0x3b, 0xfe, 0x2a, 0xfe, 0x43, 0xfe, 0x03, 0xfe, 0x4b, 0xfe, 0xdf, 0xfd, 0x56, 0xfe, 0xb8, 0xfd, 0x6a, 0xfe, 0x86, 0xfd, 0x83, 0xfe, 0x4d, 0xfd, 0x9c, 0xfe, 0x16, 0xfd, 0xb6, 0xfe, 0xe9, 0xfc, 0xd2, 0xfe, 0xcf, 0xfc, 0xf6, 0xfe, 0xc6, 0xfc, 0x1c, 0xff, 0xc7, 0xfc, 0x3f, 0xff, 0xcd, 0xfc, 0x5f, 0xff, 0xd3, 0xfc, 0x7c, 0xff, 0xd4, 0xfc, 0x99, 0xff, 0xd5, 0xfc, 0xba, 0xff, 0xe1, 0xfc, 0xe2, 0xff, 0xfe, 0xfc, 0x14, 0x00, 0x2a, 0xfd, 0x4e, 0x00, 0x60, 0xfd, 0x8b, 0x00, 0x98, 0xfd, 0xc8, 0x00, 0xc7, 0xfd, 0xfc, 0x00, 0xef, 0xfd, 0x2a, 0x01, 0x19, 0xfe, 0x5a, 0x01, 0x41, 0xfe, 0x89, 0x01, 0x6a, 0xfe, 0xb7, 0x01, 0x97, 0xfe, 0xe8, 0x01, 0xc5, 0xfe, 0x17, 0x02, 0xf4, 0xfe, 0x42, 0x02, 0x22, 0xff, 0x66, 0x02, 0x54, 0xff, 0x86, 0x02, 0x86, 0xff, 0x9e, 0x02, 0xb5, 0xff, 0xac, 0x02, 0xe1, 0xff, 0xb3, 0x02, 0x0b, 0x00, 0xb6, 0x02, 0x38, 0x00, 0xbc, 0x02, 0x68, 0x00, 0xc0, 0x02, 0x9b, 0x00, 0xbf, 0x02, 0xd2, 0x00, 0xb3, 0x02, 0x0a, 0x01, 0x9a, 0x02, 0x3f, 0x01, 0x77, 0x02, 0x6c, 0x01, 0x4e, 0x02, 0x94, 0x01, 0x29, 0x02, 0xba, 0x01, 0x08, 0x02, 0xe2, 0x01, 0xe9, 0x01, 0x10, 0x02, 0xc8, 0x01, 0x40, 0x02, 0xa3, 0x01, 0x69, 0x02, 0x76, 0x01, 0x86, 0x02, 0x40, 0x01, 0x97, 0x02, 0x0a, 0x01, 0x9a, 0x02, 0xd2, 0x00, 0x93, 0x02, 0x9d, 0x00, 0x87, 0x02, 0x6a, 0x00, 0x7b, 0x02, 0x38, 0x00, 0x72, 0x02, 0x03, 0x00, 0x6c, 0x02, 0xcf, 0xff, 0x62, 0x02, 0x9b, 0xff, 0x4e, 0x02, 0x66, 0xff, 0x2d, 0x02, 0x31, 0xff, 0x00, 0x02, 0xfa, 0xfe, 0xcb, 0x01, 0xbf, 0xfe, 0x92, 0x01, 0x82, 0xfe, 0x5b, 0x01, 0x45, 0xfe, 0x29, 0x01, 0x09, 0xfe, 0xfb, 0x00, 0xcf, 0xfd, 0xd1, 0x00, 0x9d, 0xfd, 0xaa, 0x00, 0x78, 0xfd, 0x81, 0x00, 0x61, 0xfd, 0x51, 0x00, 0x4e, 0xfd, 0x15, 0x00, 0x33, 0xfd, 0xd3, 0xff, 0x11, 0xfd, 0x8f, 0xff, 0xec, 0xfc, 0x52, 0xff, 0xcc, 0xfc, 0x23, 0xff, 0xc0, 0xfc, 0xfe, 0xfe, 0xc1, 0xfc, 0xda, 0xfe, 0xc5, 0xfc, 0xac, 0xfe, 0xc3, 0xfc, 0x71, 0xfe, 0xbb, 0xfc, 0x31, 0xfe, 0xb5, 0xfc, 0xf6, 0xfd, 0xb9, 0xfc, 0xc7, 0xfd, 0xcd, 0xfc, 0xa9, 0xfd, 0xf4, 0xfc, 0x9b, 0xfd, 0x28, 0xfd, 0x93, 0xfd, 0x61, 0xfd, 0x88, 0xfd, 0x96, 0xfd, 0x7b, 0xfd, 0xc8, 0xfd, 0x71, 0xfd, 0xfb, 0xfd, 0x6e, 0xfd, 0x2f, 0xfe, 0x76, 0xfd, 0x67, 0xfe, 0x8c, 0xfd, 0xa9, 0xfe, 0xae, 0xfd, 0xf4, 0xfe, 0xd2, 0xfd, 0x41, 0xff, 0xf8, 0xfd, 0x8d, 0xff, 0x20, 0xfe, 0xd1, 0xff, 0x4b, 0xfe, 0x0d, 0x00, 0x79, 0xfe, 0x42, 0x00, 0xaa, 0xfe, 0x75, 0x00, 0xdd, 0xfe, 0xae, 0x00, 0x18, 0xff, 0xf1, 0x00, 0x59, 0xff, 0x3c, 0x01, 0x9a, 0xff, 0x83, 0x01, 0xd3, 0xff, 0xbd, 0x01, 0x09, 0x00, 0xeb, 0x01, 0x3e, 0x00, 0x0f, 0x02, 0x73, 0x00, 0x30, 0x02, 0xa9, 0x00, 0x53, 0x02, 0xdf, 0x00, 0x7a, 0x02, 0x17, 0x01, 0xa3, 0x02, 0x4b, 0x01, 0xc7, 0x02, 0x7a, 0x01, 0xe2, 0x02, 0xa3, 0x01, 0xf6, 0x02, 0xc3, 0x01, 0x01, 0x03, 0xde, 0x01, 0x07, 0x03, 0xf9, 0x01, 0x0b, 0x03, 0x17, 0x02, 0x0b, 0x03, 0x34, 0x02, 0x01, 0x03, 0x4d, 0x02, 0xe9, 0x02, 0x62, 0x02, 0xc5, 0x02, 0x75, 0x02, 0x9c, 0x02, 0x7f, 0x02, 0x6e, 0x02, 0x81, 0x02, 0x3d, 0x02, 0x7f, 0x02, 0x0e, 0x02, 0x7e, 0x02, 0xe0, 0x01, 0x81, 0x02, 0xb1, 0x01, 0x8d, 0x02, 0x82, 0x01, 0x9f, 0x02, 0x53, 0x01, 0xad, 0x02, 0x20, 0x01, 0xb4, 0x02, 0xed, 0x00, 0xb5, 0x02, 0xbd, 0x00, 0xae, 0x02, 0x91, 0x00, 0xa4, 0x02, 0x67, 0x00, 0x9e, 0x02, 0x44, 0x00, 0x9b, 0x02, 0x23, 0x00, 0x91, 0x02, 0xfe, 0xff, 0x7d, 0x02, 0xd6, 0xff, 0x5d, 0x02, 0xaf, 0xff, 0x31, 0x02, 0x8b, 0xff, 0xfd, 0x01, 0x68, 0xff, 0xc5, 0x01, 0x45, 0xff, 0x87, 0x01, 0x1c, 0xff, 0x45, 0x01, 0xf0, 0xfe, 0x00, 0x01, 0xc8, 0xfe, 0xbb, 0x00, 0xa9, 0xfe, 0x77, 0x00, 0x96, 0xfe, 0x2f, 0x00, 0x86, 0xfe, 0xe1, 0xff, 0x71, 0xfe, 0x8f, 0xff, 0x56, 0xfe, 0x41, 0xff, 0x3b, 0xfe, 0xfe, 0xfe, 0x23, 0xfe, 0xc6, 0xfe, 0x11, 0xfe, 0x94, 0xfe, 0x03, 0xfe, 0x63, 0xfe, 0xfb, 0xfd, 0x33, 0xfe, 0xf7, 0xfd, 0x05, 0xfe, 0xf6, 0xfd, 0xdd, 0xfd, 0xf6, 0xfd, 0xb9, 0xfd, 0xf2, 0xfd, 0x9c, 0xfd, 0xeb, 0xfd, 0x83, 0xfd, 0xe4, 0xfd, 0x6b, 0xfd, 0xe1, 0xfd, 0x56, 0xfd, 0xe5, 0xfd, 0x4a, 0xfd, 0xf8, 0xfd, 0x4a, 0xfd, 0x1a, 0xfe, 0x55, 0xfd, 0x48, 0xfe, 0x62, 0xfd, 0x75, 0xfe, 0x65, 0xfd, 0x99, 0xfe, 0x60, 0xfd, 0xb5, 0xfe, 0x5b, 0xfd, 0xd3, 0xfe, 0x5f, 0xfd, 0xfb, 0xfe, 0x72, 0xfd, 0x30, 0xff, 0x8e, 0xfd, 0x70, 0xff, 0xaa, 0xfd, 0xb2, 0xff, 0xc0, 0xfd, 0xef, 0xff, 0xd0, 0xfd, 0x23, 0x00, 0xdf, 0xfd, 0x54, 0x00, 0xf3, 0xfd, 0x85, 0x00, 0x09, 0xfe, 0xb7, 0x00, 0x26, 0xfe, 0xea, 0x00, 0x4a, 0xfe, 0x1e, 0x01, 0x75, 0xfe, 0x4d, 0x01, 0xa0, 0xfe, 0x73, 0x01, 0xce, 0xfe, 0x91, 0x01, 0xf9, 0xfe, 0xa4, 0x01, 0x23, 0xff, 0xaf, 0x01, 0x4f, 0xff, 0xb8, 0x01, 0x7d, 0xff, 0xc0, 0x01, 0xae, 0xff, 0xc9, 0x01, 0xe0, 0xff, 0xcd, 0x01, 0x14, 0x00, 0xc8, 0x01, 0x4a, 0x00, 0xbb, 0x01, 0x80, 0x00, 0xa4, 0x01, 0xb5, 0x00, 0x89, 0x01, 0xe7, 0x00, 0x6c, 0x01, 0x14, 0x01, 0x4e, 0x01, 0x3b, 0x01, 0x2d, 0x01, 0x5b, 0x01, 0x0a, 0x01, 0x75, 0x01, 0xe5, 0x00, 0x87, 0x01, 0xbc, 0x00, 0x94, 0x01, 0x90, 0x00, 0x9c, 0x01, 0x61, 0x00, 0xa2, 0x01, 0x2e, 0x00, 0xa3, 0x01, 0xf8, 0xff, 0xa1, 0x01, 0xc6, 0xff, 0x96, 0x01, 0x94, 0xff, 0x80, 0x01, 0x64, 0xff, 0x60, 0x01, 0x34, 0xff, 0x3d, 0x01, 0x07, 0xff, 0x1b, 0x01, 0xdb, 0xfe, 0xfc, 0x00, 0xac, 0xfe, 0xe1, 0x00, 0x7a, 0xfe, 0xc9, 0x00, 0x46, 0xfe, 0xad, 0x00, 0x12, 0xfe, 0x8b, 0x00, 0xde, 0xfd, 0x65, 0x00, 0xae, 0xfd, 0x3b, 0x00, 0x83, 0xfd, 0x11, 0x00, 0x60, 0xfd, 0xe9, 0xff, 0x44, 0xfd, 0xc1, 0xff, 0x2c, 0xfd, 0x94, 0xff, 0x13, 0xfd, 0x66, 0xff, 0xf9, 0xfc, 0x3d, 0xff, 0xe0, 0xfc, 0x15, 0xff, 0xc6, 0xfc, 0xef, 0xfe, 0xb3, 0xfc, 0xcd, 0xfe, 0xaa, 0xfc, 0xac, 0xfe, 0xb2, 0xfc, 0x8b, 0xfe, 0xc8, 0xfc, 0x6a, 0xfe, 0xe9, 0xfc, 0x4b, 0xfe, 0x0e, 0xfd, 0x26, 0xfe, 0x2e, 0xfd, 0xfe, 0xfd, 0x49, 0xfd, 0xda, 0xfd, 0x65, 0xfd, 0xc1, 0xfd, 0x89, 0xfd, 0xb2, 0xfd, 0xb3, 0xfd, 0xa7, 0xfd, 0xe1, 0xfd, 0x9a, 0xfd, 0x10, 0xfe, 0x88, 0xfd, 0x41, 0xfe, 0x76, 0xfd, 0x78, 0xfe, 0x6f, 0xfd, 0xb6, 0xfe, 0x78, 0xfd, 0xf8, 0xfe, 0x8f, 0xfd, 0x38, 0xff, 0xae, 0xfd, 0x72, 0xff, 0xca, 0xfd, 0xa1, 0xff, 0xde, 0xfd, 0xc7, 0xff, 0xf0, 0xfd, 0xed, 0xff, 0x07, 0xfe, 0x1b, 0x00, 0x2b, 0xfe, 0x54, 0x00, 0x60, 0xfe, 0x99, 0x00, 0xa3, 0xfe, 0xe0, 0x00, 0xe9, 0xfe, 0x1f, 0x01, 0x2c, 0xff, 0x53, 0x01, 0x65, 0xff, 0x7d, 0x01, 0x98, 0xff, 0xa4, 0x01, 0xc8, 0xff, 0xca, 0x01, 0xfe, 0xff, 0xf2, 0x01, 0x3e, 0x00, 0x1d, 0x02, 0x81, 0x00, 0x46, 0x02, 0xc5, 0x00, 0x6e, 0x02, 0x06, 0x01, 0x96, 0x02, 0x3e, 0x01, 0xb9, 0x02, 0x6c, 0x01, 0xd5, 0x02, 0x92, 0x01, 0xea, 0x02, 0xb3, 0x01, 0xf8, 0x02, 0xd4, 0x01, 0x03, 0x03, 0xf4, 0x01, 0x0c, 0x03, 0x12, 0x02, 0x12, 0x03, 0x2c, 0x02, 0x11, 0x03, 0x3f, 0x02, 0x09, 0x03, 0x4a, 0x02, 0xfa, 0x02, 0x51, 0x02, 0xe8, 0x02, 0x59, 0x02, 0xd3, 0x02, 0x65, 0x02, 0xbb, 0x02, 0x72, 0x02, 0x9d, 0x02, 0x7f, 0x02, 0x7a, 0x02, 0x88, 0x02, 0x55, 0x02, 0x8c, 0x02, 0x2f, 0x02, 0x8d, 0x02, 0x09, 0x02, 0x8b, 0x02, 0xde, 0x01, 0x89, 0x02, 0xad, 0x01, 0x84, 0x02, 0x78, 0x01, 0x81, 0x02, 0x44, 0x01, 0x7a, 0x02, 0x13, 0x01, 0x6f, 0x02, 0xe3, 0x00, 0x61, 0x02, 0xb7, 0x00, 0x52, 0x02, 0x8b, 0x00, 0x40, 0x02, 0x5b, 0x00, 0x2b, 0x02, 0x28, 0x00, 0x15, 0x02, 0xf3, 0xff, 0xf8, 0x01, 0xbd, 0xff, 0xd7, 0x01, 0x8c, 0xff, 0xb4, 0x01, 0x63, 0xff, 0x8f, 0x01, 0x42, 0xff, 0x6a, 0x01, 0x29, 0xff, 0x47, 0x01, 0x18, 0xff, 0x25, 0x01, 0x09, 0xff, 0x01, 0x01, 0xf5, 0xfe, 0xda, 0x00, 0xdf, 0xfe, 0xac, 0x00, 0xc8, 0xfe, 0x7d, 0x00, 0xb9, 0xfe, 0x4d, 0x00, 0xb5, 0xfe, 0x23, 0x00, 0xc0, 0xfe, 0xfd, 0xff, 0xcf, 0xfe, 0xd8, 0xff, 0xd9, 0xfe, 0xb4, 0xff, 0xdf, 0xfe, 0x8f, 0xff, 0xe6, 0xfe, 0x69, 0xff, 0xf0, 0xfe, 0x42, 0xff, 0x01, 0xff, 0x1b, 0xff, 0x17, 0xff, 0xf7, 0xfe, 0x2e, 0xff, 0xdf, 0xfe, 0x4a, 0xff, 0xd1, 0xfe, 0x67, 0xff, 0xc5, 0xfe, 0x7f, 0xff, 0xb5, 0xfe, 0x90, 0xff, 0x9f, 0xfe, 0x9b, 0xff, 0x87, 0xfe, 0xa5, 0xff, 0x74, 0xfe, 0xb3, 0xff, 0x6d, 0xfe, 0xc6, 0xff, 0x6f, 0xfe, 0xd9, 0xff, 0x76, 0xfe, 0xea, 0xff, 0x80, 0xfe, 0xf7, 0xff, 0x8c, 0xfe, 0x05, 0x00, 0x97, 0xfe, 0x17, 0x00, 0xa5, 0xfe, 0x31, 0x00, 0xb6, 0xfe, 0x51, 0x00, 0xcc, 0xfe, 0x73, 0x00, 0xe5, 0xfe, 0x91, 0x00, 0x02, 0xff, 0xa7, 0x00, 0x23, 0xff, 0xb6, 0x00, 0x49, 0xff, 0xc9, 0x00, 0x70, 0xff, 0xe4, 0x00, 0x93, 0xff, 0x03, 0x01, 0xb0, 0xff, 0x23, 0x01, 0xce, 0xff, 0x41, 0x01, 0xf6, 0xff, 0x60, 0x01, 0x2b, 0x00, 0x7e, 0x01, 0x65, 0x00, 0x99, 0x01, 0x96, 0x00, 0xaa, 0x01, 0xb8, 0x00, 0xb3, 0x01, 0xd2, 0x00, 0xbc, 0x01, 0xeb, 0x00, 0xc8, 0x01, 0x0b, 0x01, 0xd8, 0x01, 0x2e, 0x01, 0xe4, 0x01, 0x4e, 0x01, 0xe5, 0x01, 0x64, 0x01, 0xd6, 0x01, 0x6d, 0x01, 0xb8, 0x01, 0x6c, 0x01, 0x94, 0x01, 0x67, 0x01, 0x71, 0x01, 0x62, 0x01, 0x51, 0x01, 0x62, 0x01, 0x33, 0x01, 0x63, 0x01, 0x0f, 0x01, 0x64, 0x01, 0xe3, 0x00, 0x5a, 0x01, 0xae, 0x00, 0x47, 0x01, 0x76, 0x00, 0x2d, 0x01, 0x3f, 0x00, 0x10, 0x01, 0x0e, 0x00, 0xf9, 0x00, 0xe6, 0xff, 0xe8, 0x00, 0xc5, 0xff, 0xdd, 0x00, 0xa9, 0xff, 0xd5, 0x00, 0x8b, 0xff, 0xcb, 0x00, 0x69, 0xff, 0xbc, 0x00, 0x45, 0xff, 0xa5, 0x00, 0x21, 0xff, 0x89, 0x00, 0x03, 0xff, 0x6b, 0x00, 0xea, 0xfe, 0x50, 0x00, 0xd9, 0xfe, 0x3a, 0x00, 0xcd, 0xfe, 0x23, 0x00, 0xbf, 0xfe, 0x08, 0x00, 0xb1, 0xfe, 0xe6, 0xff, 0xa1, 0xfe, 0xbf, 0xff, 0x8f, 0xfe, 0x97, 0xff, 0x7b, 0xfe, 0x77, 0xff, 0x6b, 0xfe, 0x5f, 0xff, 0x5f, 0xfe, 0x48, 0xff, 0x53, 0xfe, 0x2d, 0xff, 0x46, 0xfe, 0x0d, 0xff, 0x39, 0xfe, 0xe5, 0xfe, 0x2a, 0xfe, 0xba, 0xfe, 0x19, 0xfe, 0x97, 0xfe, 0x0f, 0xfe, 0x83, 0xfe, 0x0e, 0xfe, 0x79, 0xfe, 0x0f, 0xfe, 0x73, 0xfe, 0x11, 0xfe, 0x6e, 0xfe, 0x13, 0xfe, 0x63, 0xfe, 0x16, 0xfe, 0x51, 0xfe, 0x1b, 0xfe, 0x3e, 0xfe, 0x27, 0xfe, 0x2b, 0xfe, 0x36, 0xfe, 0x20, 0xfe, 0x47, 0xfe, 0x20, 0xfe, 0x5a, 0xfe, 0x2c, 0xfe, 0x72, 0xfe, 0x3f, 0xfe, 0x8f, 0xfe, 0x55, 0xfe, 0xb0, 0xfe, 0x6a, 0xfe, 0xd3, 0xfe, 0x7b, 0xfe, 0xf9, 0xfe, 0x8a, 0xfe, 0x1e, 0xff, 0x99, 0xfe, 0x43, 0xff, 0xb0, 0xfe, 0x6a, 0xff, 0xd2, 0xfe, 0x93, 0xff, 0xfa, 0xfe, 0xbc, 0xff, 0x1e, 0xff, 0xe2, 0xff, 0x3d, 0xff, 0x08, 0x00, 0x54, 0xff, 0x2a, 0x00, 0x66, 0xff, 0x48, 0x00, 0x7d, 0xff, 0x65, 0x00, 0x9a, 0xff, 0x82, 0x00, 0xbb, 0xff, 0xa1, 0x00, 0xda, 0xff, 0xbc, 0x00, 0xf6, 0xff, 0xd6, 0x00, 0x0d, 0x00, 0xea, 0x00, 0x21, 0x00, 0xfa, 0x00, 0x38, 0x00, 0x0b, 0x01, 0x54, 0x00, 0x21, 0x01, 0x76, 0x00, 0x39, 0x01, 0x9d, 0x00, 0x55, 0x01, 0xc7, 0x00, 0x70, 0x01, 0xec, 0x00, 0x85, 0x01, 0x07, 0x01, 0x92, 0x01, 0x15, 0x01, 0x98, 0x01, 0x1d, 0x01, 0x99, 0x01, 0x25, 0x01, 0x99, 0x01, 0x35, 0x01, 0x9c, 0x01, 0x52, 0x01, 0xa4, 0x01, 0x77, 0x01, 0xae, 0x01, 0x97, 0x01, 0xb4, 0x01, 0xa8, 0x01, 0xb0, 0x01, 0xa6, 0x01, 0xa0, 0x01, 0x97, 0x01, 0x85, 0x01, 0x82, 0x01, 0x64, 0x01, 0x6f, 0x01, 0x40, 0x01, 0x61, 0x01, 0x20, 0x01, 0x5a, 0x01, 0x06, 0x01, 0x51, 0x01, 0xee, 0x00, 0x44, 0x01, 0xd5, 0x00, 0x32, 0x01, 0xbb, 0x00, 0x17, 0x01, 0x9e, 0x00, 0xf9, 0x00, 0x7f, 0x00, 0xdb, 0x00, 0x61, 0x00, 0xc0, 0x00, 0x43, 0x00, 0xaa, 0x00, 0x29, 0x00, 0x98, 0x00, 0x14, 0x00, 0x8c, 0x00, 0x05, 0x00, 0x7b, 0x00, 0xf4, 0xff, 0x5e, 0x00, 0xdc, 0xff, 0x3b, 0x00, 0xc1, 0xff, 0x1a, 0x00, 0xa9, 0xff, 0xfe, 0xff, 0x95, 0xff, 0xea, 0xff, 0x87, 0xff, 0xdc, 0xff, 0x7d, 0xff, 0xca, 0xff, 0x70, 0xff, 0xb2, 0xff, 0x62, 0xff, 0x97, 0xff, 0x54, 0xff, 0x7e, 0xff, 0x47, 0xff, 0x69, 0xff, 0x3a, 0xff, 0x56, 0xff, 0x2d, 0xff, 0x46, 0xff, 0x21, 0xff, 0x3a, 0xff, 0x19, 0xff, 0x30, 0xff, 0x15, 0xff, 0x28, 0xff, 0x12, 0xff, 0x22, 0xff, 0x0e, 0xff, 0x1f, 0xff, 0x0b, 0xff, 0x1d, 0xff, 0x09, 0xff, 0x17, 0xff, 0x04, 0xff, 0x0a, 0xff, 0xfc, 0xfe, 0xf9, 0xfe, 0xf2, 0xfe, 0xeb, 0xfe, 0xed, 0xfe, 0xe5, 0xfe, 0xef, 0xfe, 0xe8, 0xfe, 0xf9, 0xfe, 0xee, 0xfe, 0x06, 0xff, 0xf0, 0xfe, 0x11, 0xff, 0xeb, 0xfe, 0x19, 0xff, 0xde, 0xfe, 0x1b, 0xff, 0xcf, 0xfe, 0x1c, 0xff, 0xc3, 0xfe, 0x23, 0xff, 0xc2, 0xfe, 0x34, 0xff, 0xce, 0xfe, 0x52, 0xff, 0xe7, 0xfe, 0x7d, 0xff, 0x0a, 0xff, 0xb0, 0xff, 0x2f, 0xff, 0xe4, 0xff, 0x51, 0xff, 0x15, 0x00, 0x70, 0xff, 0x43, 0x00, 0x8a, 0xff, 0x6c, 0x00, 0xa4, 0xff, 0x94, 0x00, 0xc3, 0xff, 0xc2, 0x00, 0xed, 0xff, 0xfa, 0x00, 0x1f, 0x00, 0x37, 0x01, 0x53, 0x00, 0x73, 0x01, 0x82, 0x00, 0xa9, 0x01, 0xa4, 0x00, 0xd3, 0x01, 0xb7, 0x00, 0xed, 0x01, 0xc0, 0x00, 0xfb, 0x01, 0xca, 0x00, 0x03, 0x02, 0xd8, 0x00, 0x08, 0x02, 0xed, 0x00, 0x0f, 0x02, 0x07, 0x01, 0x19, 0x02, 0x1c, 0x01, 0x21, 0x02, 0x25, 0x01, 0x20, 0x02, 0x22, 0x01, 0x15, 0x02, 0x15, 0x01, 0x01, 0x02, 0x03, 0x01, 0xe5, 0x01, 0xf3, 0x00, 0xc3, 0x01, 0xe9, 0x00, 0x9c, 0x01, 0xe7, 0x00, 0x75, 0x01, 0xe6, 0x00, 0x4e, 0x01, 0xe2, 0x00, 0x27, 0x01, 0xd9, 0x00, 0x05, 0x01, 0xcc, 0x00, 0xe6, 0x00, 0xbd, 0x00, 0xc7, 0x00, 0xb0, 0x00, 0xa5, 0x00, 0xa8, 0x00, 0x81, 0x00, 0xa7, 0x00, 0x62, 0x00, 0xaa, 0x00, 0x4c, 0x00, 0xaa, 0x00, 0x3b, 0x00, 0x9d, 0x00, 0x28, 0x00, 0x84, 0x00, 0x0f, 0x00, 0x6a, 0x00, 0xf6, 0xff, 0x59, 0x00, 0xe1, 0xff, 0x54, 0x00, 0xd5, 0xff, 0x56, 0x00, 0xcf, 0xff, 0x51, 0x00, 0xc6, 0xff, 0x44, 0x00, 0xb7, 0xff, 0x2e, 0x00, 0xa2, 0xff, 0x15, 0x00, 0x8a, 0xff, 0xfb, 0xff, 0x6e, 0xff, 0xe3, 0xff, 0x51, 0xff, 0xcc, 0xff, 0x34, 0xff, 0xb4, 0xff, 0x14, 0xff, 0x99, 0xff, 0xf4, 0xfe, 0x7c, 0xff, 0xd4, 0xfe, 0x60, 0xff, 0xb7, 0xfe, 0x44, 0xff, 0x9e, 0xfe, 0x2d, 0xff, 0x87, 0xfe, 0x1c, 0xff, 0x73, 0xfe, 0x0c, 0xff, 0x5b, 0xfe, 0xfb, 0xfe, 0x3c, 0xfe, 0xe6, 0xfe, 0x1a, 0xfe, 0xcc, 0xfe, 0xf7, 0xfd, 0xb0, 0xfe, 0xd8, 0xfd, 0x9b, 0xfe, 0xc7, 0xfd, 0x94, 0xfe, 0xc4, 0xfd, 0x9a, 0xfe, 0xcc, 0xfd, 0xab, 0xfe, 0xdb, 0xfd, 0xc1, 0xfe, 0xec, 0xfd, 0xd1, 0xfe, 0xf9, 0xfd, 0xd3, 0xfe, 0xf9, 0xfd, 0xcb, 0xfe, 0xf4, 0xfd, 0xc5, 0xfe, 0xf6, 0xfd, 0xca, 0xfe, 0x07, 0xfe, 0xe0, 0xfe, 0x2d, 0xfe, 0x06, 0xff, 0x61, 0xfe, 0x32, 0xff, 0x97, 0xfe, 0x58, 0xff, 0xc4, 0xfe, 0x72, 0xff, 0xe4, 0xfe, 0x85, 0xff, 0xfd, 0xfe, 0x97, 0xff, 0x17, 0xff, 0xb1, 0xff, 0x39, 0xff, 0xd4, 0xff, 0x65, 0xff, 0xf9, 0xff, 0x97, 0xff, 0x19, 0x00, 0xc7, 0xff, 0x32, 0x00, 0xf3, 0xff, 0x47, 0x00, 0x18, 0x00, 0x5c, 0x00, 0x3c, 0x00, 0x76, 0x00, 0x61, 0x00, 0x95, 0x00, 0x87, 0x00, 0xb6, 0x00, 0xae, 0x00, 0xd5, 0x00, 0xcf, 0x00, 0xe6, 0x00, 0xe3, 0x00, 0xe7, 0x00, 0xe6, 0x00, 0xe2, 0x00, 0xe5, 0x00, 0xdd, 0x00, 0xe6, 0x00, 0xe0, 0x00, 0xed, 0x00, 0xf2, 0x00, 0x00, 0x01, 0x0f, 0x01, 0x1b, 0x01, 0x29, 0x01, 0x32, 0x01, 0x36, 0x01, 0x3a, 0x01, 0x32, 0x01, 0x34, 0x01, 0x24, 0x01, 0x25, 0x01, 0x12, 0x01, 0x12, 0x01, 0x04, 0x01, 0x01, 0x01, 0x05, 0x01, 0xfa, 0x00, 0x0f, 0x01, 0xfa, 0x00, 0x1c, 0x01, 0xfa, 0x00, 0x22, 0x01, 0xf4, 0x00, 0x1f, 0x01, 0xe7, 0x00, 0x14, 0x01, 0xd3, 0x00, 0x08, 0x01, 0xbb, 0x00, 0x02, 0x01, 0xa6, 0x00, 0x02, 0x01, 0x95, 0x00, 0x02, 0x01, 0x85, 0x00, 0xfa, 0x00, 0x73, 0x00, 0xeb, 0x00, 0x5f, 0x00, 0xd3, 0x00, 0x49, 0x00, 0xb9, 0x00, 0x35, 0x00, 0xa4, 0x00, 0x28, 0x00, 0x96, 0x00, 0x20, 0x00, 0x87, 0x00, 0x16, 0x00, 0x73, 0x00, 0x04, 0x00, 0x56, 0x00, 0xeb, 0xff, 0x32, 0x00, 0xce, 0xff, 0x06, 0x00, 0xb0, 0xff, 0xd6, 0xff, 0x93, 0xff, 0xaf, 0xff, 0x82, 0xff, 0x93, 0xff, 0x79, 0xff, 0x7f, 0xff, 0x73, 0xff, 0x6b, 0xff, 0x68, 0xff, 0x51, 0xff, 0x56, 0xff, 0x2e, 0xff, 0x3c, 0xff, 0x03, 0xff, 0x1c, 0xff, 0xda, 0xfe, 0xfd, 0xfe, 0xb7, 0xfe, 0xe4, 0xfe, 0x9f, 0xfe, 0xd3, 0xfe, 0x93, 0xfe, 0xcc, 0xfe, 0x90, 0xfe, 0xce, 0xfe, 0x8d, 0xfe, 0xce, 0xfe, 0x86, 0xfe, 0xcc, 0xfe, 0x7f, 0xfe, 0xca, 0xfe, 0x79, 0xfe, 0xca, 0xfe, 0x73, 0xfe, 0xcc, 0xfe, 0x71, 0xfe, 0xd3, 0xfe, 0x78, 0xfe, 0xe4, 0xfe, 0x84, 0xfe, 0xfa, 0xfe, 0x8f, 0xfe, 0x12, 0xff, 0x98, 0xfe, 0x29, 0xff, 0xa3, 0xfe, 0x41, 0xff, 0xb0, 0xfe, 0x5a, 0xff, 0xbe, 0xfe, 0x73, 0xff, 0xcf, 0xfe, 0x8d, 0xff, 0xe1, 0xfe, 0xa7, 0xff, 0xf3, 0xfe, 0xc0, 0xff, 0x05, 0xff, 0xdb, 0xff, 0x16, 0xff, 0xf6, 0xff, 0x26, 0xff, 0x10, 0x00, 0x37, 0xff, 0x2c, 0x00, 0x4c, 0xff, 0x4a, 0x00, 0x65, 0xff, 0x68, 0x00, 0x7c, 0xff, 0x83, 0x00, 0x91, 0xff, 0x9e, 0x00, 0xa1, 0xff, 0xb5, 0x00, 0xa7, 0xff, 0xc6, 0x00, 0xa8, 0xff, 0xcf, 0x00, 0xa7, 0xff, 0xd2, 0x00, 0xa9, 0xff, 0xd4, 0x00, 0xb2, 0xff, 0xdb, 0x00, 0xc5, 0xff, 0xea, 0x00, 0xdd, 0xff, 0xfc, 0x00, 0xf2, 0xff, 0x0a, 0x01, 0x04, 0x00, 0x12, 0x01, 0x10, 0x00, 0x11, 0x01, 0x19, 0x00, 0x0b, 0x01, 0x22, 0x00, 0x02, 0x01, 0x28, 0x00, 0xf5, 0x00, 0x2f, 0x00, 0xe8, 0x00, 0x37, 0x00, 0xdd, 0x00, 0x3e, 0x00, 0xd4, 0x00, 0x47, 0x00, 0xcd, 0x00, 0x54, 0x00, 0xc6, 0x00, 0x63, 0x00, 0xbd, 0x00, 0x73, 0x00, 0xb1, 0x00, 0x7e, 0x00, 0xa1, 0x00, 0x80, 0x00, 0x8c, 0x00, 0x76, 0x00, 0x71, 0x00, 0x66, 0x00, 0x55, 0x00, 0x58, 0x00, 0x3e, 0x00, 0x4f, 0x00, 0x2d, 0x00, 0x4d, 0x00, 0x24, 0x00, 0x4e, 0x00, 0x1d, 0x00, 0x4c, 0x00, 0x13, 0x00, 0x41, 0x00, 0x01, 0x00, 0x2d, 0x00, 0xe6, 0xff, 0x17, 0x00, 0xcb, 0xff, 0xff, 0xff, 0xb1, 0xff, 0xe5, 0xff, 0x95, 0xff, 0xcd, 0xff, 0x79, 0xff, 0xb6, 0xff, 0x5f, 0xff, 0xa3, 0xff, 0x49, 0xff, 0x93, 0xff, 0x36, 0xff, 0x89, 0xff, 0x28, 0xff, 0x82, 0xff, 0x1d, 0xff, 0x7e, 0xff, 0x10, 0xff, 0x7b, 0xff, 0x04, 0xff, 0x79, 0xff, 0xf9, 0xfe, 0x79, 0xff, 0xf2, 0xfe, 0x77, 0xff, 0xeb, 0xfe, 0x73, 0xff, 0xe2, 0xfe, 0x6f, 0xff, 0xda, 0xfe, 0x6c, 0xff, 0xd6, 0xfe, 0x6f, 0xff, 0xd7, 0xfe, 0x77, 0xff, 0xde, 0xfe, 0x82, 0xff, 0xe7, 0xfe, 0x8a, 0xff, 0xee, 0xfe, 0x8d, 0xff, 0xee, 0xfe, 0x8c, 0xff, 0xec, 0xfe, 0x8b, 0xff, 0xee, 0xfe, 0x92, 0xff, 0xfa, 0xfe, 0xa2, 0xff, 0x12, 0xff, 0xb9, 0xff, 0x2f, 0xff, 0xd3, 0xff, 0x4f, 0xff, 0xeb, 0xff, 0x6c, 0xff, 0x03, 0x00, 0x8a, 0xff, 0x1a, 0x00, 0xa6, 0xff, 0x2f, 0x00, 0xc2, 0xff, 0x43, 0x00, 0xde, 0xff, 0x56, 0x00, 0xfa, 0xff, 0x6a, 0x00, 0x17, 0x00, 0x80, 0x00, 0x35, 0x00, 0x9a, 0x00, 0x56, 0x00, 0xb6, 0x00, 0x7a, 0x00, 0xd2, 0x00, 0xa0, 0x00, 0xec, 0x00, 0xc6, 0x00, 0x04, 0x01, 0xea, 0x00, 0x18, 0x01, 0x08, 0x01, 0x28, 0x01, 0x1e, 0x01, 0x31, 0x01, 0x2c, 0x01, 0x31, 0x01, 0x33, 0x01, 0x30, 0x01, 0x3b, 0x01, 0x32, 0x01, 0x4a, 0x01, 0x39, 0x01, 0x5e, 0x01, 0x44, 0x01, 0x74, 0x01, 0x53, 0x01, 0x88, 0x01, 0x60, 0x01, 0x93, 0x01, 0x63, 0x01, 0x91, 0x01, 0x5c, 0x01, 0x85, 0x01, 0x51, 0x01, 0x76, 0x01, 0x44, 0x01, 0x6a, 0x01, 0x38, 0x01, 0x62, 0x01, 0x33, 0x01, 0x61, 0x01, 0x32, 0x01, 0x63, 0x01, 0x32, 0x01, 0x60, 0x01, 0x31, 0x01, 0x54, 0x01, 0x2e, 0x01, 0x43, 0x01, 0x29, 0x01, 0x30, 0x01, 0x20, 0x01, 0x1a, 0x01, 0x15, 0x01, 0x04, 0x01, 0x08, 0x01, 0xee, 0x00, 0xff, 0x00, 0xd9, 0x00, 0xf9, 0x00, 0xc4, 0x00, 0xf3, 0x00, 0xac, 0x00, 0xeb, 0x00, 0x91, 0x00, 0xe2, 0x00, 0x76, 0x00, 0xdb, 0x00, 0x5d, 0x00, 0xcf, 0x00, 0x42, 0x00, 0xc2, 0x00, 0x28, 0x00, 0xb7, 0x00, 0x14, 0x00, 0xae, 0x00, 0x04, 0x00, 0xa5, 0x00, 0xf7, 0xff, 0x9f, 0x00, 0xee, 0xff, 0x99, 0x00, 0xe9, 0xff, 0x91, 0x00, 0xe4, 0xff, 0x85, 0x00, 0xe0, 0xff, 0x76, 0x00, 0xdc, 0xff, 0x66, 0x00, 0xd6, 0xff, 0x55, 0x00, 0xd0, 0xff, 0x46, 0x00, 0xcd, 0xff, 0x38, 0x00, 0xcc, 0xff, 0x28, 0x00, 0xcf, 0xff, 0x14, 0x00, 0xcf, 0xff, 0xfd, 0xff, 0xcb, 0xff, 0xe7, 0xff, 0xc6, 0xff, 0xd2, 0xff, 0xbe, 0xff, 0xc1, 0xff, 0xb5, 0xff, 0xb4, 0xff, 0xae, 0xff, 0xac, 0xff, 0xa8, 0xff, 0xa9, 0xff, 0xa5, 0xff, 0xa8, 0xff, 0xa5, 0xff, 0xa9, 0xff, 0xa8, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0x9a, 0xff, 0x9b, 0xff, 0x90, 0xff, 0x92, 0xff, 0x8a, 0xff, 0x8b, 0xff, 0x8a, 0xff, 0x8a, 0xff, 0x92, 0xff, 0x91, 0xff, 0x9d, 0xff, 0x9d, 0xff, 0xa6, 0xff, 0xa7, 0xff, 0xae, 0xff, 0xb1, 0xff, 0xba, 0xff, 0xbb, 0xff, 0xc6, 0xff, 0xc8, 0xff, 0xce, 0xff, 0xd4, 0xff, 0xd3, 0xff, 0xe1, 0xff, 0xd7, 0xff, 0xf1, 0xff, 0xd9, 0xff, 0x00, 0x00, 0xda, 0xff, 0x0f, 0x00, 0xdf, 0xff, 0x1e, 0x00, 0xeb, 0xff, 0x31, 0x00, 0xf8, 0xff, 0x42, 0x00, 0x02, 0x00, 0x4f, 0x00, 0x07, 0x00, 0x59, 0x00, 0x08, 0x00, 0x65, 0x00, 0x09, 0x00, 0x77, 0x00, 0x08, 0x00, 0x89, 0x00, 0x08, 0x00, 0x99, 0x00, 0x06, 0x00, 0xa3, 0x00, 0x03, 0x00, 0xa7, 0x00, 0x01, 0x00, 0xac, 0x00, 0xfd, 0xff, 0xae, 0x00, 0xf5, 0xff, 0xaf, 0x00, 0xec, 0xff, 0xb1, 0x00, 0xe4, 0xff, 0xb5, 0x00, 0xe1, 0xff, 0xbd, 0x00, 0xde, 0xff, 0xc0, 0x00, 0xd8, 0xff, 0xbc, 0x00, 0xcc, 0xff, 0xad, 0x00, 0xbb, 0xff, 0x98, 0x00, 0xa9, 0xff, 0x81, 0x00, 0x9a, 0xff, 0x6c, 0x00, 0x90, 0xff, 0x5b, 0x00, 0x88, 0xff, 0x49, 0x00, 0x7f, 0xff, 0x34, 0x00, 0x70, 0xff, 0x1b, 0x00, 0x5e, 0xff, 0xfd, 0xff, 0x4a, 0xff, 0xdf, 0xff, 0x39, 0xff, 0xc3, 0xff, 0x32, 0xff, 0xae, 0xff, 0x37, 0xff, 0xa0, 0xff, 0x44, 0xff, 0x98, 0xff, 0x52, 0xff, 0x90, 0xff, 0x5c, 0xff, 0x86, 0xff, 0x62, 0xff, 0x7b, 0xff, 0x62, 0xff, 0x6f, 0xff, 0x5f, 0xff, 0x65, 0xff, 0x5d, 0xff, 0x60, 0xff, 0x5e, 0xff, 0x5f, 0xff, 0x66, 0xff, 0x62, 0xff, 0x76, 0xff, 0x69, 0xff, 0x86, 0xff, 0x6d, 0xff, 0x91, 0xff, 0x6a, 0xff, 0x97, 0xff, 0x67, 0xff, 0x9d, 0xff, 0x67, 0xff, 0xa2, 0xff, 0x6b, 0xff, 0xa8, 0xff, 0x70, 0xff, 0xac, 0xff, 0x74, 0xff, 0xad, 0xff, 0x73, 0xff, 0xa8, 0xff, 0x68, 0xff, 0x9d, 0xff, 0x54, 0xff, 0x91, 0xff, 0x3c, 0xff, 0x85, 0xff, 0x26, 0xff, 0x7a, 0xff, 0x15, 0xff, 0x77, 0xff, 0x0e, 0xff, 0x7b, 0xff, 0x11, 0xff, 0x81, 0xff, 0x15, 0xff, 0x81, 0xff, 0x12, 0xff, 0x79, 0xff, 0x05, 0xff, 0x6d, 0xff, 0xf5, 0xfe, 0x66, 0xff, 0xe8, 0xfe, 0x68, 0xff, 0xe4, 0xfe, 0x74, 0xff, 0xea, 0xfe, 0x86, 0xff, 0xf7, 0xfe, 0x96, 0xff, 0x00, 0xff, 0xa3, 0xff, 0x09, 0xff, 0xb0, 0xff, 0x16, 0xff, 0xbe, 0xff, 0x25, 0xff, 0xcd, 0xff, 0x3a, 0xff, 0xdf, 0xff, 0x53, 0xff, 0xf4, 0xff, 0x72, 0xff, 0x06, 0x00, 0x8e, 0xff, 0x16, 0x00, 0xa7, 0xff, 0x25, 0x00, 0xbe, 0xff, 0x35, 0x00, 0xd5, 0xff, 0x48, 0x00, 0xee, 0xff, 0x5b, 0x00, 0x09, 0x00, 0x6e, 0x00, 0x29, 0x00, 0x7b, 0x00, 0x46, 0x00, 0x7d, 0x00, 0x57, 0x00, 0x74, 0x00, 0x5e, 0x00, 0x67, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5d, 0x00, 0x5b, 0x00, 0x62, 0x00, 0x60, 0x00, 0x6d, 0x00, 0x69, 0x00, 0x7b, 0x00, 0x6e, 0x00, 0x85, 0x00, 0x6b, 0x00, 0x88, 0x00, 0x5c, 0x00, 0x80, 0x00, 0x47, 0x00, 0x71, 0x00, 0x33, 0x00, 0x61, 0x00, 0x29, 0x00, 0x58, 0x00, 0x2b, 0x00, 0x58, 0x00, 0x36, 0x00, 0x5f, 0x00, 0x43, 0x00, 0x67, 0x00, 0x4a, 0x00, 0x68, 0x00, 0x49, 0x00, 0x61, 0x00, 0x44, 0x00, 0x56, 0x00, 0x40, 0x00, 0x4d, 0x00, 0x3e, 0x00, 0x47, 0x00, 0x44, 0x00, 0x49, 0x00, 0x4d, 0x00, 0x4f, 0x00, 0x57, 0x00, 0x54, 0x00, 0x5f, 0x00, 0x55, 0x00, 0x64, 0x00, 0x50, 0x00, 0x60, 0x00, 0x43, 0x00, 0x5c, 0x00, 0x38, 0x00, 0x5e, 0x00, 0x34, 0x00, 0x64, 0x00, 0x36, 0x00, 0x6a, 0x00, 0x3a, 0x00, 0x6e, 0x00, 0x3c, 0x00, 0x6f, 0x00, 0x3a, 0x00, 0x6d, 0x00, 0x34, 0x00, 0x69, 0x00, 0x2b, 0x00, 0x65, 0x00, 0x1f, 0x00, 0x63, 0x00, 0x15, 0x00, 0x60, 0x00, 0x0d, 0x00, 0x5c, 0x00, 0x07, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x54, 0x00, 0xf8, 0xff, 0x4b, 0x00, 0xeb, 0xff, 0x3f, 0x00, 0xd9, 0xff, 0x31, 0x00, 0xc5, 0xff, 0x25, 0x00, 0xb4, 0xff, 0x1e, 0x00, 0xa8, 0xff, 0x17, 0x00, 0x9d, 0xff, 0x0d, 0x00, 0x90, 0xff, 0x01, 0x00, 0x82, 0xff, 0xf3, 0xff, 0x73, 0xff, 0xe2, 0xff, 0x63, 0xff, 0xd5, 0xff, 0x58, 0xff, 0xcb, 0xff, 0x53, 0xff, 0xc3, 0xff, 0x54, 0xff, 0xbc, 0xff, 0x57, 0xff, 0xb5, 0xff, 0x59, 0xff, 0xae, 0xff, 0x5a, 0xff, 0xa6, 0xff, 0x58, 0xff, 0xa1, 0xff, 0x59, 0xff, 0xa3, 0xff, 0x61, 0xff, 0xa8, 0xff, 0x6e, 0xff, 0xae, 0xff, 0x7f, 0xff, 0xb3, 0xff, 0x91, 0xff, 0xb2, 0xff, 0x9e, 0xff, 0xab, 0xff, 0xa5, 0xff, 0xa2, 0xff, 0xab, 0xff, 0x9e, 0xff, 0xb4, 0xff, 0xa4, 0xff, 0xc7, 0xff, 0xb4, 0xff, 0xe2, 0xff, 0xc8, 0xff, 0x02, 0x00, 0xdb, 0xff, 0x22, 0x00, 0xe8, 0xff, 0x3c, 0x00, 0xf0, 0xff, 0x53, 0x00, 0xf5, 0xff, 0x66, 0x00, 0xf9, 0xff, 0x77, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x0c, 0x00, 0xa1, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0x32, 0x00, 0xdd, 0x00, 0x44, 0x00, 0xf8, 0x00, 0x50, 0x00, 0x0c, 0x01, 0x54, 0x00, 0x16, 0x01, 0x57, 0x00, 0x1d, 0x01, 0x59, 0x00, 0x25, 0x01, 0x5b, 0x00, 0x2b, 0x01, 0x5e, 0x00, 0x31, 0x01, 0x5e, 0x00, 0x33, 0x01, 0x58, 0x00, 0x2c, 0x01, 0x4e, 0x00, 0x1d, 0x01, 0x45, 0x00, 0x0a, 0x01, 0x41, 0x00, 0xf7, 0x00, 0x3f, 0x00, 0xe3, 0x00, 0x3d, 0x00, 0xd1, 0x00, 0x3e, 0x00, 0xc6, 0x00, 0x3e, 0x00, 0xbb, 0x00, 0x38, 0x00, 0xad, 0x00, 0x2e, 0x00, 0x9b, 0x00, 0x24, 0x00, 0x84, 0x00, 0x19, 0x00, 0x6a, 0x00, 0x12, 0x00, 0x4e, 0x00, 0x0c, 0x00, 0x32, 0x00, 0x07, 0x00, 0x17, 0x00, 0x01, 0x00, 0xfd, 0xff, 0xf7, 0xff, 0xe1, 0xff, 0xe4, 0xff, 0xc1, 0xff, 0xcf, 0xff, 0xa3, 0xff, 0xc1, 0xff, 0x8f, 0xff, 0xbc, 0xff, 0x85, 0xff, 0xbe, 0xff, 0x81, 0xff, 0xc4, 0xff, 0x81, 0xff, 0xca, 0xff, 0x7e, 0xff, 0xca, 0xff, 0x78, 0xff, 0xc3, 0xff, 0x6d, 0xff, 0xb8, 0xff, 0x63, 0xff, 0xac, 0xff, 0x5b, 0xff, 0xa6, 0xff, 0x5d, 0xff, 0xa6, 0xff, 0x68, 0xff, 0xa7, 0xff, 0x75, 0xff, 0xa6, 0xff, 0x7c, 0xff, 0xa0, 0xff, 0x7c, 0xff, 0x99, 0xff, 0x76, 0xff, 0x92, 0xff, 0x6e, 0xff, 0x91, 0xff, 0x6c, 0xff, 0x97, 0xff, 0x74, 0xff, 0xa2, 0xff, 0x82, 0xff, 0xb0, 0xff, 0x92, 0xff, 0xba, 0xff, 0x9f, 0xff, 0xbd, 0xff, 0xa4, 0xff, 0xbb, 0xff, 0xa0, 0xff, 0xb4, 0xff, 0x94, 0xff, 0xb2, 0xff, 0x8a, 0xff, 0xb6, 0xff, 0x83, 0xff, 0xbe, 0xff, 0x82, 0xff, 0xc5, 0xff, 0x85, 0xff, 0xc7, 0xff, 0x87, 0xff, 0xc3, 0xff, 0x87, 0xff, 0xbc, 0xff, 0x83, 0xff, 0xb7, 0xff, 0x82, 0xff, 0xb8, 0xff, 0x87, 0xff, 0xc0, 0xff, 0x94, 0xff, 0xcc, 0xff, 0xa5, 0xff, 0xd9, 0xff, 0xbb, 0xff, 0xe3, 0xff, 0xd1, 0xff, 0xe7, 0xff, 0xe2, 0xff, 0xe7, 0xff, 0xf3, 0xff, 0xe9, 0xff, 0x06, 0x00, 0xf3, 0xff, 0x21, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x14, 0x00, 0x5c, 0x00, 0x22, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x87, 0x00, 0x3c, 0x00, 0x9c, 0x00, 0x4d, 0x00, 0xb2, 0x00, 0x62, 0x00, 0xc7, 0x00, 0x74, 0x00, 0xd8, 0x00, 0x81, 0x00, 0xe4, 0x00, 0x8a, 0x00, 0xec, 0x00, 0x90, 0x00, 0xf1, 0x00, 0x93, 0x00, 0xf4, 0x00, 0x91, 0x00, 0xf3, 0x00, 0x8d, 0x00, 0xed, 0x00, 0x8e, 0x00, 0xe9, 0x00, 0x97, 0x00, 0xeb, 0x00, 0xa5, 0x00, 0xef, 0x00, 0xae, 0x00, 0xee, 0x00, 0xac, 0x00, 0xe5, 0x00, 0xa4, 0x00, 0xd9, 0x00, 0x96, 0x00, 0xca, 0x00, 0x84, 0x00, 0xb9, 0x00, 0x6f, 0x00, 0xa3, 0x00, 0x5b, 0x00, 0x8d, 0x00, 0x4f, 0x00, 0x7d, 0x00, 0x47, 0x00, 0x70, 0x00, 0x3b, 0x00, 0x5e, 0x00, 0x25, 0x00, 0x46, 0x00, 0x0a, 0x00, 0x29, 0x00, 0xef, 0xff, 0x10, 0x00, 0xd9, 0xff, 0xfc, 0xff, 0xc8, 0xff, 0xec, 0xff, 0xba, 0xff, 0xdd, 0xff, 0xac, 0xff, 0xcb, 0xff, 0xa0, 0xff, 0xb9, 0xff, 0x98, 0xff, 0xa9, 0xff, 0x96, 0xff, 0x9e, 0xff, 0x98, 0xff, 0x98, 0xff, 0x9a, 0xff, 0x92, 0xff, 0x9d, 0xff, 0x8d, 0xff, 0xa4, 0xff, 0x8d, 0xff, 0xaf, 0xff, 0x90, 0xff, 0xb9, 0xff, 0x92, 0xff, 0xc0, 0xff, 0x8f, 0xff, 0xc2, 0xff, 0x88, 0xff, 0xc3, 0xff, 0x7f, 0xff, 0xc6, 0xff, 0x76, 0xff, 0xd0, 0xff, 0x73, 0xff, 0xe3, 0xff, 0x78, 0xff, 0xf5, 0xff, 0x80, 0xff, 0xff, 0xff, 0x83, 0xff, 0xff, 0xff, 0x80, 0xff, 0xf4, 0xff, 0x77, 0xff, 0xe7, 0xff, 0x6e, 0xff, 0xe0, 0xff, 0x6b, 0xff, 0xe2, 0xff, 0x70, 0xff, 0xe6, 0xff, 0x79, 0xff, 0xec, 0xff, 0x84, 0xff, 0xef, 0xff, 0x8e, 0xff, 0xe8, 0xff, 0x90, 0xff, 0xd6, 0xff, 0x89, 0xff, 0xc6, 0xff, 0x83, 0xff, 0xbe, 0xff, 0x87, 0xff, 0xbe, 0xff, 0x92, 0xff, 0xc1, 0xff, 0xa0, 0xff, 0xc3, 0xff, 0xaf, 0xff, 0xc1, 0xff, 0xba, 0xff, 0xb8, 0xff, 0xbd, 0xff, 0xaf, 0xff, 0xbe, 0xff, 0xac, 0xff, 0xc1, 0xff, 0xb1, 0xff, 0xc8, 0xff, 0xbc, 0xff, 0xd5, 0xff, 0xcd, 0xff, 0xe7, 0xff, 0xdd, 0xff, 0xf9, 0xff, 0xe4, 0xff, 0x03, 0x00, 0xe2, 0xff, 0x07, 0x00, 0xde, 0xff, 0x09, 0x00, 0xde, 0xff, 0x0e, 0x00, 0xe7, 0xff, 0x19, 0x00, 0xfc, 0xff, 0x2c, 0x00, 0x15, 0x00, 0x41, 0x00, 0x29, 0x00, 0x52, 0x00, 0x30, 0x00, 0x59, 0x00, 0x2a, 0x00, 0x57, 0x00, 0x21, 0x00, 0x54, 0x00, 0x1c, 0x00, 0x55, 0x00, 0x21, 0x00, 0x5e, 0x00, 0x2d, 0x00, 0x6b, 0x00, 0x3c, 0x00, 0x7a, 0x00, 0x48, 0x00, 0x85, 0x00, 0x4c, 0x00, 0x88, 0x00, 0x49, 0x00, 0x87, 0x00, 0x3f, 0x00, 0x82, 0x00, 0x33, 0x00, 0x7d, 0x00, 0x2b, 0x00, 0x7d, 0x00, 0x28, 0x00, 0x81, 0x00, 0x29, 0x00, 0x86, 0x00, 0x29, 0x00, 0x88, 0x00, 0x26, 0x00, 0x87, 0x00, 0x1c, 0x00, 0x7f, 0x00, 0x0c, 0x00, 0x70, 0x00, 0xfc, 0xff, 0x61, 0x00, 0xf3, 0xff, 0x58, 0x00, 0xee, 0xff, 0x52, 0x00, 0xe6, 0xff, 0x4a, 0x00, 0xdb, 0xff, 0x3f, 0x00, 0xca, 0xff, 0x2d, 0x00, 0xb9, 0xff, 0x16, 0x00, 0xab, 0xff, 0x00, 0x00, 0xa2, 0xff, 0xeb, 0xff, 0x9d, 0xff, 0xdb, 0xff, 0x99, 0xff, 0xcb, 0xff, 0x93, 0xff, 0xb8, 0xff, 0x86, 0xff, 0x9f, 0xff, 0x74, 0xff, 0x80, 0xff, 0x62, 0xff, 0x64, 0xff, 0x5b, 0xff, 0x50, 0xff, 0x5f, 0xff, 0x45, 0xff, 0x68, 0xff, 0x3f, 0xff, 0x71, 0xff, 0x36, 0xff, 0x76, 0xff, 0x2b, 0xff, 0x79, 0xff, 0x20, 0xff, 0x7f, 0xff, 0x1a, 0xff, 0x8b, 0xff, 0x1b, 0xff, 0x9a, 0xff, 0x1f, 0xff, 0xac, 0xff, 0x26, 0xff, 0xc2, 0xff, 0x33, 0xff, 0xda, 0xff, 0x43, 0xff, 0xeb, 0xff, 0x51, 0xff, 0xf2, 0xff, 0x57, 0xff, 0xf1, 0xff, 0x58, 0xff, 0xf0, 0xff, 0x59, 0xff, 0xf6, 0xff, 0x63, 0xff, 0x02, 0x00, 0x72, 0xff, 0x0c, 0x00, 0x81, 0xff, 0x0e, 0x00, 0x8c, 0xff, 0x0b, 0x00, 0x93, 0xff, 0x04, 0x00, 0x99, 0xff, 0xfb, 0xff, 0x9f, 0xff, 0xf3, 0xff, 0xa5, 0xff, 0xf1, 0xff, 0xb1, 0xff, 0xfb, 0xff, 0xc5, 0xff, 0x0c, 0x00, 0xdd, 0xff, 0x1e, 0x00, 0xf6, 0xff, 0x2e, 0x00, 0x0c, 0x00, 0x37, 0x00, 0x1c, 0x00, 0x39, 0x00, 0x26, 0x00, 0x3d, 0x00, 0x31, 0x00, 0x48, 0x00, 0x42, 0x00, 0x5a, 0x00, 0x59, 0x00, 0x74, 0x00, 0x74, 0x00, 0x96, 0x00, 0x95, 0x00, 0xb6, 0x00, 0xb2, 0x00, 0xcc, 0x00, 0xc5, 0x00, 0xdc, 0x00, 0xd2, 0x00, 0xe9, 0x00, 0xdd, 0x00, 0xf2, 0x00, 0xe3, 0x00, 0xf8, 0x00, 0xe6, 0x00, 0xf9, 0x00, 0xe5, 0x00, 0xfb, 0x00, 0xe6, 0x00, 0xfe, 0x00, 0xea, 0x00, 0x06, 0x01, 0xf1, 0x00, 0x0d, 0x01, 0xf5, 0x00, 0x0c, 0x01, 0xf0, 0x00, 0x05, 0x01, 0xe6, 0x00, 0xfb, 0x00, 0xd9, 0x00, 0xf1, 0x00, 0xce, 0x00, 0xea, 0x00, 0xc9, 0x00, 0xeb, 0x00, 0xcb, 0x00, 0xed, 0x00, 0xce, 0x00, 0xe5, 0x00, 0xc7, 0x00, 0xd5, 0x00, 0xb9, 0x00, 0xbf, 0x00, 0xa6, 0x00, 0xa7, 0x00, 0x8f, 0x00, 0x90, 0x00, 0x78, 0x00, 0x7d, 0x00, 0x65, 0x00, 0x6a, 0x00, 0x52, 0x00, 0x57, 0x00, 0x3f, 0x00, 0x47, 0x00, 0x2e, 0x00, 0x3c, 0x00, 0x22, 0x00, 0x30, 0x00, 0x16, 0x00, 0x22, 0x00, 0x07, 0x00, 0x0f, 0x00, 0xf4, 0xff, 0xfb, 0xff, 0xe1, 0xff, 0xec, 0xff, 0xd1, 0xff, 0xe6, 0xff, 0xc9, 0xff, 0xe5, 0xff, 0xc5, 0xff, 0xe4, 0xff, 0xc1, 0xff, 0xdf, 0xff, 0xba, 0xff, 0xd5, 0xff, 0xb1, 0xff, 0xc6, 0xff, 0xa5, 0xff, 0xb5, 0xff, 0x98, 0xff, 0xa8, 0xff, 0x8e, 0xff, 0x9e, 0xff, 0x86, 0xff, 0x97, 0xff, 0x7e, 0xff, 0x90, 0xff, 0x77, 0xff, 0x89, 0xff, 0x71, 0xff, 0x83, 0xff, 0x6f, 0xff, 0x7d, 0xff, 0x70, 0xff, 0x74, 0xff, 0x71, 0xff, 0x68, 0xff, 0x70, 0xff, 0x5d, 0xff, 0x6c, 0xff, 0x57, 0xff, 0x6a, 0xff, 0x56, 0xff, 0x69, 0xff, 0x5a, 0xff, 0x6d, 0xff, 0x61, 0xff, 0x75, 0xff, 0x67, 0xff, 0x7f, 0xff, 0x6b, 0xff, 0x87, 0xff, 0x6d, 0xff, 0x8d, 0xff, 0x70, 0xff, 0x91, 0xff, 0x75, 0xff, 0x97, 0xff, 0x78, 0xff, 0x9a, 0xff, 0x7b, 0xff, 0x9e, 0xff, 0x7c, 0xff, 0xa3, 0xff, 0x81, 0xff, 0xac, 0xff, 0x8a, 0xff, 0xba, 0xff, 0x96, 0xff, 0xc9, 0xff, 0xa4, 0xff, 0xd9, 0xff, 0xb4, 0xff, 0xe7, 0xff, 0xc1, 0xff, 0xf4, 0xff, 0xcd, 0xff, 0x00, 0x00, 0xd8, 0xff, 0x0e, 0x00, 0xe5, 0xff, 0x23, 0x00, 0xf9, 0xff, 0x3f, 0x00, 0x11, 0x00, 0x5f, 0x00, 0x2d, 0x00, 0x7f, 0x00, 0x47, 0x00, 0x9a, 0x00, 0x56, 0x00, 0xab, 0x00, 0x5e, 0x00, 0xb6, 0x00, 0x5f, 0x00, 0xbe, 0x00, 0x5d, 0x00, 0xc5, 0x00, 0x5a, 0x00, 0xce, 0x00, 0x57, 0x00, 0xd6, 0x00, 0x53, 0x00, 0xdc, 0x00, 0x4c, 0x00, 0xdd, 0x00, 0x42, 0x00, 0xd9, 0x00, 0x32, 0x00, 0xcc, 0x00, 0x1c, 0x00, 0xba, 0x00, 0x08, 0x00, 0xa8, 0x00, 0xf7, 0xff, 0x99, 0x00, 0xe9, 0xff, 0x8c, 0x00, 0xdb, 0xff, 0x7e, 0x00, 0xcd, 0xff, 0x70, 0x00, 0xbf, 0xff, 0x5f, 0x00, 0xac, 0xff, 0x49, 0x00, 0x9a, 0xff, 0x31, 0x00, 0x8d, 0xff, 0x1d, 0x00, 0x87, 0xff, 0x0d, 0x00, 0x86, 0xff, 0xff, 0xff, 0x83, 0xff, 0xed, 0xff, 0x7c, 0xff, 0xd8, 0xff, 0x73, 0xff, 0xc0, 0xff, 0x64, 0xff, 0xa8, 0xff, 0x55, 0xff, 0x90, 0xff, 0x47, 0xff, 0x7a, 0xff, 0x41, 0xff, 0x69, 0xff, 0x43, 0xff, 0x5e, 0xff, 0x4a, 0xff, 0x55, 0xff, 0x53, 0xff, 0x4d, 0xff, 0x58, 0xff, 0x44, 0xff, 0x5c, 0xff, 0x3b, 0xff, 0x5e, 0xff, 0x35, 0xff, 0x5f, 0xff, 0x2e, 0xff, 0x5c, 0xff, 0x25, 0xff, 0x56, 0xff, 0x1b, 0xff, 0x59, 0xff, 0x19, 0xff, 0x6d, 0xff, 0x26, 0xff, 0x8b, 0xff, 0x3e, 0xff, 0x9e, 0xff, 0x4b, 0xff, 0x9c, 0xff, 0x45, 0xff, 0x92, 0xff, 0x37, 0xff, 0x90, 0xff, 0x34, 0xff, 0x9a, 0xff, 0x3c, 0xff, 0xa0, 0xff, 0x43, 0xff, 0x9d, 0xff, 0x42, 0xff, 0x9e, 0xff, 0x45, 0xff, 0xb0, 0xff, 0x5a, 0xff, 0xcd, 0xff, 0x7a, 0xff, 0xe4, 0xff, 0x94, 0xff, 0xeb, 0xff, 0x9f, 0xff, 0xe5, 0xff, 0x9b, 0xff, 0xd9, 0xff, 0x90, 0xff, 0xcc, 0xff, 0x85, 0xff, 0xca, 0xff, 0x85, 0xff, 0xd5, 0xff, 0x95, 0xff, 0xeb, 0xff, 0xae, 0xff, 0xfb, 0xff, 0xc0, 0xff, 0xfd, 0xff, 0xc0, 0xff, 0xf4, 0xff, 0xb2, 0xff, 0xed, 0xff, 0xa7, 0xff, 0xf4, 0xff, 0xac, 0xff, 0x05, 0x00, 0xbd, 0xff, 0x19, 0x00, 0xd3, 0xff, 0x2b, 0x00, 0xe6, 0xff, 0x37, 0x00, 0xf1, 0xff, 0x3e, 0x00, 0xf5, 0xff, 0x44, 0x00, 0xf6, 0xff, 0x49, 0x00, 0xf3, 0xff, 0x4e, 0x00, 0xf1, 0xff, 0x57, 0x00, 0xf6, 0xff, 0x6e, 0x00, 0x0c, 0x00, 0x97, 0x00, 0x36, 0x00, 0xc2, 0x00, 0x62, 0x00, 0xda, 0x00, 0x79, 0x00, 0xda, 0x00, 0x77, 0x00, 0xd3, 0x00, 0x6c, 0x00, 0xd5, 0x00, 0x6e, 0x00, 0xe5, 0x00, 0x82, 0x00, 0xfd, 0x00, 0xa2, 0x00, 0x16, 0x01, 0xc2, 0x00, 0x30, 0x01, 0xe2, 0x00, 0x44, 0x01, 0xfa, 0x00, 0x4b, 0x01, 0x03, 0x01, 0x46, 0x01, 0xfe, 0x00, 0x38, 0x01, 0xef, 0x00, 0x27, 0x01, 0xdf, 0x00, 0x1a, 0x01, 0xd7, 0x00, 0x18, 0x01, 0xdb, 0x00, 0x1d, 0x01, 0xe7, 0x00, 0x22, 0x01, 0xf0, 0x00, 0x18, 0x01, 0xe6, 0x00, 0xf7, 0x00, 0xc1, 0x00, 0xc5, 0x00, 0x8b, 0x00, 0x93, 0x00, 0x58, 0x00, 0x77, 0x00, 0x3b, 0x00, 0x72, 0x00, 0x37, 0x00, 0x7a, 0x00, 0x3e, 0x00, 0x78, 0x00, 0x38, 0x00, 0x5f, 0x00, 0x1c, 0x00, 0x35, 0x00, 0xee, 0xff, 0x0a, 0x00, 0xc3, 0xff, 0xf0, 0xff, 0xa8, 0xff, 0xe6, 0xff, 0xa0, 0xff, 0xde, 0xff, 0x9b, 0xff, 0xcc, 0xff, 0x8b, 0xff, 0xb2, 0xff, 0x72, 0xff, 0x97, 0xff, 0x5a, 0xff, 0x84, 0xff, 0x4c, 0xff, 0x79, 0xff, 0x48, 0xff, 0x6e, 0xff, 0x45, 0xff, 0x66, 0xff, 0x45, 0xff, 0x61, 0xff, 0x48, 0xff, 0x65, 0xff, 0x4f, 0xff, 0x70, 0xff, 0x5b, 0xff, 0x84, 0xff, 0x6f, 0xff, 0x9e, 0xff, 0x89, 0xff, 0xb5, 0xff, 0xa2, 0xff, 0xc3, 0xff, 0xb6, 0xff, 0xcc, 0xff, 0xc5, 0xff, 0xd8, 0xff, 0xd6, 0xff, 0xea, 0xff, 0xee, 0xff, 0x03, 0x00, 0x08, 0x00, 0x1c, 0x00, 0x20, 0x00, 0x2f, 0x00, 0x31, 0x00, 0x3c, 0x00, 0x3e, 0x00, 0x46, 0x00, 0x4b, 0x00, 0x4d, 0x00, 0x59, 0x00, 0x53, 0x00, 0x6a, 0x00, 0x5a, 0x00, 0x7b, 0x00, 0x60, 0x00, 0x89, 0x00, 0x61, 0x00, 0x8f, 0x00, 0x5e, 0x00, 0x90, 0x00, 0x60, 0x00, 0x95, 0x00, 0x67, 0x00, 0xa0, 0x00, 0x6f, 0x00, 0xae, 0x00, 0x75, 0x00, 0xbb, 0x00, 0x74, 0x00, 0xc1, 0x00, 0x6b, 0x00, 0xbe, 0x00, 0x5f, 0x00, 0xb6, 0x00, 0x54, 0x00, 0xb0, 0x00, 0x51, 0x00, 0xb2, 0x00, 0x56, 0x00, 0xbd, 0x00, 0x5c, 0x00, 0xc9, 0x00, 0x58, 0x00, 0xca, 0x00, 0x45, 0x00, 0xb8, 0x00, 0x26, 0x00, 0x97, 0x00, 0x0c, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x01, 0x00, 0x68, 0x00, 0x08, 0x00, 0x6d, 0x00, 0x0c, 0x00, 0x70, 0x00, 0x04, 0x00, 0x67, 0x00, 0xf3, 0xff, 0x52, 0x00, 0xdd, 0xff, 0x33, 0x00, 0xc6, 0xff, 0x13, 0x00, 0xb1, 0xff, 0xf3, 0xff, 0x9c, 0xff, 0xd8, 0xff, 0x8e, 0xff, 0xc5, 0xff, 0x84, 0xff, 0xb9, 0xff, 0x7f, 0xff, 0xaf, 0xff, 0x79, 0xff, 0xa1, 0xff, 0x6b, 0xff, 0x89, 0xff, 0x55, 0xff, 0x69, 0xff, 0x3d, 0xff, 0x48, 0xff, 0x2e, 0xff, 0x32, 0xff, 0x2b, 0xff, 0x2a, 0xff, 0x2f, 0xff, 0x2d, 0xff, 0x36, 0xff, 0x35, 0xff, 0x38, 0xff, 0x3a, 0xff, 0x33, 0xff, 0x38, 0xff, 0x2e, 0xff, 0x36, 0xff, 0x2f, 0xff, 0x3a, 0xff, 0x39, 0xff, 0x49, 0xff, 0x44, 0xff, 0x5c, 0xff, 0x4d, 0xff, 0x6c, 0xff, 0x54, 0xff, 0x77, 0xff, 0x59, 0xff, 0x7e, 0xff, 0x65, 0xff, 0x89, 0xff, 0x77, 0xff, 0x9b, 0xff, 0x87, 0xff, 0xac, 0xff, 0x91, 0xff, 0xb8, 0xff, 0x96, 0xff, 0xc0, 0xff, 0x98, 0xff, 0xc7, 0xff, 0x9c, 0xff, 0xcd, 0xff, 0xa2, 0xff, 0xd4, 0xff, 0xac, 0xff, 0xdb, 0xff, 0xb9, 0xff, 0xe3, 0xff, 0xc9, 0xff, 0xeb, 0xff, 0xdb, 0xff, 0xf8, 0xff, 0xec, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x10, 0x00, 0x00, 0x00, 0x13, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x02, 0x00, 0x09, 0x00, 0x06, 0x00, 0x07, 0x00, 0x12, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x18, 0x00, 0x28, 0x00, 0x1d, 0x00, 0x2b, 0x00, 0x19, 0x00, 0x27, 0x00, 0x0f, 0x00, 0x1d, 0x00, 0x01, 0x00, 0x15, 0x00, 0xf8, 0xff, 0x16, 0x00, 0xf8, 0xff, 0x20, 0x00, 0x01, 0x00, 0x2e, 0x00, 0x0d, 0x00, 0x3d, 0x00, 0x18, 0x00, 0x4a, 0x00, 0x21, 0x00, 0x52, 0x00, 0x22, 0x00, 0x56, 0x00, 0x20, 0x00, 0x5a, 0x00, 0x1f, 0x00, 0x5f, 0x00, 0x22, 0x00, 0x67, 0x00, 0x2a, 0x00, 0x74, 0x00, 0x38, 0x00, 0x85, 0x00, 0x48, 0x00, 0x95, 0x00, 0x53, 0x00, 0x9d, 0x00, 0x57, 0x00, 0x9f, 0x00, 0x54, 0x00, 0xa0, 0x00, 0x52, 0x00, 0xa6, 0x00, 0x56, 0x00, 0xb3, 0x00, 0x64, 0x00, 0xc2, 0x00, 0x76, 0x00, 0xcf, 0x00, 0x87, 0x00, 0xd3, 0x00, 0x91, 0x00, 0xca, 0x00, 0x8e, 0x00, 0xb8, 0x00, 0x82, 0x00, 0xa6, 0x00, 0x76, 0x00, 0x98, 0x00, 0x70, 0x00, 0x8c, 0x00, 0x6e, 0x00, 0x81, 0x00, 0x6d, 0x00, 0x77, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6a, 0x00, 0x5b, 0x00, 0x61, 0x00, 0x46, 0x00, 0x54, 0x00, 0x30, 0x00, 0x47, 0x00, 0x1c, 0x00, 0x3e, 0x00, 0x08, 0x00, 0x37, 0x00, 0xf3, 0xff, 0x2f, 0x00, 0xdc, 0xff, 0x24, 0x00, 0xc0, 0xff, 0x12, 0x00, 0xa3, 0xff, 0xfc, 0xff, 0x88, 0xff, 0xe4, 0xff, 0x73, 0xff, 0xcf, 0xff, 0x64, 0xff, 0xc1, 0xff, 0x57, 0xff, 0xb9, 0xff, 0x45, 0xff, 0xb1, 0xff, 0x2d, 0xff, 0xa5, 0xff, 0x13, 0xff, 0x96, 0xff, 0xfc, 0xfe, 0x88, 0xff, 0xec, 0xfe, 0x7d, 0xff, 0xe3, 0xfe, 0x79, 0xff, 0xe4, 0xfe, 0x7e, 0xff, 0xec, 0xfe, 0x8a, 0xff, 0xf6, 0xfe, 0x98, 0xff, 0xfe, 0xfe, 0xa7, 0xff, 0x03, 0xff, 0xb4, 0xff, 0x08, 0xff, 0xc1, 0xff, 0x0d, 0xff, 0xcc, 0xff, 0x15, 0xff, 0xd9, 0xff, 0x22, 0xff, 0xe8, 0xff, 0x34, 0xff, 0xfa, 0xff, 0x46, 0xff, 0x0b, 0x00, 0x55, 0xff, 0x17, 0x00, 0x61, 0xff, 0x1f, 0x00, 0x69, 0xff, 0x21, 0x00, 0x74, 0xff, 0x25, 0x00, 0x88, 0xff, 0x31, 0x00, 0xa6, 0xff, 0x45, 0x00, 0xc9, 0xff, 0x5e, 0x00, 0xea, 0xff, 0x71, 0x00, 0x04, 0x00, 0x7c, 0x00, 0x1a, 0x00, 0x82, 0x00, 0x33, 0x00, 0x8a, 0x00, 0x51, 0x00, 0x97, 0x00, 0x75, 0x00, 0xa9, 0x00, 0x9b, 0x00, 0xbc, 0x00, 0xb8, 0x00, 0xc9, 0x00, 0xc7, 0x00, 0xc9, 0x00, 0xc8, 0x00, 0xbd, 0x00, 0xc4, 0x00, 0xab, 0x00, 0xc5, 0x00, 0x9d, 0x00, 0xce, 0x00, 0x95, 0x00, 0xdf, 0x00, 0x94, 0x00, 0xef, 0x00, 0x93, 0x00, 0xf8, 0x00, 0x8d, 0x00, 0xf8, 0x00, 0x82, 0x00, 0xf4, 0x00, 0x78, 0x00, 0xee, 0x00, 0x6f, 0x00, 0xe6, 0x00, 0x66, 0x00, 0xe3, 0x00, 0x60, 0x00, 0xe2, 0x00, 0x5a, 0x00, 0xe1, 0x00, 0x52, 0x00, 0xda, 0x00, 0x45, 0x00, 0xcf, 0x00, 0x35, 0x00, 0xc0, 0x00, 0x25, 0x00, 0xb1, 0x00, 0x17, 0x00, 0xa8, 0x00, 0x10, 0x00, 0xa5, 0x00, 0x0f, 0x00, 0xa4, 0x00, 0x11, 0x00, 0xa2, 0x00, 0x0f, 0x00, 0x98, 0x00, 0x07, 0x00, 0x85, 0x00, 0xf6, 0xff, 0x6f, 0x00, 0xe2, 0xff, 0x5b, 0x00, 0xd1, 0xff, 0x4d, 0x00, 0xc8, 0xff, 0x45, 0x00, 0xc6, 0xff, 0x3b, 0x00, 0xc3, 0xff, 0x2f, 0x00, 0xc0, 0xff, 0x1b, 0x00, 0xb9, 0xff, 0xfe, 0xff, 0xaa, 0xff, 0xda, 0xff, 0x96, 0xff, 0xb4, 0xff, 0x7e, 0xff, 0x94, 0xff, 0x69, 0xff, 0x7f, 0xff, 0x5e, 0xff, 0x72, 0xff, 0x5b, 0xff, 0x69, 0xff, 0x5f, 0xff, 0x5e, 0xff, 0x65, 0xff, 0x4e, 0xff, 0x6a, 0xff, 0x37, 0xff, 0x66, 0xff, 0x1b, 0xff, 0x5a, 0xff, 0x01, 0xff, 0x4c, 0xff, 0xea, 0xfe, 0x3d, 0xff, 0xd7, 0xfe, 0x30, 0xff, 0xc7, 0xfe, 0x26, 0xff, 0xba, 0xfe, 0x1f, 0xff, 0xad, 0xfe, 0x17, 0xff, 0xa0, 0xfe, 0x0f, 0xff, 0x96, 0xfe, 0x08, 0xff, 0x92, 0xfe, 0x04, 0xff, 0x95, 0xfe, 0x06, 0xff, 0x9c, 0xfe, 0x0a, 0xff, 0xa5, 0xfe, 0x10, 0xff, 0xac, 0xfe, 0x14, 0xff, 0xb4, 0xfe, 0x19, 0xff, 0xc2, 0xfe, 0x20, 0xff, 0xd5, 0xfe, 0x2a, 0xff, 0xf1, 0xfe, 0x37, 0xff, 0x13, 0xff, 0x4a, 0xff, 0x3a, 0xff, 0x61, 0xff, 0x5d, 0xff, 0x79, 0xff, 0x7a, 0xff, 0x8e, 0xff, 0x92, 0xff, 0xa0, 0xff, 0xa8, 0xff, 0xae, 0xff, 0xc1, 0xff, 0xbc, 0xff, 0xe1, 0xff, 0xcc, 0xff, 0x05, 0x00, 0xe0, 0xff, 0x2d, 0x00, 0xf7, 0xff, 0x57, 0x00, 0x11, 0x00, 0x7f, 0x00, 0x2b, 0x00, 0xa2, 0x00, 0x44, 0x00, 0xbb, 0x00, 0x55, 0x00, 0xcc, 0x00, 0x5f, 0x00, 0xde, 0x00, 0x69, 0x00, 0xf1, 0x00, 0x74, 0x00, 0x04, 0x01, 0x7f, 0x00, 0x17, 0x01, 0x89, 0x00, 0x2c, 0x01, 0x94, 0x00, 0x40, 0x01, 0x9d, 0x00, 0x52, 0x01, 0xa4, 0x00, 0x60, 0x01, 0xa6, 0x00, 0x68, 0x01, 0xa6, 0x00, 0x67, 0x01, 0xa1, 0x00, 0x5e, 0x01, 0x97, 0x00, 0x4e, 0x01, 0x8a, 0x00, 0x3c, 0x01, 0x79, 0x00, 0x2a, 0x01, 0x66, 0x00, 0x1a, 0x01, 0x4f, 0x00, 0x09, 0x01, 0x37, 0x00, 0xf9, 0x00, 0x23, 0x00, 0xeb, 0x00, 0x15, 0x00, 0xdd, 0x00, 0x0e, 0x00, 0xce, 0x00, 0x09, 0x00, 0xbc, 0x00, 0x02, 0x00, 0xaa, 0x00, 0xf8, 0xff, 0x98, 0x00, 0xeb, 0xff, 0x89, 0x00, 0xdd, 0xff, 0x7f, 0x00, 0xd2, 0xff, 0x77, 0x00, 0xca, 0xff, 0x6e, 0x00, 0xc6, 0xff, 0x62, 0x00, 0xc4, 0xff, 0x55, 0x00, 0xc5, 0xff, 0x48, 0x00, 0xc7, 0xff, 0x38, 0x00, 0xc5, 0xff, 0x24, 0x00, 0xbd, 0xff, 0x0d, 0x00, 0xb2, 0xff, 0xf4, 0xff, 0xa7, 0xff, 0xdc, 0xff, 0x9e, 0xff, 0xc9, 0xff, 0x9d, 0xff, 0xb6, 0xff, 0x9f, 0xff, 0xa3, 0xff, 0xa1, 0xff, 0x91, 0xff, 0xa4, 0xff, 0x81, 0xff, 0xaa, 0xff, 0x73, 0xff, 0xb1, 0xff, 0x63, 0xff, 0xb6, 0xff, 0x4f, 0xff, 0xb7, 0xff, 0x38, 0xff, 0xb2, 0xff, 0x21, 0xff, 0xab, 0xff, 0x10, 0xff, 0xa6, 0xff, 0x06, 0xff, 0xa6, 0xff, 0xff, 0xfe, 0xa8, 0xff, 0xf9, 0xfe, 0xaa, 0xff, 0xf2, 0xfe, 0xac, 0xff, 0xee, 0xfe, 0xaf, 0xff, 0xef, 0xfe, 0xb6, 0xff, 0xef, 0xfe, 0xb9, 0xff, 0xf0, 0xfe, 0xba, 0xff, 0xf0, 0xfe, 0xb9, 0xff, 0xf6, 0xfe, 0xb9, 0xff, 0x00, 0xff, 0xbe, 0xff, 0x0f, 0xff, 0xca, 0xff, 0x24, 0xff, 0xde, 0xff, 0x3d, 0xff, 0xf7, 0xff, 0x57, 0xff, 0x0f, 0x00, 0x6e, 0xff, 0x21, 0x00, 0x82, 0xff, 0x2d, 0x00, 0x93, 0xff, 0x35, 0x00, 0xa3, 0xff, 0x3f, 0x00, 0xb7, 0xff, 0x4f, 0x00, 0xd1, 0xff, 0x65, 0x00, 0xed, 0xff, 0x7c, 0x00, 0x0b, 0x00, 0x93, 0x00, 0x28, 0x00, 0xa6, 0x00, 0x41, 0x00, 0xb7, 0x00, 0x54, 0x00, 0xc5, 0x00, 0x64, 0x00, 0xd2, 0x00, 0x74, 0x00, 0xe0, 0x00, 0x85, 0x00, 0xed, 0x00, 0x95, 0x00, 0xf8, 0x00, 0xa3, 0x00, 0xfd, 0x00, 0xab, 0x00, 0xfd, 0x00, 0xac, 0x00, 0xf6, 0x00, 0xab, 0x00, 0xee, 0x00, 0xa9, 0x00, 0xe7, 0x00, 0xa5, 0x00, 0xde, 0x00, 0x9f, 0x00, 0xd3, 0x00, 0x98, 0x00, 0xc4, 0x00, 0x95, 0x00, 0xb7, 0x00, 0x96, 0x00, 0xa8, 0x00, 0x96, 0x00, 0x95, 0x00, 0x93, 0x00, 0x7f, 0x00, 0x91, 0x00, 0x6a, 0x00, 0x90, 0x00, 0x5a, 0x00, 0x93, 0x00, 0x50, 0x00, 0x99, 0x00, 0x48, 0x00, 0x9c, 0x00, 0x3e, 0x00, 0x99, 0x00, 0x2b, 0x00, 0x8e, 0x00, 0x10, 0x00, 0x7e, 0x00, 0xf4, 0xff, 0x72, 0x00, 0xe0, 0xff, 0x69, 0x00, 0xd3, 0xff, 0x63, 0x00, 0xcb, 0xff, 0x63, 0x00, 0xc8, 0xff, 0x64, 0x00, 0xc4, 0xff, 0x63, 0x00, 0xbf, 0xff, 0x60, 0x00, 0xba, 0xff, 0x5b, 0x00, 0xb9, 0xff, 0x54, 0x00, 0xba, 0xff, 0x4a, 0x00, 0xbb, 0xff, 0x3f, 0x00, 0xba, 0xff, 0x34, 0x00, 0xb9, 0xff, 0x2a, 0x00, 0xb5, 0xff, 0x1e, 0x00, 0xae, 0xff, 0x12, 0x00, 0xa9, 0xff, 0x06, 0x00, 0xa5, 0xff, 0xf7, 0xff, 0xa3, 0xff, 0xe9, 0xff, 0xa4, 0xff, 0xdd, 0xff, 0xa4, 0xff, 0xcf, 0xff, 0xa1, 0xff, 0xc0, 0xff, 0x96, 0xff, 0xb0, 0xff, 0x87, 0xff, 0xa0, 0xff, 0x77, 0xff, 0x8d, 0xff, 0x65, 0xff, 0x7b, 0xff, 0x58, 0xff, 0x71, 0xff, 0x54, 0xff, 0x6c, 0xff, 0x55, 0xff, 0x68, 0xff, 0x54, 0xff, 0x66, 0xff, 0x51, 0xff, 0x62, 0xff, 0x4b, 0xff, 0x5f, 0xff, 0x43, 0xff, 0x60, 0xff, 0x40, 0xff, 0x66, 0xff, 0x43, 0xff, 0x6d, 0xff, 0x4a, 0xff, 0x78, 0xff, 0x55, 0xff, 0x87, 0xff, 0x64, 0xff, 0x99, 0xff, 0x75, 0xff, 0xa9, 0xff, 0x83, 0xff, 0xb7, 0xff, 0x91, 0xff, 0xc6, 0xff, 0xa3, 0xff, 0xd6, 0xff, 0xb7, 0xff, 0xe6, 0xff, 0xcb, 0xff, 0xf6, 0xff, 0xdf, 0xff, 0x07, 0x00, 0xf2, 0xff, 0x15, 0x00, 0x04, 0x00, 0x22, 0x00, 0x17, 0x00, 0x2c, 0x00, 0x28, 0x00, 0x32, 0x00, 0x34, 0x00, 0x39, 0x00, 0x3f, 0x00, 0x43, 0x00, 0x4b, 0x00, 0x4d, 0x00, 0x55, 0x00, 0x53, 0x00, 0x5b, 0x00, 0x54, 0x00, 0x5e, 0x00, 0x52, 0x00, 0x5f, 0x00, 0x53, 0x00, 0x62, 0x00, 0x5a, 0x00, 0x6a, 0x00, 0x69, 0x00, 0x78, 0x00, 0x7a, 0x00, 0x85, 0x00, 0x88, 0x00, 0x8f, 0x00, 0x93, 0x00, 0x94, 0x00, 0x9a, 0x00, 0x94, 0x00, 0x9d, 0x00, 0x92, 0x00, 0x9d, 0x00, 0x90, 0x00, 0x9a, 0x00, 0x8e, 0x00, 0x98, 0x00, 0x8e, 0x00, 0x9e, 0x00, 0x93, 0x00, 0xaa, 0x00, 0x9b, 0x00, 0xb6, 0x00, 0xa0, 0x00, 0xbf, 0x00, 0xa3, 0x00, 0xc4, 0x00, 0xa5, 0x00, 0xc6, 0x00, 0xa6, 0x00, 0xc1, 0x00, 0xa3, 0x00, 0xbb, 0x00, 0x9d, 0x00, 0xb9, 0x00, 0x98, 0x00, 0xba, 0x00, 0x94, 0x00, 0xbb, 0x00, 0x8e, 0x00, 0xb5, 0x00, 0x85, 0x00, 0xa8, 0x00, 0x76, 0x00, 0x98, 0x00, 0x69, 0x00, 0x8c, 0x00, 0x62, 0x00, 0x85, 0x00, 0x61, 0x00, 0x7e, 0x00, 0x60, 0x00, 0x74, 0x00, 0x5c, 0x00, 0x63, 0x00, 0x51, 0x00, 0x4b, 0x00, 0x3e, 0x00, 0x2d, 0x00, 0x26, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0xf3, 0xff, 0x00, 0x00, 0xd8, 0xff, 0xf5, 0xff, 0xbf, 0xff, 0xef, 0xff, 0xa9, 0xff, 0xea, 0xff, 0x92, 0xff, 0xe1, 0xff, 0x79, 0xff, 0xd2, 0xff, 0x5f, 0xff, 0xc3, 0xff, 0x49, 0xff, 0xbc, 0xff, 0x35, 0xff, 0xba, 0xff, 0x24, 0xff, 0xbc, 0xff, 0x18, 0xff, 0xbd, 0xff, 0x11, 0xff, 0xbb, 0xff, 0x0d, 0xff, 0xb8, 0xff, 0x10, 0xff, 0xb9, 0xff, 0x15, 0xff, 0xbd, 0xff, 0x1b, 0xff, 0xc2, 0xff, 0x23, 0xff, 0xc9, 0xff, 0x2d, 0xff, 0xd4, 0xff, 0x3a, 0xff, 0xdf, 0xff, 0x47, 0xff, 0xe5, 0xff, 0x4f, 0xff, 0xe5, 0xff, 0x59, 0xff, 0xe2, 0xff, 0x63, 0xff, 0xe0, 0xff, 0x6c, 0xff, 0xe2, 0xff, 0x77, 0xff, 0xe8, 0xff, 0x80, 0xff, 0xef, 0xff, 0x89, 0xff, 0xf5, 0xff, 0x94, 0xff, 0xfa, 0xff, 0xa0, 0xff, 0xfb, 0xff, 0xaa, 0xff, 0xfa, 0xff, 0xb5, 0xff, 0xfa, 0xff, 0xc1, 0xff, 0xfc, 0xff, 0xcf, 0xff, 0x05, 0x00, 0xe1, 0xff, 0x11, 0x00, 0xf1, 0xff, 0x1b, 0x00, 0xfc, 0xff, 0x1e, 0x00, 0x02, 0x00, 0x1b, 0x00, 0x09, 0x00, 0x16, 0x00, 0x14, 0x00, 0x14, 0x00, 0x21, 0x00, 0x16, 0x00, 0x2f, 0x00, 0x19, 0x00, 0x3e, 0x00, 0x1e, 0x00, 0x4e, 0x00, 0x23, 0x00, 0x5b, 0x00, 0x23, 0x00, 0x65, 0x00, 0x1f, 0x00, 0x70, 0x00, 0x1c, 0x00, 0x7f, 0x00, 0x20, 0x00, 0x91, 0x00, 0x29, 0x00, 0xa3, 0x00, 0x34, 0x00, 0xaf, 0x00, 0x3a, 0x00, 0xb8, 0x00, 0x3c, 0x00, 0xbc, 0x00, 0x38, 0x00, 0xbc, 0x00, 0x2f, 0x00, 0xbc, 0x00, 0x25, 0x00, 0xbe, 0x00, 0x20, 0x00, 0xc2, 0x00, 0x21, 0x00, 0xc2, 0x00, 0x22, 0x00, 0xbf, 0x00, 0x23, 0x00, 0xba, 0x00, 0x22, 0x00, 0xb1, 0x00, 0x1c, 0x00, 0xa2, 0x00, 0x0f, 0x00, 0x92, 0x00, 0x00, 0x00, 0x84, 0x00, 0xf6, 0xff, 0x78, 0x00, 0xf1, 0xff, 0x6b, 0x00, 0xf1, 0xff, 0x5f, 0x00, 0xf6, 0xff, 0x51, 0x00, 0xf9, 0xff, 0x3c, 0x00, 0xf4, 0xff, 0x21, 0x00, 0xe5, 0xff, 0x00, 0x00, 0xd1, 0xff, 0xe0, 0xff, 0xbe, 0xff, 0xc4, 0xff, 0xb3, 0xff, 0xae, 0xff, 0xad, 0xff, 0x9c, 0xff, 0xaa, 0xff, 0x89, 0xff, 0xa5, 0xff, 0x70, 0xff, 0x99, 0xff, 0x4f, 0xff, 0x84, 0xff, 0x2d, 0xff, 0x6d, 0xff, 0x14, 0xff, 0x5f, 0xff, 0x0c, 0xff, 0x64, 0xff, 0x07, 0xff, 0x6a, 0xff, 0xf5, 0xfe, 0x63, 0xff, 0xda, 0xfe, 0x50, 0xff, 0xc8, 0xfe, 0x44, 0xff, 0xc5, 0xfe, 0x46, 0xff, 0xc6, 0xfe, 0x4c, 0xff, 0xc0, 0xfe, 0x4f, 0xff, 0xb2, 0xfe, 0x4b, 0xff, 0xa8, 0xfe, 0x4b, 0xff, 0xae, 0xfe, 0x59, 0xff, 0xc1, 0xfe, 0x71, 0xff, 0xd1, 0xfe, 0x81, 0xff, 0xd5, 0xfe, 0x82, 0xff, 0xd7, 0xfe, 0x81, 0xff, 0xe0, 0xfe, 0x89, 0xff, 0xf3, 0xfe, 0x9c, 0xff, 0x0e, 0xff, 0xb7, 0xff, 0x29, 0xff, 0xce, 0xff, 0x38, 0xff, 0xd4, 0xff, 0x40, 0xff, 0xce, 0xff, 0x4f, 0xff, 0xcd, 0xff, 0x67, 0xff, 0xd8, 0xff, 0x81, 0xff, 0xe6, 0xff, 0x96, 0xff, 0xf1, 0xff, 0xa8, 0xff, 0xf8, 0xff, 0xba, 0xff, 0xf9, 0xff, 0xce, 0xff, 0xf5, 0xff, 0xe4, 0xff, 0xef, 0xff, 0xfa, 0xff, 0xec, 0xff, 0x10, 0x00, 0xec, 0xff, 0x25, 0x00, 0xf0, 0xff, 0x38, 0x00, 0xf4, 0xff, 0x45, 0x00, 0xf0, 0xff, 0x50, 0x00, 0xeb, 0xff, 0x60, 0x00, 0xeb, 0xff, 0x76, 0x00, 0xf5, 0xff, 0x8e, 0x00, 0x02, 0x00, 0xa2, 0x00, 0x10, 0x00, 0xb0, 0x00, 0x1d, 0x00, 0xb8, 0x00, 0x27, 0x00, 0xbd, 0x00, 0x30, 0x00, 0xc4, 0x00, 0x3b, 0x00, 0xd0, 0x00, 0x48, 0x00, 0xdd, 0x00, 0x54, 0x00, 0xe0, 0x00, 0x59, 0x00, 0xdd, 0x00, 0x5a, 0x00, 0xd8, 0x00, 0x5d, 0x00, 0xd7, 0x00, 0x65, 0x00, 0xd6, 0x00, 0x6f, 0x00, 0xd2, 0x00, 0x74, 0x00, 0xce, 0x00, 0x77, 0x00, 0xcd, 0x00, 0x7d, 0x00, 0xce, 0x00, 0x85, 0x00, 0xcd, 0x00, 0x8e, 0x00, 0xcc, 0x00, 0x96, 0x00, 0xcb, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0xa6, 0x00, 0xcc, 0x00, 0xab, 0x00, 0xcc, 0x00, 0xaf, 0x00, 0xc9, 0x00, 0xb0, 0x00, 0xc2, 0x00, 0xaf, 0x00, 0xb8, 0x00, 0xaf, 0x00, 0xab, 0x00, 0xad, 0x00, 0x9c, 0x00, 0xab, 0x00, 0x8e, 0x00, 0xa6, 0x00, 0x7e, 0x00, 0x9c, 0x00, 0x6a, 0x00, 0x8d, 0x00, 0x56, 0x00, 0x81, 0x00, 0x44, 0x00, 0x7b, 0x00, 0x31, 0x00, 0x75, 0x00, 0x1c, 0x00, 0x6a, 0x00, 0x05, 0x00, 0x59, 0x00, 0xf1, 0xff, 0x48, 0x00, 0xdc, 0xff, 0x36, 0x00, 0xc4, 0xff, 0x22, 0x00, 0xa8, 0xff, 0x0a, 0x00, 0x89, 0xff, 0xef, 0xff, 0x6c, 0xff, 0xd5, 0xff, 0x52, 0xff, 0xbf, 0xff, 0x3c, 0xff, 0xae, 0xff, 0x27, 0xff, 0x9e, 0xff, 0x16, 0xff, 0x91, 0xff, 0x0b, 0xff, 0x85, 0xff, 0x03, 0xff, 0x7b, 0xff, 0xfd, 0xfe, 0x73, 0xff, 0xf8, 0xfe, 0x6f, 0xff, 0xf8, 0xfe, 0x6f, 0xff, 0xfb, 0xfe, 0x70, 0xff, 0x03, 0xff, 0x70, 0xff, 0x0c, 0xff, 0x6d, 0xff, 0x16, 0xff, 0x6a, 0xff, 0x26, 0xff, 0x6d, 0xff, 0x38, 0xff, 0x74, 0xff, 0x49, 0xff, 0x7a, 0xff, 0x57, 0xff, 0x7a, 0xff, 0x67, 0xff, 0x77, 0xff, 0x7a, 0xff, 0x75, 0xff, 0x91, 0xff, 0x77, 0xff, 0xac, 0xff, 0x7f, 0xff, 0xc4, 0xff, 0x89, 0xff, 0xd9, 0xff, 0x93, 0xff, 0xed, 0xff, 0x9f, 0xff, 0x07, 0x00, 0xb0, 0xff, 0x22, 0x00, 0xc1, 0xff, 0x3a, 0x00, 0xce, 0xff, 0x4f, 0x00, 0xd9, 0xff, 0x5c, 0x00, 0xe1, 0xff, 0x66, 0x00, 0xea, 0xff, 0x70, 0x00, 0xf7, 0xff, 0x7d, 0x00, 0x06, 0x00, 0x89, 0x00, 0x15, 0x00, 0x92, 0x00, 0x1e, 0x00, 0x99, 0x00, 0x24, 0x00, 0xa3, 0x00, 0x2c, 0x00, 0xad, 0x00, 0x33, 0x00, 0xb4, 0x00, 0x38, 0x00, 0xb7, 0x00, 0x3b, 0x00, 0xb8, 0x00, 0x3e, 0x00, 0xbc, 0x00, 0x41, 0x00, 0xbf, 0x00, 0x42, 0x00, 0xc5, 0x00, 0x42, 0x00, 0xca, 0x00, 0x40, 0x00, 0xd1, 0x00, 0x41, 0x00, 0xd9, 0x00, 0x46, 0x00, 0xe0, 0x00, 0x4a, 0x00, 0xe5, 0x00, 0x4d, 0x00, 0xec, 0x00, 0x52, 0x00, 0xf4, 0x00, 0x57, 0x00, 0xfa, 0x00, 0x59, 0x00, 0xff, 0x00, 0x5b, 0x00, 0x02, 0x01, 0x5e, 0x00, 0x02, 0x01, 0x61, 0x00, 0xfe, 0x00, 0x63, 0x00, 0xf4, 0x00, 0x63, 0x00, 0xe7, 0x00, 0x62, 0x00, 0xd5, 0x00, 0x5b, 0x00, 0xc5, 0x00, 0x54, 0x00, 0xc0, 0x00, 0x56, 0x00, 0xbc, 0x00, 0x5a, 0x00, 0xae, 0x00, 0x56, 0x00, 0x98, 0x00, 0x4e, 0x00, 0x83, 0x00, 0x4a, 0x00, 0x74, 0x00, 0x4e, 0x00, 0x66, 0x00, 0x57, 0x00, 0x4f, 0x00, 0x57, 0x00, 0x25, 0x00, 0x44, 0x00, 0xf7, 0xff, 0x29, 0x00, 0xdd, 0xff, 0x1e, 0x00, 0xd9, 0xff, 0x28, 0x00, 0xd2, 0xff, 0x2d, 0x00, 0xb2, 0xff, 0x19, 0x00, 0x80, 0xff, 0xf3, 0xff, 0x51, 0xff, 0xd1, 0xff, 0x32, 0xff, 0xbf, 0xff, 0x1e, 0xff, 0xb6, 0xff, 0x07, 0xff, 0xa7, 0xff, 0xe8, 0xfe, 0x8a, 0xff, 0xca, 0xfe, 0x68, 0xff, 0xbd, 0xfe, 0x53, 0xff, 0xbb, 0xfe, 0x48, 0xff, 0xb8, 0xfe, 0x41, 0xff, 0xb2, 0xfe, 0x39, 0xff, 0xaf, 0xfe, 0x36, 0xff, 0xb2, 0xfe, 0x38, 0xff, 0xbb, 0xfe, 0x3d, 0xff, 0xc8, 0xfe, 0x41, 0xff, 0xd9, 0xfe, 0x46, 0xff, 0xed, 0xfe, 0x4e, 0xff, 0xfc, 0xfe, 0x55, 0xff, 0x05, 0xff, 0x59, 0xff, 0x09, 0xff, 0x5f, 0xff, 0x11, 0xff, 0x68, 0xff, 0x1f, 0xff, 0x76, 0xff, 0x32, 0xff, 0x84, 0xff, 0x43, 0xff, 0x90, 0xff, 0x4f, 0xff, 0x97, 0xff, 0x56, 0xff, 0x9a, 0xff, 0x58, 0xff, 0x9d, 0xff, 0x5b, 0xff, 0xa2, 0xff, 0x62, 0xff, 0xab, 0xff, 0x6e, 0xff, 0xb9, 0xff, 0x7e, 0xff, 0xc9, 0xff, 0x8f, 0xff, 0xd9, 0xff, 0xa2, 0xff, 0xea, 0xff, 0xb4, 0xff, 0xfa, 0xff, 0xc6, 0xff, 0x0c, 0x00, 0xd9, 0xff, 0x22, 0x00, 0xee, 0xff, 0x39, 0x00, 0x03, 0x00, 0x4f, 0x00, 0x18, 0x00, 0x62, 0x00, 0x2c, 0x00, 0x74, 0x00, 0x42, 0x00, 0x87, 0x00, 0x54, 0x00, 0x9b, 0x00, 0x64, 0x00, 0xaf, 0x00, 0x72, 0x00, 0xc0, 0x00, 0x7e, 0x00, 0xcf, 0x00, 0x8b, 0x00, 0xdc, 0x00, 0x96, 0x00, 0xe6, 0x00, 0x9e, 0x00, 0xef, 0x00, 0xa5, 0x00, 0xf8, 0x00, 0xb1, 0x00, 0x07, 0x01, 0xbc, 0x00, 0x16, 0x01, 0xc0, 0x00, 0x1f, 0x01, 0xbe, 0x00, 0x23, 0x01, 0xb7, 0x00, 0x20, 0x01, 0xb1, 0x00, 0x1c, 0x01, 0xae, 0x00, 0x17, 0x01, 0xaf, 0x00, 0x10, 0x01, 0xae, 0x00, 0x06, 0x01, 0xa4, 0x00, 0xf4, 0x00, 0x95, 0x00, 0xde, 0x00, 0x88, 0x00, 0xc9, 0x00, 0x80, 0x00, 0xb9, 0x00, 0x7e, 0x00, 0xac, 0x00, 0x7b, 0x00, 0x9d, 0x00, 0x73, 0x00, 0x8a, 0x00, 0x69, 0x00, 0x78, 0x00, 0x62, 0x00, 0x69, 0x00, 0x5d, 0x00, 0x5a, 0x00, 0x54, 0x00, 0x45, 0x00, 0x49, 0x00, 0x2b, 0x00, 0x3d, 0x00, 0x11, 0x00, 0x33, 0x00, 0xfd, 0xff, 0x2b, 0x00, 0xf2, 0xff, 0x21, 0x00, 0xe9, 0xff, 0x13, 0x00, 0xdd, 0xff, 0x01, 0x00, 0xcb, 0xff, 0xf0, 0xff, 0xb4, 0xff, 0xde, 0xff, 0x9b, 0xff, 0xcb, 0xff, 0x81, 0xff, 0xb5, 0xff, 0x66, 0xff, 0x9b, 0xff, 0x4a, 0xff, 0x7e, 0xff, 0x2d, 0xff, 0x63, 0xff, 0x14, 0xff, 0x51, 0xff, 0x04, 0xff, 0x47, 0xff, 0xfa, 0xfe, 0x3e, 0xff, 0xef, 0xfe, 0x31, 0xff, 0xdf, 0xfe, 0x25, 0xff, 0xcd, 0xfe, 0x1f, 0xff, 0xc1, 0xfe, 0x25, 0xff, 0xc3, 0xfe, 0x34, 0xff, 0xd2, 0xfe, 0x43, 0xff, 0xe6, 0xfe, 0x4e, 0xff, 0xf6, 0xfe, 0x54, 0xff, 0x01, 0xff, 0x5f, 0xff, 0x0f, 0xff, 0x6f, 0xff, 0x20, 0xff, 0x82, 0xff, 0x37, 0xff, 0x97, 0xff, 0x50, 0xff, 0xae, 0xff, 0x69, 0xff, 0xc6, 0xff, 0x81, 0xff, 0xe2, 0xff, 0x99, 0xff, 0x01, 0x00, 0xb0, 0xff, 0x1d, 0x00, 0xc5, 0xff, 0x32, 0x00, 0xd7, 0xff, 0x43, 0x00, 0xe7, 0xff, 0x53, 0x00, 0xf8, 0xff, 0x69, 0x00, 0x0f, 0x00, 0x84, 0x00, 0x2b, 0x00, 0x9e, 0x00, 0x45, 0x00, 0xb2, 0x00, 0x57, 0x00, 0xba, 0x00, 0x5d, 0x00, 0xbd, 0x00, 0x5d, 0x00, 0xc1, 0x00, 0x60, 0x00, 0xc6, 0x00, 0x6a, 0x00, 0xcd, 0x00, 0x7b, 0x00, 0xd1, 0x00, 0x8a, 0x00, 0xcf, 0x00, 0x90, 0x00, 0xca, 0x00, 0x90, 0x00, 0xc8, 0x00, 0x8e, 0x00, 0xc9, 0x00, 0x8f, 0x00, 0xc7, 0x00, 0x91, 0x00, 0xc0, 0x00, 0x92, 0x00, 0xb7, 0x00, 0x94, 0x00, 0xb0, 0x00, 0x97, 0x00, 0xa8, 0x00, 0x99, 0x00, 0xa3, 0x00, 0x99, 0x00, 0xa2, 0x00, 0x9b, 0x00, 0xa5, 0x00, 0xa0, 0x00, 0xa5, 0x00, 0xa5, 0x00, 0xa2, 0x00, 0xa9, 0x00, 0x9e, 0x00, 0xac, 0x00, 0x97, 0x00, 0xac, 0x00, 0x90, 0x00, 0xab, 0x00, 0x8c, 0x00, 0xaa, 0x00, 0x89, 0x00, 0xaa, 0x00, 0x83, 0x00, 0xaa, 0x00, 0x78, 0x00, 0xa6, 0x00, 0x68, 0x00, 0xa0, 0x00, 0x57, 0x00, 0x97, 0x00, 0x42, 0x00, 0x8a, 0x00, 0x28, 0x00, 0x75, 0x00, 0x0b, 0x00, 0x5b, 0x00, 0xee, 0xff, 0x41, 0x00, 0xd3, 0xff, 0x27, 0x00, 0xbb, 0xff, 0x0d, 0x00, 0xa2, 0xff, 0xf3, 0xff, 0x83, 0xff, 0xd5, 0xff, 0x60, 0xff, 0xb6, 0xff, 0x40, 0xff, 0x9a, 0xff, 0x24, 0xff, 0x82, 0xff, 0x0e, 0xff, 0x6e, 0xff, 0xfd, 0xfe, 0x5b, 0xff, 0xf3, 0xfe, 0x4f, 0xff, 0xec, 0xfe, 0x45, 0xff, 0xe5, 0xfe, 0x39, 0xff, 0xdc, 0xfe, 0x2a, 0xff, 0xd6, 0xfe, 0x1a, 0xff, 0xd7, 0xfe, 0x12, 0xff, 0xde, 0xfe, 0x10, 0xff, 0xec, 0xfe, 0x17, 0xff, 0xfe, 0xfe, 0x24, 0xff, 0x10, 0xff, 0x33, 0xff, 0x20, 0xff, 0x3d, 0xff, 0x2c, 0xff, 0x41, 0xff, 0x39, 0xff, 0x44, 0xff, 0x49, 0xff, 0x49, 0xff, 0x61, 0xff, 0x56, 0xff, 0x7e, 0xff, 0x6c, 0xff, 0x9e, 0xff, 0x86, 0xff, 0xbc, 0xff, 0xa0, 0xff, 0xd2, 0xff, 0xb3, 0xff, 0xe0, 0xff, 0xbb, 0xff, 0xe8, 0xff, 0xbc, 0xff, 0xf1, 0xff, 0xbe, 0xff, 0xfa, 0xff, 0xc3, 0xff, 0x03, 0x00, 0xcc, 0xff, 0x0c, 0x00, 0xd7, 0xff, 0x11, 0x00, 0xdf, 0xff, 0x16, 0x00, 0xe3, 0xff, 0x19, 0x00, 0xe5, 0xff, 0x1d, 0x00, 0xe5, 0xff, 0x20, 0x00, 0xe6, 0xff, 0x25, 0x00, 0xe9, 0xff, 0x2b, 0x00, 0xed, 0xff, 0x33, 0x00, 0xf4, 0xff, 0x40, 0x00, 0x02, 0x00, 0x51, 0x00, 0x14, 0x00, 0x65, 0x00, 0x26, 0x00, 0x78, 0x00, 0x33, 0x00, 0x8a, 0x00, 0x3f, 0x00, 0x9e, 0x00, 0x4f, 0x00, 0xad, 0x00, 0x5f, 0x00, 0xb9, 0x00, 0x6f, 0x00, 0xc5, 0x00, 0x7f, 0x00, 0xd5, 0x00, 0x8f, 0x00, 0xe5, 0x00, 0x9c, 0x00, 0xf2, 0x00, 0xa7, 0x00, 0xfc, 0x00, 0xb1, 0x00, 0xff, 0x00, 0xb8, 0x00, 0xfd, 0x00, 0xbf, 0x00, 0xf7, 0x00, 0xc4, 0x00, 0xec, 0x00, 0xc5, 0x00, 0xdd, 0x00, 0xc0, 0x00, 0xca, 0x00, 0xb6, 0x00, 0xb5, 0x00, 0xa9, 0x00, 0xa0, 0x00, 0x9c, 0x00, 0x8e, 0x00, 0x92, 0x00, 0x7c, 0x00, 0x8d, 0x00, 0x67, 0x00, 0x85, 0x00, 0x4e, 0x00, 0x79, 0x00, 0x32, 0x00, 0x67, 0x00, 0x18, 0x00, 0x53, 0x00, 0x02, 0x00, 0x40, 0x00, 0xf1, 0xff, 0x33, 0x00, 0xe3, 0xff, 0x2c, 0x00, 0xd5, 0xff, 0x28, 0x00, 0xc3, 0xff, 0x20, 0x00, 0xae, 0xff, 0x10, 0x00, 0x99, 0xff, 0xfa, 0xff, 0x84, 0xff, 0xe0, 0xff, 0x78, 0xff, 0xcc, 0xff, 0x76, 0xff, 0xc2, 0xff, 0x7a, 0xff, 0xc1, 0xff, 0x7d, 0xff, 0xc0, 0xff, 0x7b, 0xff, 0xbd, 0xff, 0x77, 0xff, 0xb7, 0xff, 0x70, 0xff, 0xaf, 0xff, 0x69, 0xff, 0xa4, 0xff, 0x63, 0xff, 0x9c, 0xff, 0x5d, 0xff, 0x96, 0xff, 0x59, 0xff, 0x94, 0xff, 0x59, 0xff, 0x93, 0xff, 0x5d, 0xff, 0x96, 0xff, 0x5e, 0xff, 0x95, 0xff, 0x58, 0xff, 0x8d, 0xff, 0x4d, 0xff, 0x81, 0xff, 0x3f, 0xff, 0x75, 0xff, 0x33, 0xff, 0x6d, 0xff, 0x2e, 0xff, 0x6d, 0xff, 0x30, 0xff, 0x75, 0xff, 0x34, 0xff, 0x7c, 0xff, 0x37, 0xff, 0x7e, 0xff, 0x3d, 0xff, 0x7f, 0xff, 0x45, 0xff, 0x7d, 0xff, 0x4d, 0xff, 0x7c, 0xff, 0x59, 0xff, 0x80, 0xff, 0x6b, 0xff, 0x8c, 0xff, 0x80, 0xff, 0x9e, 0xff, 0x9a, 0xff, 0xb2, 0xff, 0xb7, 0xff, 0xc5, 0xff, 0xd6, 0xff, 0xd3, 0xff, 0xf2, 0xff, 0xda, 0xff, 0x0b, 0x00, 0xde, 0xff, 0x21, 0x00, 0xe5, 0xff, 0x34, 0x00, 0xee, 0xff, 0x44, 0x00, 0xfa, 0xff, 0x54, 0x00, 0x09, 0x00, 0x66, 0x00, 0x19, 0x00, 0x79, 0x00, 0x28, 0x00, 0x8e, 0x00, 0x37, 0x00, 0xa0, 0x00, 0x43, 0x00, 0xab, 0x00, 0x4c, 0x00, 0xb3, 0x00, 0x57, 0x00, 0xbb, 0x00, 0x64, 0x00, 0xc0, 0x00, 0x70, 0x00, 0xc2, 0x00, 0x7a, 0x00, 0xc2, 0x00, 0x84, 0x00, 0xbd, 0x00, 0x8c, 0x00, 0xb8, 0x00, 0x94, 0x00, 0xb7, 0x00, 0xa1, 0x00, 0xbc, 0x00, 0xb2, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc8, 0x00, 0xd1, 0x00, 0xc7, 0x00, 0xd8, 0x00, 0xbf, 0x00, 0xd9, 0x00, 0xb5, 0x00, 0xd7, 0x00, 0xac, 0x00, 0xd4, 0x00, 0xa2, 0x00, 0xce, 0x00, 0x99, 0x00, 0xc5, 0x00, 0x8d, 0x00, 0xb7, 0x00, 0x7e, 0x00, 0xa1, 0x00, 0x6d, 0x00, 0x89, 0x00, 0x5c, 0x00, 0x71, 0x00, 0x4a, 0x00, 0x59, 0x00, 0x38, 0x00, 0x41, 0x00, 0x2a, 0x00, 0x2d, 0x00, 0x1f, 0x00, 0x1b, 0x00, 0x13, 0x00, 0x08, 0x00, 0x03, 0x00, 0xf3, 0xff, 0xf3, 0xff, 0xdf, 0xff, 0xe5, 0xff, 0xd0, 0xff, 0xda, 0xff, 0xc7, 0xff, 0xd2, 0xff, 0xc4, 0xff, 0xd1, 0xff, 0xc7, 0xff, 0xd2, 0xff, 0xc9, 0xff, 0xd4, 0xff, 0xcc, 0xff, 0xd7, 0xff, 0xd0, 0xff, 0xd9, 0xff, 0xd7, 0xff, 0xd7, 0xff, 0xdd, 0xff, 0xd0, 0xff, 0xe2, 0xff, 0xc9, 0xff, 0xe8, 0xff, 0xc5, 0xff, 0xf1, 0xff, 0xc4, 0xff, 0xf9, 0xff, 0xc7, 0xff, 0x00, 0x00, 0xca, 0xff, 0x01, 0x00, 0xcb, 0xff, 0xfd, 0xff, 0xcb, 0xff, 0xf6, 0xff, 0xca, 0xff, 0xf0, 0xff, 0xcd, 0xff, 0xf0, 0xff, 0xd4, 0xff, 0xf6, 0xff, 0xdc, 0xff, 0xfd, 0xff, 0xe3, 0xff, 0x00, 0x00, 0xe5, 0xff, 0xfd, 0xff, 0xe5, 0xff, 0xf2, 0xff, 0xe4, 0xff, 0xe1, 0xff, 0xe7, 0xff, 0xd2, 0xff, 0xf0, 0xff, 0xc9, 0xff, 0xf8, 0xff, 0xc1, 0xff, 0xfb, 0xff, 0xb7, 0xff, 0xfb, 0xff, 0xac, 0xff, 0xf8, 0xff, 0xa0, 0xff, 0xf8, 0xff, 0x97, 0xff, 0xfc, 0xff, 0x93, 0xff, 0x05, 0x00, 0x93, 0xff, 0x10, 0x00, 0x94, 0xff, 0x1d, 0x00, 0x93, 0xff, 0x2d, 0x00, 0x94, 0xff, 0x3b, 0x00, 0x94, 0xff, 0x44, 0x00, 0x95, 0xff, 0x42, 0x00, 0x8f, 0xff, 0x3c, 0x00, 0x8a, 0xff, 0x3e, 0x00, 0x90, 0xff, 0x4d, 0x00, 0xa3, 0xff, 0x64, 0x00, 0xbc, 0xff, 0x7b, 0x00, 0xd2, 0xff, 0x8d, 0x00, 0xe2, 0xff, 0x97, 0x00, 0xe9, 0xff, 0x9a, 0x00, 0xec, 0xff, 0x96, 0x00, 0xef, 0xff, 0x8b, 0x00, 0xf4, 0xff, 0x78, 0x00, 0xf8, 0xff, 0x63, 0x00, 0xfa, 0xff, 0x52, 0x00, 0xfc, 0xff, 0x46, 0x00, 0xfd, 0xff, 0x3e, 0x00, 0xfd, 0xff, 0x34, 0x00, 0xfa, 0xff, 0x26, 0x00, 0xf6, 0xff, 0x14, 0x00, 0xf2, 0xff, 0x03, 0x00, 0xf2, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf3, 0xff, 0x02, 0x00, 0xf0, 0xff, 0x0a, 0x00, 0xe8, 0xff, 0x0a, 0x00, 0xde, 0xff, 0x06, 0x00, 0xd8, 0xff, 0x05, 0x00, 0xd8, 0xff, 0x0a, 0x00, 0xe1, 0xff, 0x16, 0x00, 0xec, 0xff, 0x23, 0x00, 0xf7, 0xff, 0x2b, 0x00, 0xfa, 0xff, 0x28, 0x00, 0xf1, 0xff, 0x19, 0x00, 0xe4, 0xff, 0x08, 0x00, 0xdb, 0xff, 0xfd, 0xff, 0xd7, 0xff, 0xfa, 0xff, 0xd3, 0xff, 0xf6, 0xff, 0xcc, 0xff, 0xee, 0xff, 0xc0, 0xff, 0xe2, 0xff, 0xb0, 0xff, 0xd1, 0xff, 0xa2, 0xff, 0xc3, 0xff, 0x96, 0xff, 0xb9, 0xff, 0x8a, 0xff, 0xb1, 0xff, 0x7e, 0xff, 0xaa, 0xff, 0x71, 0xff, 0xa2, 0xff, 0x61, 0xff, 0x97, 0xff, 0x51, 0xff, 0x8a, 0xff, 0x47, 0xff, 0x84, 0xff, 0x41, 0xff, 0x85, 0xff, 0x3b, 0xff, 0x89, 0xff, 0x38, 0xff, 0x90, 0xff, 0x3b, 0xff, 0x9a, 0xff, 0x40, 0xff, 0xa4, 0xff, 0x42, 0xff, 0xaa, 0xff, 0x3f, 0xff, 0xa8, 0xff, 0x33, 0xff, 0x9f, 0xff, 0x25, 0xff, 0x96, 0xff, 0x1e, 0xff, 0x95, 0xff, 0x23, 0xff, 0x9e, 0xff, 0x30, 0xff, 0xaa, 0xff, 0x41, 0xff, 0xb4, 0xff, 0x5a, 0xff, 0xbf, 0xff, 0x75, 0xff, 0xc8, 0xff, 0x8c, 0xff, 0xcc, 0xff, 0x9a, 0xff, 0xc9, 0xff, 0xa2, 0xff, 0xc5, 0xff, 0xa9, 0xff, 0xc5, 0xff, 0xb7, 0xff, 0xce, 0xff, 0xcc, 0xff, 0xdc, 0xff, 0xe2, 0xff, 0xe7, 0xff, 0xf6, 0xff, 0xeb, 0xff, 0x06, 0x00, 0xea, 0xff, 0x13, 0x00, 0xea, 0xff, 0x1d, 0x00, 0xee, 0xff, 0x21, 0x00, 0xf0, 0xff, 0x22, 0x00, 0xf0, 0xff, 0x22, 0x00, 0xf1, 0xff, 0x1f, 0x00, 0xf1, 0xff, 0x16, 0x00, 0xee, 0xff, 0x05, 0x00, 0xe4, 0xff, 0xf4, 0xff, 0xdb, 0xff, 0xeb, 0xff, 0xd8, 0xff, 0xef, 0xff, 0xe0, 0xff, 0xf9, 0xff, 0xee, 0xff, 0x00, 0x00, 0xf9, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xf2, 0xff, 0xfc, 0xff, 0xe6, 0xff, 0xfa, 0xff, 0xdd, 0xff, 0xfa, 0xff, 0xd9, 0xff, 0xff, 0xff, 0xde, 0xff, 0x0b, 0x00, 0xeb, 0xff, 0x1f, 0x00, 0xfa, 0xff, 0x33, 0x00, 0x09, 0x00, 0x45, 0x00, 0x17, 0x00, 0x53, 0x00, 0x24, 0x00, 0x5f, 0x00, 0x34, 0x00, 0x70, 0x00, 0x48, 0x00, 0x86, 0x00, 0x5c, 0x00, 0x9f, 0x00, 0x6d, 0x00, 0xb2, 0x00, 0x79, 0x00, 0xbf, 0x00, 0x84, 0x00, 0xc8, 0x00, 0x8a, 0x00, 0xc9, 0x00, 0x8c, 0x00, 0xc5, 0x00, 0x8d, 0x00, 0xbf, 0x00, 0x8b, 0x00, 0xb9, 0x00, 0x84, 0x00, 0xad, 0x00, 0x74, 0x00, 0x98, 0x00, 0x64, 0x00, 0x82, 0x00, 0x52, 0x00, 0x6b, 0x00, 0x3c, 0x00, 0x52, 0x00, 0x25, 0x00, 0x3b, 0x00, 0x12, 0x00, 0x2a, 0x00, 0x04, 0x00, 0x1c, 0x00, 0xfa, 0xff, 0x0e, 0x00, 0xf2, 0xff, 0xff, 0xff, 0xe6, 0xff, 0xed, 0xff, 0xd3, 0xff, 0xd8, 0xff, 0xb9, 0xff, 0xc0, 0xff, 0xa1, 0xff, 0xb0, 0xff, 0x90, 0xff, 0xaa, 0xff, 0x83, 0xff, 0xa9, 0xff, 0x79, 0xff, 0xa8, 0xff, 0x78, 0xff, 0xab, 0xff, 0x7f, 0xff, 0xb3, 0xff, 0x88, 0xff, 0xba, 0xff, 0x91, 0xff, 0xc0, 0xff, 0x9b, 0xff, 0xc8, 0xff, 0xa6, 0xff, 0xd3, 0xff, 0xb5, 0xff, 0xe3, 0xff, 0xc7, 0xff, 0xf7, 0xff, 0xd5, 0xff, 0x07, 0x00, 0xda, 0xff, 0x0d, 0x00, 0xdc, 0xff, 0x0d, 0x00, 0xe3, 0xff, 0x0d, 0x00, 0xec, 0xff, 0x0e, 0x00, 0xef, 0xff, 0x09, 0x00, 0xf0, 0xff, 0x01, 0x00, 0xf6, 0xff, 0xff, 0xff, 0x02, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x12, 0x00, 0x00, 0x00, 0x11, 0x00, 0xf5, 0xff, 0x0e, 0x00, 0xf6, 0xff, 0x14, 0x00, 0xff, 0xff, 0x1d, 0x00, 0x07, 0x00, 0x24, 0x00, 0x08, 0x00, 0x26, 0x00, 0x06, 0x00, 0x2b, 0x00, 0x02, 0x00, 0x36, 0x00, 0xfd, 0xff, 0x46, 0x00, 0xf7, 0xff, 0x56, 0x00, 0xf0, 0xff, 0x62, 0x00, 0xee, 0xff, 0x6c, 0x00, 0xf6, 0xff, 0x7b, 0x00, 0x08, 0x00, 0x8f, 0x00, 0x1b, 0x00, 0xa3, 0x00, 0x29, 0x00, 0xb1, 0x00, 0x33, 0x00, 0xbe, 0x00, 0x3b, 0x00, 0xca, 0x00, 0x3d, 0x00, 0xd1, 0x00, 0x3b, 0x00, 0xd0, 0x00, 0x3f, 0x00, 0xcc, 0x00, 0x4a, 0x00, 0xc9, 0x00, 0x56, 0x00, 0xc5, 0x00, 0x5f, 0x00, 0xbe, 0x00, 0x66, 0x00, 0xb6, 0x00, 0x6f, 0x00, 0xad, 0x00, 0x78, 0x00, 0xa0, 0x00, 0x7f, 0x00, 0x8e, 0x00, 0x87, 0x00, 0x7e, 0x00, 0x8b, 0x00, 0x6c, 0x00, 0x88, 0x00, 0x58, 0x00, 0x83, 0x00, 0x47, 0x00, 0x84, 0x00, 0x40, 0x00, 0x87, 0x00, 0x3d, 0x00, 0x89, 0x00, 0x36, 0x00, 0x8d, 0x00, 0x2e, 0x00, 0x92, 0x00, 0x26, 0x00, 0x95, 0x00, 0x1f, 0x00, 0x96, 0x00, 0x19, 0x00, 0x96, 0x00, 0x16, 0x00, 0x95, 0x00, 0x15, 0x00, 0x92, 0x00, 0x15, 0x00, 0x92, 0x00, 0x17, 0x00, 0x92, 0x00, 0x18, 0x00, 0x8d, 0x00, 0x11, 0x00, 0x84, 0x00, 0x04, 0x00, 0x7b, 0x00, 0xf7, 0xff, 0x74, 0x00, 0xee, 0xff, 0x6e, 0x00, 0xe6, 0xff, 0x67, 0x00, 0xe0, 0xff, 0x60, 0x00, 0xd9, 0xff, 0x52, 0x00, 0xcc, 0xff, 0x3f, 0x00, 0xbc, 0xff, 0x29, 0x00, 0xaa, 0xff, 0x15, 0x00, 0x99, 0xff, 0x02, 0x00, 0x86, 0xff, 0xf3, 0xff, 0x75, 0xff, 0xeb, 0xff, 0x6a, 0xff, 0xe8, 0xff, 0x64, 0xff, 0xe5, 0xff, 0x63, 0xff, 0xe2, 0xff, 0x66, 0xff, 0xdd, 0xff, 0x6a, 0xff, 0xd8, 0xff, 0x6f, 0xff, 0xd2, 0xff, 0x70, 0xff, 0xcf, 0xff, 0x6f, 0xff, 0xd3, 0xff, 0x72, 0xff, 0xda, 0xff, 0x76, 0xff, 0xe0, 0xff, 0x7b, 0xff, 0xe1, 0xff, 0x83, 0xff, 0xdc, 0xff, 0x8a, 0xff, 0xd5, 0xff, 0x92, 0xff, 0xd3, 0xff, 0x9d, 0xff, 0xd4, 0xff, 0xa7, 0xff, 0xd3, 0xff, 0xad, 0xff, 0xd3, 0xff, 0xb1, 0xff, 0xd3, 0xff, 0xb7, 0xff, 0xd2, 0xff, 0xbc, 0xff, 0xce, 0xff, 0xbf, 0xff, 0xcc, 0xff, 0xc5, 0xff, 0xce, 0xff, 0xcd, 0xff, 0xd1, 0xff, 0xd5, 0xff, 0xd7, 0xff, 0xdf, 0xff, 0xe1, 0xff, 0xeb, 0xff, 0xef, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0x02, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x12, 0x00, 0x15, 0x00, 0x21, 0x00, 0x21, 0x00, 0x30, 0x00, 0x2b, 0x00, 0x40, 0x00, 0x32, 0x00, 0x4e, 0x00, 0x37, 0x00, 0x58, 0x00, 0x3a, 0x00, 0x5e, 0x00, 0x3d, 0x00, 0x63, 0x00, 0x40, 0x00, 0x67, 0x00, 0x44, 0x00, 0x68, 0x00, 0x42, 0x00, 0x63, 0x00, 0x3a, 0x00, 0x5d, 0x00, 0x31, 0x00, 0x57, 0x00, 0x27, 0x00, 0x54, 0x00, 0x20, 0x00, 0x51, 0x00, 0x19, 0x00, 0x4d, 0x00, 0x13, 0x00, 0x45, 0x00, 0x0b, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x31, 0x00, 0xf7, 0xff, 0x2a, 0x00, 0xec, 0xff, 0x24, 0x00, 0xe1, 0xff, 0x1c, 0x00, 0xd4, 0xff, 0x18, 0x00, 0xc9, 0xff, 0x17, 0x00, 0xbf, 0xff, 0x19, 0x00, 0xb5, 0xff, 0x1c, 0x00, 0xa9, 0xff, 0x1e, 0x00, 0x9e, 0xff, 0x20, 0x00, 0x92, 0xff, 0x1e, 0x00, 0x85, 0xff, 0x1d, 0x00, 0x7d, 0xff, 0x21, 0x00, 0x7b, 0xff, 0x28, 0x00, 0x7c, 0xff, 0x31, 0x00, 0x7c, 0xff, 0x39, 0x00, 0x78, 0xff, 0x40, 0x00, 0x72, 0xff, 0x46, 0x00, 0x70, 0xff, 0x4d, 0x00, 0x74, 0xff, 0x54, 0x00, 0x7d, 0xff, 0x5b, 0x00, 0x86, 0xff, 0x5c, 0x00, 0x8c, 0xff, 0x5a, 0x00, 0x90, 0xff, 0x53, 0x00, 0x92, 0xff, 0x48, 0x00, 0x95, 0xff, 0x3b, 0x00, 0x97, 0xff, 0x2e, 0x00, 0x9d, 0xff, 0x21, 0x00, 0xa7, 0xff, 0x14, 0x00, 0xb6, 0xff, 0x04, 0x00, 0xc6, 0xff, 0xf2, 0xff, 0xd4, 0xff, 0xe1, 0xff, 0xe1, 0xff, 0xd2, 0xff, 0xec, 0xff, 0xc2, 0xff, 0xf5, 0xff, 0xb3, 0xff, 0xff, 0xff, 0xa4, 0xff, 0x0c, 0x00, 0x8f, 0xff, 0x16, 0x00, 0x76, 0xff, 0x1a, 0x00, 0x5b, 0xff, 0x18, 0x00, 0x40, 0xff, 0x14, 0x00, 0x29, 0xff, 0x11, 0x00, 0x18, 0xff, 0x17, 0x00, 0x0d, 0xff, 0x22, 0x00, 0x03, 0xff, 0x2e, 0x00, 0xfa, 0xfe, 0x35, 0x00, 0xf1, 0xfe, 0x39, 0x00, 0xea, 0xfe, 0x3c, 0x00, 0xe0, 0xfe, 0x3c, 0x00, 0xda, 0xfe, 0x3c, 0x00, 0xdc, 0xfe, 0x40, 0x00, 0xe7, 0xfe, 0x4a, 0x00, 0xf6, 0xfe, 0x59, 0x00, 0x04, 0xff, 0x67, 0x00, 0x0e, 0xff, 0x72, 0x00, 0x13, 0xff, 0x76, 0x00, 0x1a, 0xff, 0x79, 0x00, 0x25, 0xff, 0x80, 0x00, 0x34, 0xff, 0x8a, 0x00, 0x44, 0xff, 0x91, 0x00, 0x56, 0xff, 0x97, 0x00, 0x6b, 0xff, 0x9c, 0x00, 0x7f, 0xff, 0x9f, 0x00, 0x8f, 0xff, 0xa2, 0x00, 0x9a, 0xff, 0xa4, 0x00, 0xa5, 0xff, 0xa7, 0x00, 0xaf, 0xff, 0xa6, 0x00, 0xba, 0xff, 0xa3, 0x00, 0xc8, 0xff, 0xa0, 0x00, 0xd8, 0xff, 0x9a, 0x00, 0xe5, 0xff, 0x90, 0x00, 0xf5, 0xff, 0x89, 0x00, 0x09, 0x00, 0x88, 0x00, 0x1f, 0x00, 0x8d, 0x00, 0x2f, 0x00, 0x8f, 0x00, 0x38, 0x00, 0x88, 0x00, 0x40, 0x00, 0x7c, 0x00, 0x46, 0x00, 0x69, 0x00, 0x4a, 0x00, 0x50, 0x00, 0x50, 0x00, 0x37, 0x00, 0x5c, 0x00, 0x23, 0x00, 0x6b, 0x00, 0x16, 0x00, 0x7a, 0x00, 0x0d, 0x00, 0x86, 0x00, 0x04, 0x00, 0x8f, 0x00, 0xf9, 0xff, 0x97, 0x00, 0xee, 0xff, 0x9f, 0x00, 0xe1, 0xff, 0xa5, 0x00, 0xd1, 0xff, 0xa4, 0x00, 0xb9, 0xff, 0xa0, 0x00, 0x9d, 0xff, 0x9e, 0x00, 0x84, 0xff, 0x9f, 0x00, 0x73, 0xff, 0xa2, 0x00, 0x69, 0xff, 0x9e, 0x00, 0x5e, 0xff, 0x92, 0x00, 0x4f, 0xff, 0x81, 0x00, 0x3e, 0xff, 0x75, 0x00, 0x30, 0xff, 0x73, 0x00, 0x2a, 0xff, 0x7b, 0x00, 0x2c, 0xff, 0x82, 0x00, 0x2d, 0xff, 0x82, 0x00, 0x2a, 0xff, 0x80, 0x00, 0x29, 0xff, 0x81, 0x00, 0x32, 0xff, 0x83, 0x00, 0x41, 0xff, 0x81, 0x00, 0x4e, 0xff, 0x7c, 0x00, 0x59, 0xff, 0x79, 0x00, 0x62, 0xff, 0x78, 0x00, 0x6c, 0xff, 0x76, 0x00, 0x76, 0xff, 0x72, 0x00, 0x7f, 0xff, 0x6b, 0x00, 0x88, 0xff, 0x5f, 0x00, 0x92, 0xff, 0x4f, 0x00, 0x9a, 0xff, 0x3a, 0x00, 0x9d, 0xff, 0x1f, 0x00, 0x9a, 0xff, 0xfe, 0xff, 0x8f, 0xff, 0xd8, 0xff, 0x80, 0xff, 0xb2, 0xff, 0x71, 0xff, 0x90, 0xff, 0x68, 0xff, 0x78, 0xff, 0x6b, 0xff, 0x69, 0xff, 0x78, 0xff, 0x61, 0xff, 0x8c, 0xff, 0x67, 0xff, 0xab, 0xff, 0x79, 0xff, 0xd5, 0xff, 0x8a, 0xff, 0xfb, 0xff, 0x8d, 0xff, 0x13, 0x00, 0x86, 0xff, 0x20, 0x00, 0x83, 0xff, 0x30, 0x00, 0x88, 0xff, 0x46, 0x00, 0x93, 0xff, 0x60, 0x00, 0x9f, 0xff, 0x79, 0x00, 0xa8, 0xff, 0x8c, 0x00, 0xb0, 0xff, 0x9b, 0x00, 0xb8, 0xff, 0xa7, 0x00, 0xbe, 0xff, 0xb1, 0x00, 0xb9, 0xff, 0xad, 0x00, 0xaa, 0xff, 0xa0, 0x00, 0x9d, 0xff, 0x92, 0x00, 0x98, 0xff, 0x88, 0x00, 0x97, 0xff, 0x7d, 0x00, 0x91, 0xff, 0x69, 0x00, 0x86, 0xff, 0x4e, 0x00, 0x7f, 0xff, 0x37, 0x00, 0x80, 0xff, 0x29, 0x00, 0x8b, 0xff, 0x25, 0x00, 0x9d, 0xff, 0x27, 0x00, 0xb3, 0xff, 0x2d, 0x00, 0xca, 0xff, 0x34, 0x00, 0xe7, 0xff, 0x43, 0x00, 0x0b, 0x00, 0x59, 0x00, 0x2f, 0x00, 0x70, 0x00, 0x4d, 0x00, 0x81, 0x00, 0x68, 0x00, 0x90, 0x00, 0x80, 0x00, 0x9b, 0x00, 0x90, 0x00, 0x9e, 0x00, 0x95, 0x00, 0x97, 0x00, 0x93, 0x00, 0x8b, 0x00, 0x8c, 0x00, 0x7e, 0x00, 0x81, 0x00, 0x71, 0x00, 0x72, 0x00, 0x61, 0x00, 0x61, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x2d, 0x00, 0x35, 0x00, 0x0a, 0x00, 0x20, 0x00, 0xea, 0xff, 0x10, 0x00, 0xd0, 0xff, 0x05, 0x00, 0xbf, 0xff, 0x03, 0x00, 0xb8, 0xff, 0x07, 0x00, 0xb8, 0xff, 0x13, 0x00, 0xbe, 0xff, 0x22, 0x00, 0xc7, 0xff, 0x37, 0x00, 0xd4, 0xff, 0x4d, 0x00, 0xe4, 0xff, 0x5e, 0x00, 0xf0, 0xff, 0x6a, 0x00, 0xfb, 0xff, 0x6e, 0x00, 0x01, 0x00, 0x71, 0x00, 0x06, 0x00, 0x70, 0x00, 0x08, 0x00, 0x69, 0x00, 0x01, 0x00, 0x59, 0x00, 0xf1, 0xff, 0x42, 0x00, 0xdc, 0xff, 0x25, 0x00, 0xc5, 0xff, 0x01, 0x00, 0xad, 0xff, 0xda, 0xff, 0x97, 0xff, 0xb3, 0xff, 0x86, 0xff, 0x90, 0xff, 0x7a, 0xff, 0x71, 0xff, 0x72, 0xff, 0x55, 0xff, 0x6b, 0xff, 0x3e, 0xff, 0x67, 0xff, 0x2b, 0xff, 0x6a, 0xff, 0x20, 0xff, 0x77, 0xff, 0x1c, 0xff, 0x8f, 0xff, 0x1d, 0xff, 0xae, 0xff, 0x22, 0xff, 0xd0, 0xff, 0x29, 0xff, 0xf0, 0xff, 0x32, 0xff, 0x0f, 0x00, 0x3d, 0xff, 0x2f, 0x00, 0x4b, 0xff, 0x50, 0x00, 0x57, 0xff, 0x6c, 0x00, 0x5f, 0xff, 0x81, 0x00, 0x65, 0xff, 0x91, 0x00, 0x68, 0xff, 0x9f, 0x00, 0x66, 0xff, 0xa6, 0x00, 0x61, 0xff, 0xa9, 0x00, 0x5a, 0xff, 0xa5, 0x00, 0x51, 0xff, 0x9a, 0x00, 0x47, 0xff, 0x8b, 0x00, 0x41, 0xff, 0x7f, 0x00, 0x42, 0xff, 0x79, 0x00, 0x4a, 0xff, 0x77, 0x00, 0x57, 0xff, 0x77, 0x00, 0x6c, 0xff, 0x7e, 0x00, 0x8a, 0xff, 0x90, 0x00, 0xaa, 0xff, 0xa7, 0x00, 0xca, 0xff, 0xc0, 0x00, 0xe8, 0xff, 0xd4, 0x00, 0x01, 0x00, 0xe0, 0x00, 0x19, 0x00, 0xe7, 0x00, 0x3d, 0x00, 0xfb, 0x00, 0x73, 0x00, 0x1f, 0x01, 0xac, 0x00, 0x47, 0x01, 0xda, 0x00, 0x64, 0x01, 0xf5, 0x00, 0x6d, 0x01, 0xfb, 0x00, 0x5f, 0x01, 0xee, 0x00, 0x38, 0x01, 0xdd, 0x00, 0x09, 0x01, 0xd1, 0x00, 0xdb, 0x00, 0xc6, 0x00, 0xac, 0x00, 0xb7, 0x00, 0x7c, 0x00, 0xac, 0x00, 0x52, 0x00, 0xab, 0x00, 0x31, 0x00, 0xb4, 0x00, 0x1b, 0x00, 0xc3, 0x00, 0x07, 0x00, 0xca, 0x00, 0xe9, 0xff, 0xbe, 0x00, 0xb8, 0xff, 0xac, 0x00, 0x81, 0xff, 0xaf, 0x00, 0x64, 0xff, 0xd4, 0x00, 0x6c, 0xff, 0x07, 0x01, 0x87, 0xff, 0x2e, 0x01, 0x99, 0xff, 0x3d, 0x01, 0x93, 0xff, 0x3c, 0x01, 0x7f, 0xff, 0x3b, 0x01, 0x70, 0xff, 0x44, 0x01, 0x70, 0xff, 0x51, 0x01, 0x7b, 0xff, 0x54, 0x01, 0x83, 0xff, 0x45, 0x01, 0x7d, 0xff, 0x27, 0x01, 0x6a, 0xff, 0x01, 0x01, 0x4f, 0xff, 0xdb, 0x00, 0x34, 0xff, 0xb4, 0x00, 0x1c, 0xff, 0x8c, 0x00, 0x08, 0xff, 0x65, 0x00, 0xfb, 0xfe, 0x39, 0x00, 0xed, 0xfe, 0x0b, 0x00, 0xdd, 0xfe, 0xe5, 0xff, 0xd2, 0xfe, 0xcf, 0xff, 0xd1, 0xfe, 0xc9, 0xff, 0xda, 0xfe, 0xc7, 0xff, 0xe6, 0xfe, 0xc5, 0xff, 0xf3, 0xfe, 0xc6, 0xff, 0x07, 0xff, 0xcb, 0xff, 0x26, 0xff, 0xd7, 0xff, 0x51, 0xff, 0xe6, 0xff, 0x7c, 0xff, 0xf1, 0xff, 0xa0, 0xff, 0xf9, 0xff, 0xba, 0xff, 0xf8, 0xff, 0xca, 0xff, 0xf1, 0xff, 0xd2, 0xff, 0xe7, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xe9, 0xff, 0xc9, 0xff, 0xf2, 0xff, 0xad, 0xff, 0xf0, 0xff, 0x84, 0xff, 0xe0, 0xff, 0x57, 0xff, 0xc8, 0xff, 0x2b, 0xff, 0xae, 0xff, 0x06, 0xff, 0x9a, 0xff, 0xef, 0xfe, 0x94, 0xff, 0xde, 0xfe, 0x97, 0xff, 0xd4, 0xfe, 0xa2, 0xff, 0xd3, 0xfe, 0xb7, 0xff, 0xdd, 0xfe, 0xd5, 0xff, 0xef, 0xfe, 0xf8, 0xff, 0x09, 0xff, 0x1e, 0x00, 0x2e, 0xff, 0x4b, 0x00, 0x59, 0xff, 0x7e, 0x00, 0x82, 0xff, 0xae, 0x00, 0xa3, 0xff, 0xd4, 0x00, 0xbb, 0xff, 0xee, 0x00, 0xcc, 0xff, 0xfd, 0x00, 0xd7, 0xff, 0x03, 0x01, 0xdc, 0xff, 0x01, 0x01, 0xda, 0xff, 0xf7, 0x00, 0xd4, 0xff, 0xe9, 0x00, 0xca, 0xff, 0xd4, 0x00, 0xbc, 0xff, 0xb8, 0x00, 0xae, 0xff, 0x97, 0x00, 0xa0, 0xff, 0x71, 0x00, 0x97, 0xff, 0x4b, 0x00, 0x95, 0xff, 0x2a, 0x00, 0xa2, 0xff, 0x18, 0x00, 0xbc, 0xff, 0x16, 0x00, 0xd9, 0xff, 0x18, 0x00, 0xf7, 0xff, 0x1a, 0x00, 0x1a, 0x00, 0x1d, 0x00, 0x42, 0x00, 0x20, 0x00, 0x6b, 0x00, 0x24, 0x00, 0x97, 0x00, 0x2b, 0x00, 0xc0, 0x00, 0x35, 0x00, 0xdd, 0x00, 0x3a, 0x00, 0xec, 0x00, 0x34, 0x00, 0xf4, 0x00, 0x2c, 0x00, 0xf6, 0x00, 0x1f, 0x00, 0xec, 0x00, 0x07, 0x00, 0xdc, 0x00, 0xec, 0xff, 0xc9, 0x00, 0xcf, 0xff, 0xaf, 0x00, 0xb0, 0xff, 0x8f, 0x00, 0x8f, 0xff, 0x71, 0x00, 0x74, 0xff, 0x55, 0x00, 0x5d, 0xff, 0x37, 0x00, 0x46, 0xff, 0x20, 0x00, 0x32, 0xff, 0x17, 0x00, 0x2b, 0xff, 0x13, 0x00, 0x2a, 0xff, 0x0e, 0x00, 0x2c, 0xff, 0x0e, 0x00, 0x3a, 0xff, 0x10, 0x00, 0x4d, 0xff, 0x0e, 0x00, 0x5c, 0xff, 0x0d, 0x00, 0x68, 0xff, 0x16, 0x00, 0x7b, 0xff, 0x1c, 0x00, 0x8b, 0xff, 0x18, 0x00, 0x92, 0xff, 0x16, 0x00, 0x9c, 0xff, 0x11, 0x00, 0xa4, 0xff, 0xfd, 0xff, 0x9a, 0xff, 0xdf, 0xff, 0x86, 0xff, 0xce, 0xff, 0x7c, 0xff, 0xc5, 0xff, 0x7c, 0xff, 0xb6, 0xff, 0x75, 0xff, 0xa1, 0xff, 0x69, 0xff, 0x8e, 0xff, 0x5f, 0xff, 0x80, 0xff, 0x5b, 0xff, 0x7d, 0xff, 0x65, 0xff, 0x89, 0xff, 0x80, 0xff, 0x92, 0xff, 0x99, 0xff, 0x90, 0xff, 0xa5, 0xff, 0x96, 0xff, 0xb8, 0xff, 0xac, 0xff, 0xdc, 0xff, 0xbe, 0xff, 0xfc, 0xff, 0xc7, 0xff, 0x15, 0x00, 0xce, 0xff, 0x2b, 0x00, 0xcb, 0xff, 0x36, 0x00, 0xbd, 0xff, 0x33, 0x00, 0xaf, 0xff, 0x31, 0x00, 0xa4, 0xff, 0x33, 0x00, 0x92, 0xff, 0x31, 0x00, 0x89, 0xff, 0x3a, 0x00, 0x97, 0xff, 0x5a, 0x00, 0x98, 0xff, 0x6b, 0x00, 0x7e, 0xff, 0x59, 0x00, 0x77, 0xff, 0x55, 0x00, 0xa0, 0xff, 0x7a, 0x00, 0xc8, 0xff, 0x9c, 0x00, 0xca, 0xff, 0x96, 0x00, 0xc4, 0xff, 0x88, 0x00, 0xcb, 0xff, 0x87, 0x00, 0xdf, 0xff, 0x8e, 0x00, 0x03, 0x00, 0xa1, 0x00, 0x2b, 0x00, 0xb3, 0x00, 0x35, 0x00, 0xa2, 0x00, 0x23, 0x00, 0x78, 0x00, 0x28, 0x00, 0x64, 0x00, 0x45, 0x00, 0x6b, 0x00, 0x4d, 0x00, 0x60, 0x00, 0x44, 0x00, 0x45, 0x00, 0x48, 0x00, 0x36, 0x00, 0x52, 0x00, 0x2d, 0x00, 0x55, 0x00, 0x1d, 0x00, 0x61, 0x00, 0x19, 0x00, 0x72, 0x00, 0x21, 0x00, 0x73, 0x00, 0x1e, 0x00, 0x72, 0x00, 0x1c, 0x00, 0x84, 0x00, 0x2e, 0x00, 0x9a, 0x00, 0x40, 0x00, 0xa4, 0x00, 0x42, 0x00, 0xb2, 0x00, 0x46, 0x00, 0xc5, 0x00, 0x53, 0x00, 0xcb, 0x00, 0x56, 0x00, 0xc3, 0x00, 0x4f, 0x00, 0xbc, 0x00, 0x4a, 0x00, 0xad, 0x00, 0x3a, 0x00, 0x93, 0x00, 0x1b, 0x00, 0x7f, 0x00, 0xfc, 0xff, 0x6d, 0x00, 0xdd, 0xff, 0x4b, 0x00, 0xae, 0xff, 0x2a, 0x00, 0x83, 0xff, 0x1c, 0x00, 0x6f, 0xff, 0x0f, 0x00, 0x5c, 0xff, 0xf4, 0xff, 0x3d, 0xff, 0xe4, 0xff, 0x2a, 0xff, 0xe9, 0xff, 0x2f, 0xff, 0xec, 0xff, 0x35, 0xff, 0xe5, 0xff, 0x32, 0xff, 0xe1, 0xff, 0x35, 0xff, 0xe1, 0xff, 0x3e, 0xff, 0xde, 0xff, 0x47, 0xff, 0xdd, 0xff, 0x53, 0xff, 0xdf, 0xff, 0x63, 0xff, 0xd8, 0xff, 0x6b, 0xff, 0xcc, 0xff, 0x70, 0xff, 0xc3, 0xff, 0x78, 0xff, 0xb5, 0xff, 0x7d, 0xff, 0x9d, 0xff, 0x7b, 0xff, 0x8a, 0xff, 0x7d, 0xff, 0x7b, 0xff, 0x81, 0xff, 0x6c, 0xff, 0x81, 0xff, 0x63, 0xff, 0x86, 0xff, 0x61, 0xff, 0x93, 0xff, 0x5c, 0xff, 0xa1, 0xff, 0x54, 0xff, 0xaf, 0xff, 0x5b, 0xff, 0xce, 0xff, 0x6e, 0xff, 0xf9, 0xff, 0x7f, 0xff, 0x1e, 0x00, 0x90, 0xff, 0x40, 0x00, 0xa8, 0xff, 0x65, 0x00, 0xba, 0xff, 0x83, 0x00, 0xc4, 0xff, 0x99, 0x00, 0xd4, 0xff, 0xb5, 0x00, 0xe6, 0xff, 0xd3, 0x00, 0xe5, 0xff, 0xe0, 0x00, 0xd5, 0xff, 0xde, 0x00, 0xce, 0xff, 0xe1, 0x00, 0xcf, 0xff, 0xe9, 0x00, 0xc9, 0xff, 0xe9, 0x00, 0xb8, 0xff, 0xdb, 0x00, 0xa1, 0xff, 0xc5, 0x00, 0x8f, 0xff, 0xb6, 0x00, 0x8e, 0xff, 0xba, 0x00, 0x9c, 0xff, 0xcd, 0x00, 0xa8, 0xff, 0xde, 0x00, 0xab, 0xff, 0xe2, 0x00, 0xae, 0xff, 0xe5, 0x00, 0xbb, 0xff, 0xef, 0x00, 0xcf, 0xff, 0xff, 0x00, 0xe8, 0xff, 0x12, 0x01, 0x02, 0x00, 0x23, 0x01, 0x16, 0x00, 0x2a, 0x01, 0x25, 0x00, 0x2c, 0x01, 0x37, 0x00, 0x30, 0x01, 0x47, 0x00, 0x34, 0x01, 0x4f, 0x00, 0x2d, 0x01, 0x54, 0x00, 0x22, 0x01, 0x62, 0x00, 0x1c, 0x01, 0x74, 0x00, 0x19, 0x01, 0x80, 0x00, 0x0e, 0x01, 0x82, 0x00, 0xfa, 0x00, 0x7f, 0x00, 0xde, 0x00, 0x77, 0x00, 0xbb, 0x00, 0x75, 0x00, 0x9b, 0x00, 0x7a, 0x00, 0x84, 0x00, 0x7f, 0x00, 0x70, 0x00, 0x7c, 0x00, 0x5c, 0x00, 0x77, 0x00, 0x49, 0x00, 0x76, 0x00, 0x3c, 0x00, 0x73, 0x00, 0x2c, 0x00, 0x6b, 0x00, 0x17, 0x00, 0x64, 0x00, 0x02, 0x00, 0x60, 0x00, 0xf2, 0xff, 0x58, 0x00, 0xdf, 0xff, 0x4d, 0x00, 0xc6, 0xff, 0x42, 0x00, 0xae, 0xff, 0x37, 0x00, 0x96, 0xff, 0x29, 0x00, 0x7a, 0xff, 0x14, 0x00, 0x5a, 0xff, 0xff, 0xff, 0x3a, 0xff, 0xef, 0xff, 0x1e, 0xff, 0xe6, 0xff, 0x07, 0xff, 0xe6, 0xff, 0xfa, 0xfe, 0xec, 0xff, 0xf4, 0xfe, 0xf0, 0xff, 0xf3, 0xfe, 0xef, 0xff, 0xef, 0xfe, 0xe8, 0xff, 0xea, 0xfe, 0xe1, 0xff, 0xe7, 0xfe, 0xdb, 0xff, 0xe9, 0xfe, 0xdb, 0xff, 0xf0, 0xfe, 0xde, 0xff, 0xfa, 0xfe, 0xe2, 0xff, 0x05, 0xff, 0xe5, 0xff, 0x0e, 0xff, 0xe5, 0xff, 0x16, 0xff, 0xe0, 0xff, 0x1c, 0xff, 0xda, 0xff, 0x21, 0xff, 0xd6, 0xff, 0x2a, 0xff, 0xd1, 0xff, 0x33, 0xff, 0xcf, 0xff, 0x40, 0xff, 0xd2, 0xff, 0x54, 0xff, 0xd6, 0xff, 0x6e, 0xff, 0xd7, 0xff, 0x82, 0xff, 0xd0, 0xff, 0x8c, 0xff, 0xca, 0xff, 0x91, 0xff, 0xc8, 0xff, 0x98, 0xff, 0xc7, 0xff, 0xa2, 0xff, 0xc2, 0xff, 0xae, 0xff, 0xb9, 0xff, 0xba, 0xff, 0xaa, 0xff, 0xc3, 0xff, 0x9c, 0xff, 0xca, 0xff, 0x96, 0xff, 0xd5, 0xff, 0x95, 0xff, 0xe1, 0xff, 0x94, 0xff, 0xe9, 0xff, 0x94, 0xff, 0xef, 0xff, 0x98, 0xff, 0xfc, 0xff, 0x9e, 0xff, 0x0e, 0x00, 0xa6, 0xff, 0x25, 0x00, 0xad, 0xff, 0x38, 0x00, 0xb5, 0xff, 0x47, 0x00, 0xc0, 0xff, 0x54, 0x00, 0xd4, 0xff, 0x66, 0x00, 0xf0, 0xff, 0x82, 0x00, 0x08, 0x00, 0x98, 0x00, 0x16, 0x00, 0xa5, 0x00, 0x26, 0x00, 0xb0, 0x00, 0x3b, 0x00, 0xbc, 0x00, 0x4c, 0x00, 0xc4, 0x00, 0x5c, 0x00, 0xca, 0x00, 0x6a, 0x00, 0xce, 0x00, 0x74, 0x00, 0xce, 0x00, 0x7b, 0x00, 0xcb, 0x00, 0x80, 0x00, 0xc6, 0x00, 0x83, 0x00, 0xbc, 0x00, 0x77, 0x00, 0xa1, 0x00, 0x60, 0x00, 0x78, 0x00, 0x4b, 0x00, 0x51, 0x00, 0x46, 0x00, 0x3c, 0x00, 0x53, 0x00, 0x3e, 0x00, 0x6c, 0x00, 0x50, 0x00, 0x82, 0x00, 0x61, 0x00, 0x8c, 0x00, 0x62, 0x00, 0x8a, 0x00, 0x53, 0x00, 0x7d, 0x00, 0x36, 0x00, 0x65, 0x00, 0x10, 0x00, 0x4a, 0x00, 0xe9, 0xff, 0x30, 0x00, 0xcb, 0xff, 0x16, 0x00, 0xb1, 0xff, 0x03, 0x00, 0xa0, 0xff, 0x04, 0x00, 0xa4, 0xff, 0x13, 0x00, 0xb4, 0xff, 0x1a, 0x00, 0xbb, 0xff, 0x0d, 0x00, 0xaf, 0xff, 0xf0, 0xff, 0x98, 0xff, 0xcf, 0xff, 0x80, 0xff, 0xb6, 0xff, 0x72, 0xff, 0xb2, 0xff, 0x78, 0xff, 0xbd, 0xff, 0x88, 0xff, 0xc3, 0xff, 0x8e, 0xff, 0xc1, 0xff, 0x87, 0xff, 0xc0, 0xff, 0x7f, 0xff, 0xc0, 0xff, 0x7b, 0xff, 0xbd, 0xff, 0x76, 0xff, 0xbb, 0xff, 0x75, 0xff, 0xbf, 0xff, 0x7a, 0xff, 0xc1, 0xff, 0x79, 0xff, 0xbb, 0xff, 0x6d, 0xff, 0xb9, 0xff, 0x62, 0xff, 0xbe, 0xff, 0x5e, 0xff, 0xc5, 0xff, 0x61, 0xff, 0xca, 0xff, 0x66, 0xff, 0xcb, 0xff, 0x69, 0xff, 0xc3, 0xff, 0x65, 0xff, 0xb3, 0xff, 0x58, 0xff, 0xa6, 0xff, 0x4c, 0xff, 0x9f, 0xff, 0x48, 0xff, 0xa0, 0xff, 0x4e, 0xff, 0xa8, 0xff, 0x60, 0xff, 0xb3, 0xff, 0x79, 0xff, 0xbf, 0xff, 0x9a, 0xff, 0xd0, 0xff, 0xc1, 0xff, 0xe6, 0xff, 0xec, 0xff, 0xfd, 0xff, 0x15, 0x00, 0x09, 0x00, 0x34, 0x00, 0x0d, 0x00, 0x4c, 0x00, 0x15, 0x00, 0x69, 0x00, 0x1f, 0x00, 0x89, 0x00, 0x24, 0x00, 0xa2, 0x00, 0x22, 0x00, 0xad, 0x00, 0x20, 0x00, 0xb2, 0x00, 0x23, 0x00, 0xb9, 0x00, 0x26, 0x00, 0xbf, 0x00, 0x24, 0x00, 0xc3, 0x00, 0x1e, 0x00, 0xc6, 0x00, 0x14, 0x00, 0xc7, 0x00, 0x0a, 0x00, 0xc7, 0x00, 0x08, 0x00, 0xcb, 0x00, 0x10, 0x00, 0xd3, 0x00, 0x17, 0x00, 0xd6, 0x00, 0x1c, 0x00, 0xd4, 0x00, 0x23, 0x00, 0xd6, 0x00, 0x29, 0x00, 0xda, 0x00, 0x29, 0x00, 0xda, 0x00, 0x29, 0x00, 0xda, 0x00, 0x2d, 0x00, 0xdd, 0x00, 0x2f, 0x00, 0xdb, 0x00, 0x2b, 0x00, 0xcd, 0x00, 0x27, 0x00, 0xbe, 0x00, 0x23, 0x00, 0xae, 0x00, 0x17, 0x00, 0x98, 0x00, 0x08, 0x00, 0x7f, 0x00, 0xfc, 0xff, 0x6b, 0x00, 0xf5, 0xff, 0x57, 0x00, 0xeb, 0xff, 0x3e, 0x00, 0xe4, 0xff, 0x23, 0x00, 0xe1, 0xff, 0x0e, 0x00, 0xe3, 0xff, 0x03, 0x00, 0xe6, 0xff, 0xfd, 0xff, 0xe9, 0xff, 0xfd, 0xff, 0xed, 0xff, 0xfe, 0xff, 0xed, 0xff, 0xfa, 0xff, 0xec, 0xff, 0xf3, 0xff, 0xea, 0xff, 0xec, 0xff, 0xe4, 0xff, 0xe3, 0xff, 0xdb, 0xff, 0xd6, 0xff, 0xd1, 0xff, 0xc9, 0xff, 0xc9, 0xff, 0xbe, 0xff, 0xc1, 0xff, 0xb2, 0xff, 0xb7, 0xff, 0xa4, 0xff, 0xb0, 0xff, 0x98, 0xff, 0xb0, 0xff, 0x91, 0xff, 0xae, 0xff, 0x89, 0xff, 0xa5, 0xff, 0x7b, 0xff, 0x97, 0xff, 0x67, 0xff, 0x8a, 0xff, 0x53, 0xff, 0x80, 0xff, 0x3d, 0xff, 0x78, 0xff, 0x26, 0xff, 0x73, 0xff, 0x10, 0xff, 0x74, 0xff, 0xfd, 0xfe, 0x7c, 0xff, 0xf1, 0xfe, 0x84, 0xff, 0xe8, 0xfe, 0x8a, 0xff, 0xe2, 0xfe, 0x8e, 0xff, 0xe1, 0xfe, 0x95, 0xff, 0xe8, 0xfe, 0xa5, 0xff, 0xf8, 0xfe, 0xba, 0xff, 0x0d, 0xff, 0xd2, 0xff, 0x23, 0xff, 0xe8, 0xff, 0x37, 0xff, 0xf9, 0xff, 0x4b, 0xff, 0x06, 0x00, 0x5d, 0xff, 0x0d, 0x00, 0x6e, 0xff, 0x12, 0x00, 0x7e, 0xff, 0x15, 0x00, 0x8c, 0xff, 0x12, 0x00, 0x92, 0xff, 0x0a, 0x00, 0x92, 0xff, 0x02, 0x00, 0x94, 0xff, 0xff, 0xff, 0x9a, 0xff, 0xfc, 0xff, 0xa2, 0xff, 0xfd, 0xff, 0xae, 0xff, 0x02, 0x00, 0xbc, 0xff, 0x0a, 0x00, 0xcd, 0xff, 0x17, 0x00, 0xe1, 0xff, 0x24, 0x00, 0xf6, 0xff, 0x31, 0x00, 0x0b, 0x00, 0x3f, 0x00, 0x22, 0x00, 0x51, 0x00, 0x3a, 0x00, 0x66, 0x00, 0x53, 0x00, 0x80, 0x00, 0x69, 0x00, 0x9c, 0x00, 0x7d, 0x00, 0xba, 0x00, 0x91, 0x00, 0xd3, 0x00, 0xa1, 0x00, 0xe3, 0x00, 0xab, 0x00, 0xeb, 0x00, 0xb3, 0x00, 0xf2, 0x00, 0xb9, 0x00, 0xf9, 0x00, 0xc0, 0x00, 0x05, 0x01, 0xca, 0x00, 0x13, 0x01, 0xd1, 0x00, 0x1f, 0x01, 0xd2, 0x00, 0x2c, 0x01, 0xd1, 0x00, 0x38, 0x01, 0xcf, 0x00, 0x3f, 0x01, 0xcd, 0x00, 0x3c, 0x01, 0xc3, 0x00, 0x30, 0x01, 0xb2, 0x00, 0x25, 0x01, 0xa0, 0x00, 0x1c, 0x01, 0x91, 0x00, 0x13, 0x01, 0x84, 0x00, 0x0a, 0x01, 0x77, 0x00, 0xfc, 0x00, 0x68, 0x00, 0xeb, 0x00, 0x55, 0x00, 0xd6, 0x00, 0x3f, 0x00, 0xbf, 0x00, 0x2a, 0x00, 0xa8, 0x00, 0x18, 0x00, 0x8f, 0x00, 0x09, 0x00, 0x72, 0x00, 0xfb, 0xff, 0x53, 0x00, 0xec, 0xff, 0x35, 0x00, 0xdc, 0xff, 0x19, 0x00, 0xca, 0xff, 0x00, 0x00, 0xb6, 0xff, 0xe8, 0xff, 0xa0, 0xff, 0xcd, 0xff, 0x8a, 0xff, 0xb1, 0xff, 0x78, 0xff, 0x96, 0xff, 0x6d, 0xff, 0x7d, 0xff, 0x66, 0xff, 0x67, 0xff, 0x63, 0xff, 0x58, 0xff, 0x61, 0xff, 0x53, 0xff, 0x64, 0xff, 0x57, 0xff, 0x67, 0xff, 0x5d, 0xff, 0x6b, 0xff, 0x63, 0xff, 0x6f, 0xff, 0x65, 0xff, 0x75, 0xff, 0x62, 0xff, 0x7d, 0xff, 0x5f, 0xff, 0x87, 0xff, 0x5c, 0xff, 0x8e, 0xff, 0x5b, 0xff, 0x90, 0xff, 0x59, 0xff, 0x8b, 0xff, 0x56, 0xff, 0x85, 0xff, 0x53, 0xff, 0x7f, 0xff, 0x4e, 0xff, 0x7d, 0xff, 0x47, 0xff, 0x7f, 0xff, 0x40, 0xff, 0x81, 0xff, 0x39, 0xff, 0x82, 0xff, 0x33, 0xff, 0x81, 0xff, 0x2f, 0xff, 0x7f, 0xff, 0x31, 0xff, 0x7f, 0xff, 0x3b, 0xff, 0x86, 0xff, 0x4b, 0xff, 0x93, 0xff, 0x5b, 0xff, 0xa0, 0xff, 0x6d, 0xff, 0xb0, 0xff, 0x81, 0xff, 0xc2, 0xff, 0x96, 0xff, 0xd8, 0xff, 0xac, 0xff, 0xf0, 0xff, 0xbf, 0xff, 0x05, 0x00, 0xcf, 0xff, 0x15, 0x00, 0xdf, 0xff, 0x20, 0x00, 0xef, 0xff, 0x2a, 0x00, 0xfd, 0xff, 0x31, 0x00, 0x09, 0x00, 0x38, 0x00, 0x13, 0x00, 0x3d, 0x00, 0x1c, 0x00, 0x44, 0x00, 0x23, 0x00, 0x4d, 0x00, 0x2a, 0x00, 0x59, 0x00, 0x31, 0x00, 0x67, 0x00, 0x36, 0x00, 0x71, 0x00, 0x3e, 0x00, 0x77, 0x00, 0x4b, 0x00, 0x7a, 0x00, 0x5c, 0x00, 0x7f, 0x00, 0x6f, 0x00, 0x88, 0x00, 0x7d, 0x00, 0x92, 0x00, 0x85, 0x00, 0x9b, 0x00, 0x8a, 0x00, 0xa2, 0x00, 0x8d, 0x00, 0xa2, 0x00, 0x90, 0x00, 0x9d, 0x00, 0x93, 0x00, 0x94, 0x00, 0x99, 0x00, 0x8c, 0x00, 0xa0, 0x00, 0x87, 0x00, 0xa6, 0x00, 0x84, 0x00, 0xa4, 0x00, 0x7d, 0x00, 0x9d, 0x00, 0x74, 0x00, 0x96, 0x00, 0x6c, 0x00, 0x8f, 0x00, 0x61, 0x00, 0x8a, 0x00, 0x55, 0x00, 0x83, 0x00, 0x47, 0x00, 0x7c, 0x00, 0x3a, 0x00, 0x71, 0x00, 0x2d, 0x00, 0x63, 0x00, 0x22, 0x00, 0x54, 0x00, 0x1b, 0x00, 0x45, 0x00, 0x15, 0x00, 0x38, 0x00, 0x0f, 0x00, 0x2b, 0x00, 0x07, 0x00, 0x1f, 0x00, 0x01, 0x00, 0x12, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xf9, 0xff, 0xf4, 0xff, 0xf9, 0xff, 0xe6, 0xff, 0xfc, 0xff, 0xd8, 0xff, 0xfd, 0xff, 0xcb, 0xff, 0xf9, 0xff, 0xbd, 0xff, 0xf2, 0xff, 0xab, 0xff, 0xe6, 0xff, 0x96, 0xff, 0xdb, 0xff, 0x7e, 0xff, 0xd3, 0xff, 0x64, 0xff, 0xce, 0xff, 0x4a, 0xff, 0xc9, 0xff, 0x35, 0xff, 0xc2, 0xff, 0x25, 0xff, 0xba, 0xff, 0x19, 0xff, 0xb3, 0xff, 0x0e, 0xff, 0xae, 0xff, 0x04, 0xff, 0xab, 0xff, 0xfa, 0xfe, 0xac, 0xff, 0xf2, 0xfe, 0xae, 0xff, 0xf0, 0xfe, 0xb4, 0xff, 0xf4, 0xfe, 0xbc, 0xff, 0xfc, 0xfe, 0xc4, 0xff, 0x06, 0xff, 0xca, 0xff, 0x0e, 0xff, 0xcf, 0xff, 0x14, 0xff, 0xd8, 0xff, 0x18, 0xff, 0xe3, 0xff, 0x1c, 0xff, 0xf0, 0xff, 0x23, 0xff, 0xfc, 0xff, 0x30, 0xff, 0x08, 0x00, 0x43, 0xff, 0x13, 0x00, 0x56, 0xff, 0x1a, 0x00, 0x69, 0xff, 0x23, 0x00, 0x7c, 0xff, 0x2d, 0x00, 0x8e, 0xff, 0x3c, 0x00, 0xa2, 0xff, 0x4c, 0x00, 0xb6, 0xff, 0x5b, 0x00, 0xcd, 0xff, 0x69, 0x00, 0xe4, 0xff, 0x75, 0x00, 0xfc, 0xff, 0x7d, 0x00, 0x11, 0x00, 0x85, 0x00, 0x22, 0x00, 0x8f, 0x00, 0x2e, 0x00, 0x98, 0x00, 0x35, 0x00, 0xa0, 0x00, 0x3a, 0x00, 0xa5, 0x00, 0x40, 0x00, 0xa6, 0x00, 0x4a, 0x00, 0xa6, 0x00, 0x57, 0x00, 0xa4, 0x00, 0x63, 0x00, 0xa0, 0x00, 0x6d, 0x00, 0x9e, 0x00, 0x75, 0x00, 0x9e, 0x00, 0x7c, 0x00, 0xa0, 0x00, 0x82, 0x00, 0xa1, 0x00, 0x89, 0x00, 0x9f, 0x00, 0x90, 0x00, 0x9a, 0x00, 0x97, 0x00, 0x93, 0x00, 0x9e, 0x00, 0x8c, 0x00, 0xa5, 0x00, 0x87, 0x00, 0xac, 0x00, 0x83, 0x00, 0xb1, 0x00, 0x7e, 0x00, 0xb4, 0x00, 0x79, 0x00, 0xb5, 0x00, 0x71, 0x00, 0xb5, 0x00, 0x68, 0x00, 0xb4, 0x00, 0x5e, 0x00, 0xaf, 0x00, 0x54, 0x00, 0xa7, 0x00, 0x4c, 0x00, 0x9a, 0x00, 0x46, 0x00, 0x8f, 0x00, 0x41, 0x00, 0x82, 0x00, 0x3b, 0x00, 0x73, 0x00, 0x2f, 0x00, 0x63, 0x00, 0x22, 0x00, 0x53, 0x00, 0x15, 0x00, 0x43, 0x00, 0x0d, 0x00, 0x32, 0x00, 0x05, 0x00, 0x1f, 0x00, 0xfa, 0xff, 0x0d, 0x00, 0xf1, 0xff, 0xff, 0xff, 0xe8, 0xff, 0xf5, 0xff, 0xe1, 0xff, 0xf2, 0xff, 0xdf, 0xff, 0xf1, 0xff, 0xdd, 0xff, 0xec, 0xff, 0xd8, 0xff, 0xe5, 0xff, 0xd0, 0xff, 0xdc, 0xff, 0xc6, 0xff, 0xd1, 0xff, 0xb9, 0xff, 0xc5, 0xff, 0xa9, 0xff, 0xb9, 0xff, 0x9a, 0xff, 0xac, 0xff, 0x8c, 0xff, 0x9f, 0xff, 0x82, 0xff, 0x94, 0xff, 0x7c, 0xff, 0x8a, 0xff, 0x78, 0xff, 0x83, 0xff, 0x74, 0xff, 0x7d, 0xff, 0x6c, 0xff, 0x79, 0xff, 0x61, 0xff, 0x74, 0xff, 0x55, 0xff, 0x6f, 0xff, 0x49, 0xff, 0x6e, 0xff, 0x44, 0xff, 0x70, 0xff, 0x45, 0xff, 0x70, 0xff, 0x45, 0xff, 0x72, 0xff, 0x43, 0xff, 0x77, 0xff, 0x3f, 0xff, 0x80, 0xff, 0x3a, 0xff, 0x89, 0xff, 0x31, 0xff, 0x90, 0xff, 0x27, 0xff, 0x98, 0xff, 0x22, 0xff, 0xa0, 0xff, 0x22, 0xff, 0xa9, 0xff, 0x24, 0xff, 0xb3, 0xff, 0x26, 0xff, 0xbc, 0xff, 0x25, 0xff, 0xc8, 0xff, 0x25, 0xff, 0xd6, 0xff, 0x27, 0xff, 0xe7, 0xff, 0x2f, 0xff, 0xfb, 0xff, 0x3e, 0xff, 0x12, 0x00, 0x52, 0xff, 0x2a, 0x00, 0x6b, 0xff, 0x41, 0x00, 0x85, 0xff, 0x56, 0x00, 0x9c, 0xff, 0x6b, 0x00, 0xb2, 0xff, 0x7d, 0x00, 0xc5, 0xff, 0x8c, 0x00, 0xd5, 0xff, 0x95, 0x00, 0xe5, 0xff, 0x97, 0x00, 0xf5, 0xff, 0x96, 0x00, 0x04, 0x00, 0x94, 0x00, 0x10, 0x00, 0x93, 0x00, 0x18, 0x00, 0x95, 0x00, 0x1d, 0x00, 0x95, 0x00, 0x21, 0x00, 0x95, 0x00, 0x25, 0x00, 0x95, 0x00, 0x2b, 0x00, 0x98, 0x00, 0x36, 0x00, 0x9a, 0x00, 0x43, 0x00, 0x9c, 0x00, 0x51, 0x00, 0x9c, 0x00, 0x5c, 0x00, 0x9a, 0x00, 0x63, 0x00, 0x98, 0x00, 0x65, 0x00, 0x97, 0x00, 0x63, 0x00, 0x92, 0x00, 0x5b, 0x00, 0x86, 0x00, 0x4f, 0x00, 0x78, 0x00, 0x44, 0x00, 0x69, 0x00, 0x3b, 0x00, 0x59, 0x00, 0x32, 0x00, 0x47, 0x00, 0x27, 0x00, 0x36, 0x00, 0x1a, 0x00, 0x27, 0x00, 0x0c, 0x00, 0x19, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xe9, 0xff, 0xfd, 0xff, 0xd6, 0xff, 0xf5, 0xff, 0xcc, 0xff, 0xf3, 0xff, 0xcd, 0xff, 0xf8, 0xff, 0xd7, 0xff, 0xfe, 0xff, 0xe3, 0xff, 0x01, 0x00, 0xea, 0xff, 0x05, 0x00, 0xf1, 0xff, 0x0a, 0x00, 0xfb, 0xff, 0x0b, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0xee, 0xff, 0x00, 0x00, 0xdd, 0xff, 0xfb, 0xff, 0xce, 0xff, 0xf7, 0xff, 0xc3, 0xff, 0xf6, 0xff, 0xbb, 0xff, 0xf8, 0xff, 0xaf, 0xff, 0xf9, 0xff, 0x9d, 0xff, 0xf6, 0xff, 0x88, 0xff, 0xf0, 0xff, 0x71, 0xff, 0xe4, 0xff, 0x5a, 0xff, 0xd2, 0xff, 0x46, 0xff, 0xbe, 0xff, 0x37, 0xff, 0xa9, 0xff, 0x2b, 0xff, 0x95, 0xff, 0x22, 0xff, 0x84, 0xff, 0x1e, 0xff, 0x78, 0xff, 0x1d, 0xff, 0x70, 0xff, 0x20, 0xff, 0x6c, 0xff, 0x2a, 0xff, 0x6c, 0xff, 0x3c, 0xff, 0x6e, 0xff, 0x4f, 0xff, 0x6f, 0xff, 0x5d, 0xff, 0x6a, 0xff, 0x67, 0xff, 0x66, 0xff, 0x71, 0xff, 0x69, 0xff, 0x7a, 0xff, 0x71, 0xff, 0x85, 0xff, 0x7e, 0xff, 0x92, 0xff, 0x90, 0xff, 0xa3, 0xff, 0xa5, 0xff, 0xb6, 0xff, 0xbd, 0xff, 0xc8, 0xff, 0xd4, 0xff, 0xd6, 0xff, 0xeb, 0xff, 0xde, 0xff, 0xfc, 0xff, 0xe1, 0xff, 0x09, 0x00, 0xe5, 0xff, 0x13, 0x00, 0xea, 0xff, 0x1c, 0x00, 0xf5, 0xff, 0x28, 0x00, 0x0a, 0x00, 0x3d, 0x00, 0x27, 0x00, 0x59, 0x00, 0x41, 0x00, 0x70, 0x00, 0x52, 0x00, 0x7e, 0x00, 0x60, 0x00, 0x89, 0x00, 0x67, 0x00, 0x8d, 0x00, 0x6d, 0x00, 0x8e, 0x00, 0x72, 0x00, 0x8d, 0x00, 0x79, 0x00, 0x8a, 0x00, 0x7c, 0x00, 0x87, 0x00, 0x7b, 0x00, 0x86, 0x00, 0x79, 0x00, 0x8a, 0x00, 0x70, 0x00, 0x8d, 0x00, 0x64, 0x00, 0x8e, 0x00, 0x5c, 0x00, 0x91, 0x00, 0x52, 0x00, 0x92, 0x00, 0x46, 0x00, 0x90, 0x00, 0x3e, 0x00, 0x92, 0x00, 0x3e, 0x00, 0x9f, 0x00, 0x46, 0x00, 0xb5, 0x00, 0x51, 0x00, 0xce, 0x00, 0x55, 0x00, 0xdd, 0x00, 0x50, 0x00, 0xe1, 0x00, 0x43, 0x00, 0xda, 0x00, 0x32, 0x00, 0xce, 0x00, 0x24, 0x00, 0xc5, 0x00, 0x1a, 0x00, 0xbf, 0x00, 0x14, 0x00, 0xbc, 0x00, 0x15, 0x00, 0xbf, 0x00, 0x22, 0x00, 0xcd, 0x00, 0x30, 0x00, 0xdc, 0x00, 0x37, 0x00, 0xe3, 0x00, 0x2e, 0x00, 0xdc, 0x00, 0x12, 0x00, 0xc6, 0x00, 0xed, 0xff, 0xa9, 0x00, 0xcd, 0xff, 0x94, 0x00, 0xbb, 0xff, 0x89, 0x00, 0xb7, 0xff, 0x86, 0x00, 0xbe, 0xff, 0x88, 0x00, 0xca, 0xff, 0x8a, 0x00, 0xd3, 0xff, 0x88, 0x00, 0xd7, 0xff, 0x81, 0x00, 0xd4, 0xff, 0x76, 0x00, 0xc9, 0xff, 0x61, 0x00, 0xb6, 0xff, 0x40, 0x00, 0xa2, 0xff, 0x18, 0x00, 0x96, 0xff, 0xf2, 0xff, 0x95, 0xff, 0xd5, 0xff, 0x9f, 0xff, 0xc6, 0xff, 0xb1, 0xff, 0xc3, 0xff, 0xc4, 0xff, 0xc4, 0xff, 0xd5, 0xff, 0xc5, 0xff, 0xe0, 0xff, 0xc3, 0xff, 0xe8, 0xff, 0xc1, 0xff, 0xeb, 0xff, 0xbe, 0xff, 0xe9, 0xff, 0xb7, 0xff, 0xe4, 0xff, 0xaf, 0xff, 0xdf, 0xff, 0xa7, 0xff, 0xe1, 0xff, 0xa6, 0xff, 0xee, 0xff, 0xaf, 0xff, 0x06, 0x00, 0xc0, 0xff, 0x20, 0x00, 0xd1, 0xff, 0x37, 0x00, 0xdf, 0xff, 0x46, 0x00, 0xe9, 0xff, 0x4f, 0x00, 0xef, 0xff, 0x55, 0x00, 0xf4, 0xff, 0x5c, 0x00, 0xf7, 0xff, 0x65, 0x00, 0xf9, 0xff, 0x6f, 0x00, 0xf7, 0xff, 0x7f, 0x00, 0xf8, 0xff, 0x94, 0x00, 0xfd, 0xff, 0xa6, 0x00, 0x06, 0x00, 0xb1, 0x00, 0x0f, 0x00, 0xae, 0x00, 0x12, 0x00, 0xa0, 0x00, 0x0c, 0x00, 0x8a, 0x00, 0xfb, 0xff, 0x75, 0x00, 0xe6, 0xff, 0x66, 0x00, 0xd6, 0xff, 0x64, 0x00, 0xd4, 0xff, 0x6e, 0x00, 0xe3, 0xff, 0x7c, 0x00, 0xfd, 0xff, 0x8a, 0x00, 0x1a, 0x00, 0x97, 0x00, 0x33, 0x00, 0x9f, 0x00, 0x44, 0x00, 0xa0, 0x00, 0x4b, 0x00, 0x9e, 0x00, 0x48, 0x00, 0x95, 0x00, 0x3c, 0x00, 0x8c, 0x00, 0x31, 0x00, 0x85, 0x00, 0x2c, 0x00, 0x85, 0x00, 0x2e, 0x00, 0x90, 0x00, 0x3c, 0x00, 0xa5, 0x00, 0x50, 0x00, 0xb8, 0x00, 0x60, 0x00, 0xc7, 0x00, 0x6c, 0x00, 0xcf, 0x00, 0x74, 0x00, 0xc8, 0x00, 0x71, 0x00, 0xb4, 0x00, 0x68, 0x00, 0x9b, 0x00, 0x5e, 0x00, 0x80, 0x00, 0x54, 0x00, 0x65, 0x00, 0x48, 0x00, 0x52, 0x00, 0x40, 0x00, 0x48, 0x00, 0x3d, 0x00, 0x43, 0x00, 0x3e, 0x00, 0x3c, 0x00, 0x3e, 0x00, 0x30, 0x00, 0x3a, 0x00, 0x1b, 0x00, 0x2f, 0x00, 0x01, 0x00, 0x1c, 0x00, 0xe4, 0xff, 0x02, 0x00, 0xcd, 0xff, 0xe9, 0xff, 0xc2, 0xff, 0xd6, 0xff, 0xbe, 0xff, 0xc9, 0xff, 0xba, 0xff, 0xba, 0xff, 0xb8, 0xff, 0xaf, 0xff, 0xba, 0xff, 0xaa, 0xff, 0xb0, 0xff, 0x99, 0xff, 0x98, 0xff, 0x78, 0xff, 0x84, 0xff, 0x58, 0xff, 0x72, 0xff, 0x3b, 0xff, 0x5e, 0xff, 0x1b, 0xff, 0x5e, 0xff, 0x12, 0xff, 0x7b, 0xff, 0x29, 0xff, 0x94, 0xff, 0x3d, 0xff, 0x9f, 0xff, 0x46, 0xff, 0xa6, 0xff, 0x4a, 0xff, 0xa2, 0xff, 0x41, 0xff, 0x90, 0xff, 0x29, 0xff, 0x81, 0xff, 0x14, 0xff, 0x7a, 0xff, 0x07, 0xff, 0x78, 0xff, 0x00, 0xff, 0x83, 0xff, 0x07, 0xff, 0x9a, 0xff, 0x1a, 0xff, 0xb0, 0xff, 0x2c, 0xff, 0xc0, 0xff, 0x38, 0xff, 0xc7, 0xff, 0x3d, 0xff, 0xba, 0xff, 0x2f, 0xff, 0xa1, 0xff, 0x17, 0xff, 0x97, 0xff, 0x12, 0xff, 0x9a, 0xff, 0x1b, 0xff, 0xa7, 0xff, 0x2c, 0xff, 0xd2, 0xff, 0x58, 0xff, 0x11, 0x00, 0x99, 0xff, 0x34, 0x00, 0xc3, 0xff, 0x27, 0x00, 0xc2, 0xff, 0xf2, 0xff, 0x9e, 0xff, 0x9e, 0xff, 0x5a, 0xff, 0x53, 0xff, 0x1d, 0xff, 0x33, 0xff, 0x0a, 0xff, 0x39, 0xff, 0x1d, 0xff, 0x67, 0xff, 0x58, 0xff, 0xcb, 0xff, 0xc9, 0xff, 0x44, 0x00, 0x4b, 0x00, 0xa2, 0x00, 0xb2, 0x00, 0xc9, 0x00, 0xde, 0x00, 0x96, 0x00, 0xad, 0x00, 0x1a, 0x00, 0x30, 0x00, 0xa1, 0xff, 0xb3, 0xff, 0x58, 0xff, 0x66, 0xff, 0x55, 0xff, 0x63, 0xff, 0xae, 0xff, 0xc3, 0xff, 0x3b, 0x00, 0x5d, 0x00, 0xb5, 0x00, 0xe4, 0x00, 0xf6, 0x00, 0x2f, 0x01, 0xe5, 0x00, 0x24, 0x01, 0x8b, 0x00, 0xcd, 0x00, 0x29, 0x00, 0x6f, 0x00, 0xf1, 0xff, 0x42, 0x00, 0xf4, 0xff, 0x55, 0x00, 0x32, 0x00, 0xa7, 0x00, 0x71, 0x00, 0xfa, 0x00, 0x6c, 0x00, 0x05, 0x01, 0x0d, 0x00, 0xb0, 0x00, 0x60, 0xff, 0x09, 0x00, 0xae, 0xfe, 0x5b, 0xff, 0x66, 0xfe, 0x14, 0xff, 0xbf, 0xfe, 0x6d, 0xff, 0xb2, 0xff, 0x61, 0x00, 0xfb, 0x00, 0xaa, 0x01, 0x0e, 0x02, 0xbd, 0x02, 0x7e, 0x02, 0x2d, 0x03, 0x15, 0x02, 0xc0, 0x02, 0xb1, 0x00, 0x52, 0x01, 0xcc, 0xfe, 0x5e, 0xff, 0x6a, 0xfd, 0xea, 0xfd, 0x17, 0xfd, 0x86, 0xfd, 0xee, 0xfd, 0x4f, 0xfe, 0xd1, 0xff, 0x29, 0x00, 0xf6, 0x01, 0x46, 0x02, 0x61, 0x03, 0xa9, 0x03, 0xad, 0x03, 0xea, 0x03, 0xb2, 0x02, 0xe1, 0x02, 0xa7, 0x00, 0xca, 0x00, 0x8d, 0xfe, 0xa2, 0xfe, 0x50, 0xfd, 0x56, 0xfd, 0x3d, 0xfd, 0x33, 0xfd, 0x52, 0xfe, 0x39, 0xfe, 0x0b, 0x00, 0xe6, 0xff, 0x88, 0x01, 0x5b, 0x01, 0x42, 0x02, 0x10, 0x02, 0x02, 0x02, 0xcb, 0x01, 0xd8, 0x00, 0x9d, 0x00, 0x58, 0xff, 0x18, 0xff, 0x22, 0xfe, 0xe0, 0xfd, 0x98, 0xfd, 0x54, 0xfd, 0xee, 0xfd, 0xa9, 0xfd, 0xeb, 0xfe, 0xa7, 0xfe, 0xff, 0xff, 0xbd, 0xff, 0xc7, 0x00, 0x8c, 0x00, 0xfd, 0x00, 0xcc, 0x00, 0x7b, 0x00, 0x54, 0x00, 0x8a, 0xff, 0x68, 0xff, 0x84, 0xfe, 0x63, 0xfe, 0xbe, 0xfd, 0x9a, 0xfd, 0xa2, 0xfd, 0x7d, 0xfd, 0x33, 0xfe, 0x0e, 0xfe, 0x12, 0xff, 0xf2, 0xfe, 0x01, 0x00, 0xe9, 0xff, 0xb4, 0x00, 0xa7, 0x00, 0xe0, 0x00, 0xde, 0x00, 0x9a, 0x00, 0xa0, 0x00, 0x06, 0x00, 0x0f, 0x00, 0x39, 0xff, 0x40, 0xff, 0x90, 0xfe, 0x95, 0xfe, 0x49, 0xfe, 0x4e, 0xfe, 0x69, 0xfe, 0x72, 0xfe, 0x02, 0xff, 0x13, 0xff, 0xe8, 0xff, 0x06, 0x00, 0xac, 0x00, 0xd8, 0x00, 0x19, 0x01, 0x51, 0x01, 0x12, 0x01, 0x51, 0x01, 0x84, 0x00, 0xc7, 0x00, 0xbb, 0xff, 0x00, 0x00, 0x0b, 0xff, 0x50, 0xff, 0x98, 0xfe, 0xde, 0xfe, 0xa4, 0xfe, 0xeb, 0xfe, 0x39, 0xff, 0x80, 0xff, 0xf2, 0xff, 0x39, 0x00, 0x85, 0x00, 0xcb, 0x00, 0xd3, 0x00, 0x17, 0x01, 0xb6, 0x00, 0xf8, 0x00, 0x4f, 0x00, 0x90, 0x00, 0xf2, 0xff, 0x32, 0x00, 0xbe, 0xff, 0xfc, 0xff, 0xba, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0x39, 0x00, 0x5f, 0x00, 0xa2, 0x00, 0xc3, 0x00, 0x0c, 0x01, 0xfb, 0x00, 0x4b, 0x01, 0xe0, 0x00, 0x35, 0x01, 0x75, 0x00, 0xcf, 0x00, 0xeb, 0xff, 0x49, 0x00, 0x7f, 0xff, 0xe0, 0xff, 0x6d, 0xff, 0xcf, 0xff, 0xc9, 0xff, 0x29, 0x00, 0x63, 0x00, 0xc2, 0x00, 0xfd, 0x00, 0x5b, 0x01, 0x60, 0x01, 0xbe, 0x01, 0x58, 0x01, 0xb4, 0x01, 0xda, 0x00, 0x31, 0x01, 0x11, 0x00, 0x61, 0x00, 0x37, 0xff, 0x7e, 0xff, 0xa0, 0xfe, 0xdf, 0xfe, 0xad, 0xfe, 0xe4, 0xfe, 0x6b, 0xff, 0x9a, 0xff, 0x7b, 0x00, 0x9e, 0x00, 0x63, 0x01, 0x79, 0x01, 0xce, 0x01, 0xd5, 0x01, 0x95, 0x01, 0x8a, 0x01, 0xcb, 0x00, 0xac, 0x00, 0xc0, 0xff, 0x8c, 0xff, 0xe7, 0xfe, 0x9f, 0xfe, 0xa9, 0xfe, 0x4f, 0xfe, 0x36, 0xff, 0xce, 0xfe, 0x6e, 0x00, 0xfa, 0xff, 0xc9, 0x01, 0x48, 0x01, 0x7b, 0x02, 0xea, 0x01, 0x0f, 0x02, 0x6b, 0x01, 0xc1, 0x00, 0x08, 0x00, 0x17, 0xff, 0x4f, 0xfe, 0xba, 0xfd, 0xea, 0xfc, 0x6e, 0xfd, 0x9f, 0xfc, 0x70, 0xfe, 0xa7, 0xfd, 0x34, 0x00, 0x75, 0xff, 0xf4, 0x01, 0x40, 0x01, 0xe6, 0x02, 0x3e, 0x02, 0x6e, 0x02, 0xd2, 0x01, 0xbe, 0x00, 0x2f, 0x00, 0xb3, 0xfe, 0x32, 0xfe, 0x27, 0xfd, 0xb7, 0xfc, 0xa8, 0xfc, 0x50, 0xfc, 0x5c, 0xfd, 0x22, 0xfd, 0xf2, 0xfe, 0xd8, 0xfe, 0xb9, 0x00, 0xbc, 0x00, 0xdc, 0x01, 0xf8, 0x01, 0xdf, 0x01, 0x0e, 0x02, 0xe2, 0x00, 0x21, 0x01, 0x52, 0xff, 0x9e, 0xff, 0xc4, 0xfd, 0x1c, 0xfe, 0xfa, 0xfc, 0x59, 0xfd, 0x47, 0xfd, 0xaa, 0xfd, 0x5b, 0xfe, 0xc0, 0xfe, 0xc4, 0xff, 0x2c, 0x00, 0x0a, 0x01, 0x76, 0x01, 0xa5, 0x01, 0x14, 0x02, 0x63, 0x01, 0xd4, 0x01, 0x85, 0x00, 0xf6, 0x00, 0x76, 0xff, 0xe6, 0xff, 0x96, 0xfe, 0x03, 0xff, 0x10, 0xfe, 0x7e, 0xfe, 0x22, 0xfe, 0x93, 0xfe, 0xf7, 0xfe, 0x6e, 0xff, 0x22, 0x00, 0x9f, 0x00, 0x18, 0x01, 0x9b, 0x01, 0xbf, 0x01, 0x46, 0x02, 0xf5, 0x01, 0x7d, 0x02, 0x78, 0x01, 0xff, 0x01, 0x90, 0x00, 0x14, 0x01, 0xa5, 0xff, 0x22, 0x00, 0xd1, 0xfe, 0x48, 0xff, 0x71, 0xfe, 0xe5, 0xfe, 0xf0, 0xfe, 0x62, 0xff, 0x25, 0x00, 0x96, 0x00, 0x7d, 0x01, 0xeb, 0x01, 0x62, 0x02, 0xc7, 0x02, 0x76, 0x02, 0xd1, 0x02, 0xbb, 0x01, 0x09, 0x02, 0x80, 0x00, 0xc3, 0x00, 0x58, 0xff, 0x8f, 0xff, 0xdf, 0xfe, 0x0d, 0xff, 0x3e, 0xff, 0x65, 0xff, 0x2f, 0x00, 0x52, 0x00, 0x5b, 0x01, 0x7c, 0x01, 0x43, 0x02, 0x61, 0x02, 0x68, 0x02, 0x81, 0x02, 0xcb, 0x01, 0xde, 0x01, 0xd0, 0x00, 0xda, 0x00, 0xe4, 0xff, 0xe2, 0xff, 0x69, 0xff, 0x58, 0xff, 0x7f, 0xff, 0x5e, 0xff, 0x06, 0x00, 0xd6, 0xff, 0xc5, 0x00, 0x87, 0x00, 0x66, 0x01, 0x1c, 0x01, 0xa8, 0x01, 0x53, 0x01, 0x8a, 0x01, 0x2c, 0x01, 0x0b, 0x01, 0xa5, 0x00, 0x4f, 0x00, 0xe1, 0xff, 0xbd, 0xff, 0x41, 0xff, 0x80, 0xff, 0xf0, 0xfe, 0x86, 0xff, 0xe0, 0xfe, 0xd7, 0xff, 0x1f, 0xff, 0x4f, 0x00, 0x8d, 0xff, 0xa0, 0x00, 0xdc, 0xff, 0xb5, 0x00, 0xf4, 0xff, 0x93, 0x00, 0xd6, 0xff, 0x3c, 0x00, 0x82, 0xff, 0xd1, 0xff, 0x18, 0xff, 0x7d, 0xff, 0xc3, 0xfe, 0x56, 0xff, 0x9a, 0xfe, 0x67, 0xff, 0xa9, 0xfe, 0x9a, 0xff, 0xda, 0xfe, 0xd9, 0xff, 0x19, 0xff, 0x1d, 0x00, 0x61, 0xff, 0x3e, 0x00, 0x89, 0xff, 0x23, 0x00, 0x75, 0xff, 0xe8, 0xff, 0x43, 0xff, 0xaa, 0xff, 0x0d, 0xff, 0x77, 0xff, 0xe4, 0xfe, 0x70, 0xff, 0xe9, 0xfe, 0x9c, 0xff, 0x23, 0xff, 0xd9, 0xff, 0x72, 0xff, 0x0c, 0x00, 0xbc, 0xff, 0x13, 0x00, 0xde, 0xff, 0xe3, 0xff, 0xce, 0xff, 0x99, 0xff, 0xa4, 0xff, 0x49, 0xff, 0x74, 0xff, 0x14, 0xff, 0x58, 0xff, 0x1f, 0xff, 0x74, 0xff, 0x54, 0xff, 0xb5, 0xff, 0x84, 0xff, 0xef, 0xff, 0xab, 0xff, 0x1e, 0x00, 0xbe, 0xff, 0x38, 0x00, 0xa6, 0xff, 0x26, 0x00, 0x7d, 0xff, 0x04, 0x00, 0x60, 0xff, 0xee, 0xff, 0x4d, 0xff, 0xe1, 0xff, 0x49, 0xff, 0xe0, 0xff, 0x52, 0xff, 0xe7, 0xff, 0x5e, 0xff, 0xec, 0xff, 0x73, 0xff, 0xf7, 0xff, 0x8b, 0xff, 0x06, 0x00, 0xa1, 0xff, 0x16, 0x00, 0xbc, 0xff, 0x2d, 0x00, 0xce, 0xff, 0x3d, 0x00, 0xcd, 0xff, 0x3c, 0x00, 0xcd, 0xff, 0x3a, 0x00, 0xd4, 0xff, 0x3b, 0x00, 0xd7, 0xff, 0x36, 0x00, 0xea, 0xff, 0x40, 0x00, 0x15, 0x00, 0x60, 0x00, 0x35, 0x00, 0x7a, 0x00, 0x3f, 0x00, 0x81, 0x00, 0x2f, 0x00, 0x73, 0x00, 0x01, 0x00, 0x47, 0x00, 0xca, 0xff, 0x0e, 0x00, 0xb4, 0xff, 0xf0, 0xff, 0xe0, 0xff, 0x0d, 0x00, 0x44, 0x00, 0x5e, 0x00, 0xa0, 0x00, 0xa7, 0x00, 0xc6, 0x00, 0xc0, 0x00, 0xbf, 0x00, 0xb2, 0x00, 0x8f, 0x00, 0x82, 0x00, 0x3a, 0x00, 0x2b, 0x00, 0xdb, 0xff, 0xc6, 0xff, 0x91, 0xff, 0x6d, 0xff, 0x7f, 0xff, 0x46, 0xff, 0xcf, 0xff, 0x7b, 0xff, 0x62, 0x00, 0xf4, 0xff, 0xdb, 0x00, 0x58, 0x00, 0xf6, 0x00, 0x64, 0x00, 0xac, 0x00, 0x10, 0x00, 0x24, 0x00, 0x82, 0xff, 0xa7, 0xff, 0xfc, 0xfe, 0x67, 0xff, 0xad, 0xfe, 0x7e, 0xff, 0xae, 0xfe, 0xef, 0xff, 0x06, 0xff, 0x80, 0x00, 0x81, 0xff, 0xdc, 0x00, 0xcf, 0xff, 0xdc, 0x00, 0xcd, 0xff, 0x8c, 0x00, 0x83, 0xff, 0x15, 0x00, 0x18, 0xff, 0xbe, 0xff, 0xce, 0xfe, 0xa9, 0xff, 0xc6, 0xfe, 0xcb, 0xff, 0xf4, 0xfe, 0x0e, 0x00, 0x42, 0xff, 0x54, 0x00, 0x92, 0xff, 0x79, 0x00, 0xc5, 0xff, 0x74, 0x00, 0xd1, 0xff, 0x47, 0x00, 0xbb, 0xff, 0x03, 0x00, 0x93, 0xff, 0xcb, 0xff, 0x77, 0xff, 0xad, 0xff, 0x70, 0xff, 0xa9, 0xff, 0x7c, 0xff, 0xbe, 0xff, 0x9c, 0xff, 0xdd, 0xff, 0xc5, 0xff, 0xf0, 0xff, 0xe1, 0xff, 0xef, 0xff, 0xeb, 0xff, 0xd9, 0xff, 0xe2, 0xff, 0xb0, 0xff, 0xc8, 0xff, 0x88, 0xff, 0xb1, 0xff, 0x72, 0xff, 0xad, 0xff, 0x73, 0xff, 0xc0, 0xff, 0x85, 0xff, 0xe0, 0xff, 0x99, 0xff, 0x01, 0x00, 0xa0, 0xff, 0x13, 0x00, 0xa1, 0xff, 0x1f, 0x00, 0xa0, 0xff, 0x27, 0x00, 0x9a, 0xff, 0x2b, 0x00, 0x9d, 0xff, 0x39, 0x00, 0xa7, 0xff, 0x4e, 0x00, 0xae, 0xff, 0x61, 0x00, 0xae, 0xff, 0x6d, 0x00, 0xac, 0xff, 0x74, 0x00, 0xb2, 0xff, 0x80, 0x00, 0xcb, 0xff, 0x9a, 0x00, 0xee, 0xff, 0xb7, 0x00, 0x07, 0x00, 0xc8, 0x00, 0x11, 0x00, 0xc9, 0x00, 0x0f, 0x00, 0xc2, 0x00, 0x07, 0x00, 0xbe, 0x00, 0x03, 0x00, 0xc3, 0x00, 0x0a, 0x00, 0xd2, 0x00, 0x23, 0x00, 0xef, 0x00, 0x4b, 0x00, 0x12, 0x01, 0x6b, 0x00, 0x25, 0x01, 0x7e, 0x00, 0x27, 0x01, 0x84, 0x00, 0x1e, 0x01, 0x7a, 0x00, 0x0b, 0x01, 0x64, 0x00, 0xf5, 0x00, 0x52, 0x00, 0xe9, 0x00, 0x4c, 0x00, 0xec, 0x00, 0x4c, 0x00, 0xf3, 0x00, 0x54, 0x00, 0xf9, 0x00, 0x5e, 0x00, 0xf8, 0x00, 0x6a, 0x00, 0xf0, 0x00, 0x76, 0x00, 0xe2, 0x00, 0x7c, 0x00, 0xd0, 0x00, 0x7d, 0x00, 0xc2, 0x00, 0x72, 0x00, 0xb2, 0x00, 0x5b, 0x00, 0x9d, 0x00, 0x48, 0x00, 0x8c, 0x00, 0x40, 0x00, 0x7f, 0x00, 0x40, 0x00, 0x72, 0x00, 0x48, 0x00, 0x63, 0x00, 0x58, 0x00, 0x58, 0x00, 0x68, 0x00, 0x4e, 0x00, 0x71, 0x00, 0x45, 0x00, 0x6b, 0x00, 0x38, 0x00, 0x58, 0x00, 0x2b, 0x00, 0x43, 0x00, 0x20, 0x00, 0x33, 0x00, 0x17, 0x00, 0x2d, 0x00, 0x0b, 0x00, 0x37, 0x00, 0x01, 0x00, 0x4e, 0x00, 0xfc, 0xff, 0x6a, 0x00, 0xfb, 0xff, 0x7e, 0x00, 0xfc, 0xff, 0x7c, 0x00, 0xf6, 0xff, 0x62, 0x00, 0xe5, 0xff, 0x3d, 0x00, 0xd2, 0xff, 0x1d, 0x00, 0xc2, 0xff, 0x08, 0x00, 0xb5, 0xff, 0x08, 0x00, 0xae, 0xff, 0x18, 0x00, 0xad, 0xff, 0x2c, 0x00, 0xaf, 0xff, 0x3a, 0x00, 0xaf, 0xff, 0x34, 0x00, 0xa8, 0xff, 0x18, 0x00, 0x99, 0xff, 0xf2, 0xff, 0x8b, 0xff, 0xd0, 0xff, 0x87, 0xff, 0xb8, 0xff, 0x8c, 0xff, 0xb0, 0xff, 0x9d, 0xff, 0xb4, 0xff, 0xb1, 0xff, 0xbb, 0xff, 0xc0, 0xff, 0xc7, 0xff, 0xcb, 0xff, 0xd0, 0xff, 0xd2, 0xff, 0xd0, 0xff, 0xd3, 0xff, 0xc8, 0xff, 0xd4, 0xff, 0xbb, 0xff, 0xd8, 0xff, 0xae, 0xff, 0xe2, 0xff, 0xa8, 0xff, 0xf1, 0xff, 0xac, 0xff, 0x05, 0x00, 0xb6, 0xff, 0x18, 0x00, 0xc3, 0xff, 0x24, 0x00, 0xcf, 0xff, 0x27, 0x00, 0xd5, 0xff, 0x22, 0x00, 0xd6, 0xff, 0x1a, 0x00, 0xd1, 0xff, 0x11, 0x00, 0xc7, 0xff, 0x09, 0x00, 0xbf, 0xff, 0x06, 0x00, 0xbe, 0xff, 0x08, 0x00, 0xc6, 0xff, 0x0d, 0x00, 0xd8, 0xff, 0x14, 0x00, 0xf3, 0xff, 0x1d, 0x00, 0x12, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2a, 0x00, 0x23, 0x00, 0x21, 0x00, 0x0f, 0x00, 0x15, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xf1, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xf2, 0xff, 0x0e, 0x00, 0xf1, 0xff, 0x25, 0x00, 0xf1, 0xff, 0x30, 0x00, 0xeb, 0xff, 0x30, 0x00, 0xe4, 0xff, 0x25, 0x00, 0xde, 0xff, 0x14, 0x00, 0xd8, 0xff, 0x05, 0x00, 0xd6, 0xff, 0xfc, 0xff, 0xd4, 0xff, 0xf7, 0xff, 0xce, 0xff, 0xf4, 0xff, 0xc3, 0xff, 0xf2, 0xff, 0xb6, 0xff, 0xf1, 0xff, 0xab, 0xff, 0xeb, 0xff, 0xa0, 0xff, 0xe1, 0xff, 0x97, 0xff, 0xd6, 0xff, 0x91, 0xff, 0xd0, 0xff, 0x91, 0xff, 0xcd, 0xff, 0x93, 0xff, 0xcd, 0xff, 0x93, 0xff, 0xd0, 0xff, 0x90, 0xff, 0xd1, 0xff, 0x85, 0xff, 0xcf, 0xff, 0x72, 0xff, 0xcc, 0xff, 0x5c, 0xff, 0xc7, 0xff, 0x47, 0xff, 0xbe, 0xff, 0x32, 0xff, 0xb2, 0xff, 0x1f, 0xff, 0xa9, 0xff, 0x11, 0xff, 0xa3, 0xff, 0x06, 0xff, 0xa1, 0xff, 0xf9, 0xfe, 0xa4, 0xff, 0xeb, 0xfe, 0xae, 0xff, 0xe1, 0xfe, 0xbc, 0xff, 0xdc, 0xfe, 0xc8, 0xff, 0xda, 0xfe, 0xcd, 0xff, 0xdc, 0xfe, 0xc9, 0xff, 0xe1, 0xfe, 0xbe, 0xff, 0xe5, 0xfe, 0xb1, 0xff, 0xe8, 0xfe, 0xa6, 0xff, 0xe8, 0xfe, 0x9f, 0xff, 0xe3, 0xfe, 0xa3, 0xff, 0xe1, 0xfe, 0xae, 0xff, 0xe3, 0xfe, 0xba, 0xff, 0xec, 0xfe, 0xbd, 0xff, 0xf3, 0xfe, 0xb4, 0xff, 0xfa, 0xfe, 0xa5, 0xff, 0x06, 0xff, 0x93, 0xff, 0x12, 0xff, 0x85, 0xff, 0x21, 0xff, 0x81, 0xff, 0x30, 0xff, 0x89, 0xff, 0x40, 0xff, 0x9a, 0xff, 0x4e, 0xff, 0xad, 0xff, 0x5a, 0xff, 0xbe, 0xff, 0x67, 0xff, 0xc5, 0xff, 0x77, 0xff, 0xc5, 0xff, 0x8a, 0xff, 0xc3, 0xff, 0xa3, 0xff, 0xc5, 0xff, 0xc0, 0xff, 0xcd, 0xff, 0xdd, 0xff, 0xdb, 0xff, 0xf8, 0xff, 0xed, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x22, 0x00, 0x0e, 0x00, 0x31, 0x00, 0x15, 0x00, 0x38, 0x00, 0x13, 0x00, 0x3a, 0x00, 0x0a, 0x00, 0x3c, 0x00, 0xff, 0xff, 0x44, 0x00, 0xf8, 0xff, 0x57, 0x00, 0xf7, 0xff, 0x6f, 0x00, 0xfc, 0xff, 0x85, 0x00, 0x07, 0x00, 0x97, 0x00, 0x17, 0x00, 0xa6, 0x00, 0x23, 0x00, 0xae, 0x00, 0x28, 0x00, 0xb1, 0x00, 0x2b, 0x00, 0xba, 0x00, 0x2f, 0x00, 0xce, 0x00, 0x35, 0x00, 0xed, 0x00, 0x3d, 0x00, 0x11, 0x01, 0x46, 0x00, 0x33, 0x01, 0x4f, 0x00, 0x48, 0x01, 0x52, 0x00, 0x4a, 0x01, 0x4f, 0x00, 0x3d, 0x01, 0x4e, 0x00, 0x31, 0x01, 0x4e, 0x00, 0x2b, 0x01, 0x4b, 0x00, 0x2a, 0x01, 0x49, 0x00, 0x2e, 0x01, 0x47, 0x00, 0x33, 0x01, 0x47, 0x00, 0x33, 0x01, 0x49, 0x00, 0x2c, 0x01, 0x49, 0x00, 0x1a, 0x01, 0x48, 0x00, 0x03, 0x01, 0x43, 0x00, 0xeb, 0x00, 0x3b, 0x00, 0xd5, 0x00, 0x36, 0x00, 0xc7, 0x00, 0x33, 0x00, 0xbc, 0x00, 0x35, 0x00, 0xb3, 0x00, 0x3b, 0x00, 0xa9, 0x00, 0x44, 0x00, 0x9b, 0x00, 0x4d, 0x00, 0x89, 0x00, 0x53, 0x00, 0x78, 0x00, 0x55, 0x00, 0x68, 0x00, 0x51, 0x00, 0x5c, 0x00, 0x49, 0x00, 0x55, 0x00, 0x3d, 0x00, 0x4e, 0x00, 0x2d, 0x00, 0x3e, 0x00, 0x1c, 0x00, 0x26, 0x00, 0x15, 0x00, 0x0e, 0x00, 0x18, 0x00, 0xfa, 0xff, 0x1d, 0x00, 0xea, 0xff, 0x1d, 0x00, 0xdb, 0xff, 0x19, 0x00, 0xd2, 0xff, 0x14, 0x00, 0xcd, 0xff, 0x0b, 0x00, 0xc5, 0xff, 0xfd, 0xff, 0xb5, 0xff, 0xf4, 0xff, 0xa5, 0xff, 0xf6, 0xff, 0x9b, 0xff, 0x00, 0x00, 0x95, 0xff, 0x12, 0x00, 0x98, 0xff, 0x28, 0x00, 0xa3, 0xff, 0x3d, 0x00, 0xb6, 0xff, 0x46, 0x00, 0xc7, 0xff, 0x3f, 0x00, 0xce, 0xff, 0x30, 0x00, 0xcb, 0xff, 0x20, 0x00, 0xc1, 0xff, 0x15, 0x00, 0xb4, 0xff, 0x14, 0x00, 0xac, 0xff, 0x1b, 0x00, 0xa9, 0xff, 0x26, 0x00, 0xab, 0xff, 0x30, 0x00, 0xb3, 0xff, 0x37, 0x00, 0xc4, 0xff, 0x3a, 0x00, 0xd9, 0xff, 0x36, 0x00, 0xeb, 0xff, 0x2b, 0x00, 0xf4, 0xff, 0x20, 0x00, 0xf4, 0xff, 0x18, 0x00, 0xf0, 0xff, 0x17, 0x00, 0xf0, 0xff, 0x1e, 0x00, 0xf9, 0xff, 0x2a, 0x00, 0x0a, 0x00, 0x37, 0x00, 0x21, 0x00, 0x41, 0x00, 0x3a, 0x00, 0x46, 0x00, 0x52, 0x00, 0x42, 0x00, 0x66, 0x00, 0x39, 0x00, 0x72, 0x00, 0x31, 0x00, 0x7b, 0x00, 0x2c, 0x00, 0x82, 0x00, 0x28, 0x00, 0x87, 0x00, 0x21, 0x00, 0x89, 0x00, 0x19, 0x00, 0x8e, 0x00, 0x0e, 0x00, 0x93, 0x00, 0x05, 0x00, 0x98, 0x00, 0x00, 0x00, 0x9c, 0x00, 0xfc, 0xff, 0x9c, 0x00, 0xf8, 0xff, 0x98, 0x00, 0xf0, 0xff, 0x8f, 0x00, 0xe7, 0xff, 0x85, 0x00, 0xdc, 0xff, 0x7e, 0x00, 0xd0, 0xff, 0x78, 0x00, 0xc7, 0xff, 0x79, 0x00, 0xc4, 0xff, 0x80, 0x00, 0xc7, 0xff, 0x87, 0x00, 0xce, 0xff, 0x8a, 0x00, 0xdb, 0xff, 0x89, 0x00, 0xe8, 0xff, 0x86, 0x00, 0xf2, 0xff, 0x82, 0x00, 0xf8, 0xff, 0x7f, 0x00, 0xfd, 0xff, 0x7e, 0x00, 0x04, 0x00, 0x7d, 0x00, 0x0e, 0x00, 0x79, 0x00, 0x19, 0x00, 0x73, 0x00, 0x24, 0x00, 0x68, 0x00, 0x2d, 0x00, 0x58, 0x00, 0x2f, 0x00, 0x41, 0x00, 0x2c, 0x00, 0x28, 0x00, 0x25, 0x00, 0x11, 0x00, 0x1d, 0x00, 0xfb, 0xff, 0x18, 0x00, 0xe7, 0xff, 0x1c, 0x00, 0xd6, 0xff, 0x26, 0x00, 0xc8, 0xff, 0x2e, 0x00, 0xb7, 0xff, 0x30, 0x00, 0xa3, 0xff, 0x27, 0x00, 0x8c, 0xff, 0x15, 0x00, 0x76, 0xff, 0xfe, 0xff, 0x65, 0xff, 0xe6, 0xff, 0x5a, 0xff, 0xd4, 0xff, 0x56, 0xff, 0xc9, 0xff, 0x54, 0xff, 0xc7, 0xff, 0x50, 0xff, 0xca, 0xff, 0x4a, 0xff, 0xcb, 0xff, 0x40, 0xff, 0xc6, 0xff, 0x34, 0xff, 0xbc, 0xff, 0x2b, 0xff, 0xac, 0xff, 0x25, 0xff, 0x9c, 0xff, 0x22, 0xff, 0x94, 0xff, 0x27, 0xff, 0x97, 0xff, 0x32, 0xff, 0x9d, 0xff, 0x3b, 0xff, 0x9f, 0xff, 0x3d, 0xff, 0x9d, 0xff, 0x3c, 0xff, 0x98, 0xff, 0x37, 0xff, 0x91, 0xff, 0x30, 0xff, 0x8d, 0xff, 0x2f, 0xff, 0x94, 0xff, 0x36, 0xff, 0x9f, 0xff, 0x43, 0xff, 0xa9, 0xff, 0x50, 0xff, 0xae, 0xff, 0x5a, 0xff, 0xaf, 0xff, 0x66, 0xff, 0xaf, 0xff, 0x75, 0xff, 0xad, 0xff, 0x87, 0xff, 0xad, 0xff, 0x9b, 0xff, 0xb2, 0xff, 0xb0, 0xff, 0xbf, 0xff, 0xc5, 0xff, 0xd1, 0xff, 0xd7, 0xff, 0xe5, 0xff, 0xe8, 0xff, 0xf6, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0x0c, 0x00, 0xff, 0xff, 0x23, 0x00, 0xfe, 0xff, 0x3f, 0x00, 0xfd, 0xff, 0x5b, 0x00, 0x02, 0x00, 0x74, 0x00, 0x0d, 0x00, 0x86, 0x00, 0x1b, 0x00, 0x8f, 0x00, 0x27, 0x00, 0x92, 0x00, 0x2c, 0x00, 0x92, 0x00, 0x2a, 0x00, 0x96, 0x00, 0x20, 0x00, 0xa1, 0x00, 0x14, 0x00, 0xb5, 0x00, 0x0b, 0x00, 0xcf, 0x00, 0x07, 0x00, 0xe4, 0x00, 0x07, 0x00, 0xec, 0x00, 0x0c, 0x00, 0xe4, 0x00, 0x13, 0x00, 0xd3, 0x00, 0x19, 0x00, 0xbe, 0x00, 0x19, 0x00, 0xab, 0x00, 0x16, 0x00, 0xa1, 0x00, 0x0e, 0x00, 0x9f, 0x00, 0x04, 0x00, 0xa3, 0x00, 0xfd, 0xff, 0xaa, 0x00, 0xfc, 0xff, 0xaf, 0x00, 0x00, 0x00, 0xad, 0x00, 0x04, 0x00, 0x9f, 0x00, 0x06, 0x00, 0x88, 0x00, 0x07, 0x00, 0x71, 0x00, 0x05, 0x00, 0x5e, 0x00, 0x01, 0x00, 0x51, 0x00, 0xff, 0xff, 0x4c, 0x00, 0x02, 0x00, 0x4f, 0x00, 0x0a, 0x00, 0x56, 0x00, 0x15, 0x00, 0x5b, 0x00, 0x20, 0x00, 0x5d, 0x00, 0x26, 0x00, 0x56, 0x00, 0x24, 0x00, 0x46, 0x00, 0x1e, 0x00, 0x2e, 0x00, 0x19, 0x00, 0x17, 0x00, 0x19, 0x00, 0x04, 0x00, 0x1f, 0x00, 0xf5, 0xff, 0x2c, 0x00, 0xee, 0xff, 0x3a, 0x00, 0xeb, 0xff, 0x46, 0x00, 0xe7, 0xff, 0x4e, 0x00, 0xe1, 0xff, 0x50, 0x00, 0xd7, 0xff, 0x4d, 0x00, 0xc7, 0xff, 0x46, 0x00, 0xaf, 0xff, 0x41, 0x00, 0x98, 0xff, 0x44, 0x00, 0x89, 0xff, 0x4c, 0x00, 0x83, 0xff, 0x53, 0x00, 0x81, 0xff, 0x57, 0x00, 0x84, 0xff, 0x57, 0x00, 0x87, 0xff, 0x50, 0x00, 0x81, 0xff, 0x46, 0x00, 0x75, 0xff, 0x3d, 0x00, 0x64, 0xff, 0x38, 0x00, 0x55, 0xff, 0x34, 0x00, 0x4c, 0xff, 0x31, 0x00, 0x4a, 0xff, 0x2e, 0x00, 0x50, 0xff, 0x29, 0x00, 0x58, 0xff, 0x25, 0x00, 0x60, 0xff, 0x21, 0x00, 0x67, 0xff, 0x1f, 0x00, 0x6c, 0xff, 0x1b, 0x00, 0x6d, 0xff, 0x1a, 0x00, 0x6f, 0xff, 0x1c, 0x00, 0x75, 0xff, 0x1f, 0x00, 0x7e, 0xff, 0x1f, 0x00, 0x88, 0xff, 0x1b, 0x00, 0x92, 0xff, 0x16, 0x00, 0x9c, 0xff, 0x11, 0x00, 0xa4, 0xff, 0x0c, 0x00, 0xa8, 0xff, 0x07, 0x00, 0xa9, 0xff, 0x03, 0x00, 0xaa, 0xff, 0xfb, 0xff, 0xaa, 0xff, 0xf0, 0xff, 0xab, 0xff, 0xe6, 0xff, 0xae, 0xff, 0xdc, 0xff, 0xb1, 0xff, 0xd5, 0xff, 0xb7, 0xff, 0xd5, 0xff, 0xc4, 0xff, 0xdc, 0xff, 0xd6, 0xff, 0xe3, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xf0, 0xff, 0xe3, 0xff, 0xf6, 0xff, 0xdb, 0xff, 0xfb, 0xff, 0xd0, 0xff, 0x01, 0x00, 0xc5, 0xff, 0x0c, 0x00, 0xbb, 0xff, 0x19, 0x00, 0xb3, 0xff, 0x25, 0x00, 0xaf, 0xff, 0x2f, 0x00, 0xad, 0xff, 0x33, 0x00, 0xad, 0xff, 0x32, 0x00, 0xab, 0xff, 0x29, 0x00, 0xa8, 0xff, 0x23, 0x00, 0xa9, 0xff, 0x28, 0x00, 0xad, 0xff, 0x37, 0x00, 0xae, 0xff, 0x4a, 0x00, 0xad, 0xff, 0x5b, 0x00, 0xae, 0xff, 0x67, 0x00, 0xac, 0xff, 0x65, 0x00, 0xaa, 0xff, 0x58, 0x00, 0xa7, 0xff, 0x44, 0x00, 0xa3, 0xff, 0x30, 0x00, 0xa1, 0xff, 0x25, 0x00, 0xa2, 0xff, 0x25, 0x00, 0xa5, 0xff, 0x2d, 0x00, 0xaa, 0xff, 0x38, 0x00, 0xaf, 0xff, 0x3d, 0x00, 0xb1, 0xff, 0x37, 0x00, 0xb0, 0xff, 0x28, 0x00, 0xac, 0xff, 0x0f, 0x00, 0xa8, 0xff, 0xf8, 0xff, 0xa9, 0xff, 0xea, 0xff, 0xae, 0xff, 0xe2, 0xff, 0xb4, 0xff, 0xdf, 0xff, 0xbd, 0xff, 0xde, 0xff, 0xc8, 0xff, 0xde, 0xff, 0xd1, 0xff, 0xdb, 0xff, 0xd7, 0xff, 0xd6, 0xff, 0xda, 0xff, 0xcf, 0xff, 0xdc, 0xff, 0xc7, 0xff, 0xdd, 0xff, 0xbe, 0xff, 0xde, 0xff, 0xb3, 0xff, 0xe2, 0xff, 0xaa, 0xff, 0xe8, 0xff, 0xa5, 0xff, 0xf0, 0xff, 0xa2, 0xff, 0xf9, 0xff, 0xa6, 0xff, 0x05, 0x00, 0xb0, 0xff, 0x14, 0x00, 0xbb, 0xff, 0x23, 0x00, 0xc2, 0xff, 0x2f, 0x00, 0xc1, 0xff, 0x37, 0x00, 0xb9, 0xff, 0x37, 0x00, 0xab, 0xff, 0x34, 0x00, 0x9e, 0xff, 0x33, 0x00, 0x99, 0xff, 0x34, 0x00, 0x9c, 0xff, 0x3b, 0x00, 0xa6, 0xff, 0x45, 0x00, 0xb4, 0xff, 0x51, 0x00, 0xc0, 0xff, 0x58, 0x00, 0xc3, 0xff, 0x59, 0x00, 0xbf, 0xff, 0x53, 0x00, 0xba, 0xff, 0x40, 0x00, 0xb4, 0xff, 0x29, 0x00, 0xb3, 0xff, 0x18, 0x00, 0xbd, 0xff, 0x15, 0x00, 0xd4, 0xff, 0x23, 0x00, 0xf1, 0xff, 0x37, 0x00, 0x08, 0x00, 0x45, 0x00, 0x12, 0x00, 0x44, 0x00, 0x11, 0x00, 0x35, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x07, 0x00, 0x08, 0x00, 0x0a, 0x00, 0xf6, 0xff, 0x11, 0x00, 0xf2, 0xff, 0x1d, 0x00, 0xfd, 0xff, 0x2b, 0x00, 0x12, 0x00, 0x3a, 0x00, 0x28, 0x00, 0x46, 0x00, 0x35, 0x00, 0x4e, 0x00, 0x34, 0x00, 0x51, 0x00, 0x25, 0x00, 0x51, 0x00, 0x11, 0x00, 0x52, 0x00, 0x01, 0x00, 0x56, 0x00, 0xf7, 0xff, 0x5c, 0x00, 0xf6, 0xff, 0x64, 0x00, 0xfd, 0xff, 0x6d, 0x00, 0x0a, 0x00, 0x78, 0x00, 0x18, 0x00, 0x84, 0x00, 0x22, 0x00, 0x8b, 0x00, 0x21, 0x00, 0x8a, 0x00, 0x13, 0x00, 0x81, 0x00, 0xfe, 0xff, 0x76, 0x00, 0xeb, 0xff, 0x72, 0x00, 0xe0, 0xff, 0x75, 0x00, 0xdb, 0xff, 0x79, 0x00, 0xde, 0xff, 0x7d, 0x00, 0xe6, 0xff, 0x7c, 0x00, 0xef, 0xff, 0x76, 0x00, 0xf7, 0xff, 0x68, 0x00, 0xfe, 0xff, 0x56, 0x00, 0x04, 0x00, 0x47, 0x00, 0x06, 0x00, 0x3f, 0x00, 0x03, 0x00, 0x3d, 0x00, 0xfc, 0xff, 0x3e, 0x00, 0xf4, 0xff, 0x3d, 0x00, 0xeb, 0xff, 0x31, 0x00, 0xe7, 0xff, 0x1e, 0x00, 0xe7, 0xff, 0x06, 0x00, 0xea, 0xff, 0xef, 0xff, 0xf3, 0xff, 0xe4, 0xff, 0xff, 0xff, 0xe6, 0xff, 0x09, 0x00, 0xf2, 0xff, 0x0b, 0x00, 0xff, 0xff, 0x0a, 0x00, 0x09, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0xfb, 0xff, 0x0c, 0x00, 0xf4, 0xff, 0x17, 0x00, 0xf5, 0xff, 0x21, 0x00, 0xff, 0xff, 0x29, 0x00, 0x11, 0x00, 0x2c, 0x00, 0x23, 0x00, 0x23, 0x00, 0x2c, 0x00, 0x13, 0x00, 0x2b, 0x00, 0x01, 0x00, 0x21, 0x00, 0xf3, 0xff, 0x13, 0x00, 0xeb, 0xff, 0x06, 0x00, 0xeb, 0xff, 0xfd, 0xff, 0xf2, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xf1, 0xff, 0x00, 0x00, 0xde, 0xff, 0xfd, 0xff, 0xca, 0xff, 0xf7, 0xff, 0xbb, 0xff, 0xee, 0xff, 0xb5, 0xff, 0xe3, 0xff, 0xb7, 0xff, 0xd4, 0xff, 0xbf, 0xff, 0xc5, 0xff, 0xce, 0xff, 0xbd, 0xff, 0xdc, 0xff, 0xc1, 0xff, 0xe2, 0xff, 0xd0, 0xff, 0xe2, 0xff, 0xe6, 0xff, 0xdf, 0xff, 0xfd, 0xff, 0xda, 0xff, 0x09, 0x00, 0xd7, 0xff, 0x07, 0x00, 0xd8, 0xff, 0xf8, 0xff, 0xdf, 0xff, 0xea, 0xff, 0xec, 0xff, 0xe5, 0xff, 0xfc, 0xff, 0xf2, 0xff, 0x0c, 0x00, 0x11, 0x00, 0x17, 0x00, 0x36, 0x00, 0x1b, 0x00, 0x55, 0x00, 0x1c, 0x00, 0x65, 0x00, 0x1a, 0x00, 0x61, 0x00, 0x15, 0x00, 0x4d, 0x00, 0x11, 0x00, 0x35, 0x00, 0x10, 0x00, 0x27, 0x00, 0x10, 0x00, 0x25, 0x00, 0x0f, 0x00, 0x2e, 0x00, 0x0c, 0x00, 0x3e, 0x00, 0x0c, 0x00, 0x4b, 0x00, 0x0f, 0x00, 0x4f, 0x00, 0x14, 0x00, 0x47, 0x00, 0x1d, 0x00, 0x38, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x19, 0x00, 0x22, 0x00, 0x0c, 0x00, 0x17, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x11, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x10, 0x00, 0x28, 0x00, 0x0c, 0x00, 0x34, 0x00, 0x06, 0x00, 0x3d, 0x00, 0x03, 0x00, 0x42, 0x00, 0x01, 0x00, 0x3f, 0x00, 0xff, 0xff, 0x3b, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x05, 0x00, 0x3d, 0x00, 0x0a, 0x00, 0x42, 0x00, 0x0e, 0x00, 0x4e, 0x00, 0x14, 0x00, 0x5b, 0x00, 0x19, 0x00, 0x65, 0x00, 0x19, 0x00, 0x6a, 0x00, 0x15, 0x00, 0x67, 0x00, 0x0c, 0x00, 0x5f, 0x00, 0x02, 0x00, 0x51, 0x00, 0xf6, 0xff, 0x43, 0x00, 0xec, 0xff, 0x3b, 0x00, 0xe4, 0xff, 0x39, 0x00, 0xd9, 0xff, 0x3c, 0x00, 0xc9, 0xff, 0x44, 0x00, 0xb4, 0xff, 0x4b, 0x00, 0x9c, 0xff, 0x4d, 0x00, 0x85, 0xff, 0x4d, 0x00, 0x75, 0xff, 0x4b, 0x00, 0x6f, 0xff, 0x46, 0x00, 0x6e, 0xff, 0x3e, 0x00, 0x6f, 0xff, 0x35, 0x00, 0x6e, 0xff, 0x2f, 0x00, 0x6a, 0xff, 0x2e, 0x00, 0x61, 0xff, 0x35, 0x00, 0x59, 0xff, 0x44, 0x00, 0x57, 0xff, 0x56, 0x00, 0x5d, 0xff, 0x60, 0x00, 0x69, 0xff, 0x5e, 0x00, 0x78, 0xff, 0x4f, 0x00, 0x87, 0xff, 0x37, 0x00, 0x8e, 0xff, 0x1e, 0x00, 0x8d, 0xff, 0x09, 0x00, 0x88, 0xff, 0x01, 0x00, 0x85, 0xff, 0x00, 0x00, 0x85, 0xff, 0x04, 0x00, 0x8e, 0xff, 0x0c, 0x00, 0xa2, 0xff, 0x10, 0x00, 0xba, 0xff, 0x0b, 0x00, 0xd0, 0xff, 0xfe, 0xff, 0xde, 0xff, 0xec, 0xff, 0xe2, 0xff, 0xda, 0xff, 0xdd, 0xff, 0xcd, 0xff, 0xd3, 0xff, 0xc9, 0xff, 0xc8, 0xff, 0xce, 0xff, 0xc1, 0xff, 0xd8, 0xff, 0xc5, 0xff, 0xe3, 0xff, 0xd3, 0xff, 0xeb, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0xf9, 0xff, 0xdd, 0xff, 0x02, 0x00, 0xcf, 0xff, 0x04, 0x00, 0xc4, 0xff, 0x00, 0x00, 0xbf, 0xff, 0xf9, 0xff, 0xc0, 0xff, 0xf1, 0xff, 0xc7, 0xff, 0xef, 0xff, 0xd1, 0xff, 0xf6, 0xff, 0xd9, 0xff, 0x05, 0x00, 0xdd, 0xff, 0x1c, 0x00, 0xe0, 0xff, 0x37, 0x00, 0xdd, 0xff, 0x4f, 0x00, 0xd7, 0xff, 0x5e, 0x00, 0xd1, 0xff, 0x65, 0x00, 0xcf, 0xff, 0x67, 0x00, 0xcf, 0xff, 0x66, 0x00, 0xd2, 0xff, 0x66, 0x00, 0xda, 0xff, 0x6d, 0x00, 0xe5, 0xff, 0x7e, 0x00, 0xee, 0xff, 0x95, 0x00, 0xf3, 0xff, 0xac, 0x00, 0xf2, 0xff, 0xc0, 0x00, 0xeb, 0xff, 0xc8, 0x00, 0xe2, 0xff, 0xc6, 0x00, 0xdc, 0xff, 0xbd, 0x00, 0xdb, 0xff, 0xae, 0x00, 0xdd, 0xff, 0xa1, 0x00, 0xe4, 0xff, 0x9b, 0x00, 0xef, 0xff, 0xa2, 0x00, 0xfc, 0xff, 0xb1, 0x00, 0x04, 0x00, 0xbf, 0x00, 0x06, 0x00, 0xc3, 0x00, 0x04, 0x00, 0xba, 0x00, 0xfb, 0xff, 0xa0, 0x00, 0xf0, 0xff, 0x7c, 0x00, 0xed, 0xff, 0x5d, 0x00, 0xf2, 0xff, 0x4b, 0x00, 0x01, 0x00, 0x4c, 0x00, 0x14, 0x00, 0x5b, 0x00, 0x25, 0x00, 0x6f, 0x00, 0x2d, 0x00, 0x7c, 0x00, 0x2b, 0x00, 0x7b, 0x00, 0x25, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x55, 0x00, 0x1f, 0x00, 0x39, 0x00, 0x25, 0x00, 0x25, 0x00, 0x31, 0x00, 0x1d, 0x00, 0x3d, 0x00, 0x22, 0x00, 0x45, 0x00, 0x2c, 0x00, 0x45, 0x00, 0x35, 0x00, 0x3e, 0x00, 0x38, 0x00, 0x32, 0x00, 0x33, 0x00, 0x26, 0x00, 0x28, 0x00, 0x20, 0x00, 0x1b, 0x00, 0x21, 0x00, 0x0e, 0x00, 0x23, 0x00, 0x00, 0x00, 0x25, 0x00, 0xf4, 0xff, 0x21, 0x00, 0xe8, 0xff, 0x13, 0x00, 0xdb, 0xff, 0x00, 0x00, 0xce, 0xff, 0xed, 0xff, 0xc4, 0xff, 0xe0, 0xff, 0xbd, 0xff, 0xda, 0xff, 0xba, 0xff, 0xda, 0xff, 0xba, 0xff, 0xdd, 0xff, 0xbb, 0xff, 0xe1, 0xff, 0xbf, 0xff, 0xe1, 0xff, 0xc4, 0xff, 0xda, 0xff, 0xc6, 0xff, 0xce, 0xff, 0xc5, 0xff, 0xbe, 0xff, 0xc3, 0xff, 0xb1, 0xff, 0xc3, 0xff, 0xaa, 0xff, 0xc5, 0xff, 0xac, 0xff, 0xc9, 0xff, 0xb3, 0xff, 0xcf, 0xff, 0xbb, 0xff, 0xd5, 0xff, 0xbf, 0xff, 0xdb, 0xff, 0xbd, 0xff, 0xe0, 0xff, 0xb5, 0xff, 0xe1, 0xff, 0xad, 0xff, 0xe1, 0xff, 0xa9, 0xff, 0xe2, 0xff, 0xac, 0xff, 0xe2, 0xff, 0xb5, 0xff, 0xe6, 0xff, 0xc3, 0xff, 0xed, 0xff, 0xd2, 0xff, 0xf8, 0xff, 0xdc, 0xff, 0x07, 0x00, 0xe3, 0xff, 0x17, 0x00, 0xe5, 0xff, 0x26, 0x00, 0xe0, 0xff, 0x2c, 0x00, 0xd7, 0xff, 0x28, 0x00, 0xcd, 0xff, 0x1f, 0x00, 0xc8, 0xff, 0x19, 0x00, 0xca, 0xff, 0x1b, 0x00, 0xd0, 0xff, 0x24, 0x00, 0xd5, 0xff, 0x31, 0x00, 0xd5, 0xff, 0x3b, 0x00, 0xd0, 0xff, 0x40, 0x00, 0xc7, 0xff, 0x3f, 0x00, 0xbd, 0xff, 0x39, 0x00, 0xb4, 0xff, 0x2f, 0x00, 0xb0, 0xff, 0x28, 0x00, 0xb6, 0xff, 0x29, 0x00, 0xc3, 0xff, 0x2f, 0x00, 0xd0, 0xff, 0x37, 0x00, 0xdc, 0xff, 0x3d, 0x00, 0xe5, 0xff, 0x3e, 0x00, 0xea, 0xff, 0x38, 0x00, 0xe7, 0xff, 0x2b, 0x00, 0xe0, 0xff, 0x18, 0x00, 0xd9, 0xff, 0x05, 0x00, 0xd6, 0xff, 0xf5, 0xff, 0xd7, 0xff, 0xe9, 0xff, 0xde, 0xff, 0xdf, 0xff, 0xe9, 0xff, 0xd6, 0xff, 0xf5, 0xff, 0xce, 0xff, 0xff, 0xff, 0xc6, 0xff, 0x05, 0x00, 0xbe, 0xff, 0x05, 0x00, 0xb6, 0xff, 0xfe, 0xff, 0xaa, 0xff, 0xf2, 0xff, 0x99, 0xff, 0xe6, 0xff, 0x83, 0xff, 0xe0, 0xff, 0x6f, 0xff, 0xe1, 0xff, 0x5e, 0xff, 0xec, 0xff, 0x55, 0xff, 0xfd, 0xff, 0x55, 0xff, 0x0f, 0x00, 0x5c, 0xff, 0x19, 0x00, 0x63, 0xff, 0x18, 0x00, 0x66, 0xff, 0x0f, 0x00, 0x66, 0xff, 0xff, 0xff, 0x61, 0xff, 0xed, 0xff, 0x5b, 0xff, 0xe0, 0xff, 0x56, 0xff, 0xde, 0xff, 0x59, 0xff, 0xe9, 0xff, 0x65, 0xff, 0xfa, 0xff, 0x72, 0xff, 0x07, 0x00, 0x7b, 0xff, 0x0a, 0x00, 0x7f, 0xff, 0x01, 0x00, 0x7b, 0xff, 0xf0, 0xff, 0x76, 0xff, 0xe0, 0xff, 0x75, 0xff, 0xd4, 0xff, 0x78, 0xff, 0xcf, 0xff, 0x7c, 0xff, 0xd2, 0xff, 0x81, 0xff, 0xdd, 0xff, 0x85, 0xff, 0xee, 0xff, 0x89, 0xff, 0xfd, 0xff, 0x8c, 0xff, 0x06, 0x00, 0x8f, 0xff, 0x05, 0x00, 0x8e, 0xff, 0xfe, 0xff, 0x8a, 0xff, 0xf1, 0xff, 0x82, 0xff, 0xe3, 0xff, 0x79, 0xff, 0xdb, 0xff, 0x75, 0xff, 0xd9, 0xff, 0x78, 0xff, 0xdf, 0xff, 0x85, 0xff, 0xeb, 0xff, 0x9c, 0xff, 0xf8, 0xff, 0xb6, 0xff, 0x00, 0x00, 0xca, 0xff, 0xfd, 0xff, 0xd3, 0xff, 0xf1, 0xff, 0xd2, 0xff, 0xe1, 0xff, 0xcc, 0xff, 0xd3, 0xff, 0xca, 0xff, 0xca, 0xff, 0xcf, 0xff, 0xcd, 0xff, 0xe2, 0xff, 0xdb, 0xff, 0x01, 0x00, 0xef, 0xff, 0x24, 0x00, 0x00, 0x00, 0x41, 0x00, 0x0c, 0x00, 0x51, 0x00, 0x12, 0x00, 0x56, 0x00, 0x12, 0x00, 0x51, 0x00, 0x10, 0x00, 0x4a, 0x00, 0x12, 0x00, 0x47, 0x00, 0x19, 0x00, 0x4e, 0x00, 0x25, 0x00, 0x5c, 0x00, 0x36, 0x00, 0x6f, 0x00, 0x4a, 0x00, 0x82, 0x00, 0x5c, 0x00, 0x8f, 0x00, 0x6b, 0x00, 0x94, 0x00, 0x73, 0x00, 0x92, 0x00, 0x77, 0x00, 0x8d, 0x00, 0x79, 0x00, 0x89, 0x00, 0x7c, 0x00, 0x87, 0x00, 0x81, 0x00, 0x88, 0x00, 0x85, 0x00, 0x89, 0x00, 0x88, 0x00, 0x87, 0x00, 0x88, 0x00, 0x81, 0x00, 0x85, 0x00, 0x77, 0x00, 0x7f, 0x00, 0x6a, 0x00, 0x78, 0x00, 0x5d, 0x00, 0x6d, 0x00, 0x4f, 0x00, 0x62, 0x00, 0x43, 0x00, 0x58, 0x00, 0x39, 0x00, 0x4e, 0x00, 0x33, 0x00, 0x43, 0x00, 0x2e, 0x00, 0x39, 0x00, 0x2d, 0x00, 0x31, 0x00, 0x2e, 0x00, 0x28, 0x00, 0x2b, 0x00, 0x21, 0x00, 0x23, 0x00, 0x1c, 0x00, 0x17, 0x00, 0x19, 0x00, 0x08, 0x00, 0x18, 0x00, 0xfd, 0xff, 0x18, 0x00, 0xf7, 0xff, 0x17, 0x00, 0xf9, 0xff, 0x10, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfa, 0xff, 0xef, 0xff, 0xef, 0xff, 0xdf, 0xff, 0xdf, 0xff, 0xd6, 0xff, 0xcc, 0xff, 0xd2, 0xff, 0xbc, 0xff, 0xd5, 0xff, 0xb2, 0xff, 0xdd, 0xff, 0xb2, 0xff, 0xe7, 0xff, 0xb9, 0xff, 0xea, 0xff, 0xbd, 0xff, 0xe5, 0xff, 0xba, 0xff, 0xd8, 0xff, 0xaf, 0xff, 0xcb, 0xff, 0xa1, 0xff, 0xbf, 0xff, 0x93, 0xff, 0xb6, 0xff, 0x8b, 0xff, 0xb1, 0xff, 0x8c, 0xff, 0xb2, 0xff, 0x94, 0xff, 0xb5, 0xff, 0xa1, 0xff, 0xba, 0xff, 0xad, 0xff, 0xbd, 0xff, 0xb5, 0xff, 0xbe, 0xff, 0xb8, 0xff, 0xbc, 0xff, 0xb6, 0xff, 0xba, 0xff, 0xb2, 0xff, 0xb9, 0xff, 0xb2, 0xff, 0xb9, 0xff, 0xb4, 0xff, 0xbb, 0xff, 0xba, 0xff, 0xbd, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0xc8, 0xff, 0xc7, 0xff, 0xd0, 0xff, 0xce, 0xff, 0xda, 0xff, 0xd4, 0xff, 0xe3, 0xff, 0xda, 0xff, 0xec, 0xff, 0xdd, 0xff, 0xf0, 0xff, 0xde, 0xff, 0xf1, 0xff, 0xde, 0xff, 0xee, 0xff, 0xdf, 0xff, 0xeb, 0xff, 0xe2, 0xff, 0xed, 0xff, 0xed, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0x12, 0x00, 0x10, 0x00, 0x2e, 0x00, 0x1e, 0x00, 0x45, 0x00, 0x28, 0x00, 0x52, 0x00, 0x31, 0x00, 0x56, 0x00, 0x38, 0x00, 0x51, 0x00, 0x3f, 0x00, 0x4b, 0x00, 0x48, 0x00, 0x4c, 0x00, 0x55, 0x00, 0x57, 0x00, 0x64, 0x00, 0x6b, 0x00, 0x73, 0x00, 0x7f, 0x00, 0x81, 0x00, 0x90, 0x00, 0x8b, 0x00, 0x96, 0x00, 0x8e, 0x00, 0x91, 0x00, 0x88, 0x00, 0x81, 0x00, 0x7e, 0x00, 0x6f, 0x00, 0x77, 0x00, 0x64, 0x00, 0x72, 0x00, 0x61, 0x00, 0x71, 0x00, 0x67, 0x00, 0x74, 0x00, 0x70, 0x00, 0x7a, 0x00, 0x78, 0x00, 0x81, 0x00, 0x7a, 0x00, 0x85, 0x00, 0x74, 0x00, 0x83, 0x00, 0x65, 0x00, 0x78, 0x00, 0x52, 0x00, 0x67, 0x00, 0x40, 0x00, 0x56, 0x00, 0x34, 0x00, 0x48, 0x00, 0x32, 0x00, 0x3d, 0x00, 0x35, 0x00, 0x37, 0x00, 0x3b, 0x00, 0x33, 0x00, 0x3d, 0x00, 0x2e, 0x00, 0x3a, 0x00, 0x28, 0x00, 0x2e, 0x00, 0x1e, 0x00, 0x1b, 0x00, 0x14, 0x00, 0x08, 0x00, 0x0c, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfb, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xf1, 0xff, 0x06, 0x00, 0xde, 0xff, 0x0a, 0x00, 0xc9, 0xff, 0x09, 0x00, 0xb3, 0xff, 0x02, 0x00, 0xa1, 0xff, 0xf6, 0xff, 0x95, 0xff, 0xe7, 0xff, 0x8e, 0xff, 0xd8, 0xff, 0x8e, 0xff, 0xd2, 0xff, 0x90, 0xff, 0xd5, 0xff, 0x92, 0xff, 0xe2, 0xff, 0x8e, 0xff, 0xf0, 0xff, 0x84, 0xff, 0xf8, 0xff, 0x75, 0xff, 0xf5, 0xff, 0x68, 0xff, 0xe9, 0xff, 0x63, 0xff, 0xd9, 0xff, 0x68, 0xff, 0xcd, 0xff, 0x73, 0xff, 0xca, 0xff, 0x7f, 0xff, 0xce, 0xff, 0x87, 0xff, 0xd7, 0xff, 0x8a, 0xff, 0xe2, 0xff, 0x8a, 0xff, 0xec, 0xff, 0x88, 0xff, 0xef, 0xff, 0x87, 0xff, 0xe8, 0xff, 0x8b, 0xff, 0xd9, 0xff, 0x95, 0xff, 0xc9, 0xff, 0xa4, 0xff, 0xbd, 0xff, 0xb2, 0xff, 0xb9, 0xff, 0xbd, 0xff, 0xbe, 0xff, 0xc1, 0xff, 0xc9, 0xff, 0xc1, 0xff, 0xd3, 0xff, 0xc0, 0xff, 0xda, 0xff, 0xc5, 0xff, 0xdd, 0xff, 0xcf, 0xff, 0xdc, 0xff, 0xdc, 0xff, 0xd7, 0xff, 0xed, 0xff, 0xd0, 0xff, 0xfc, 0xff, 0xc9, 0xff, 0x0b, 0x00, 0xc8, 0xff, 0x18, 0x00, 0xce, 0xff, 0x23, 0x00, 0xdc, 0xff, 0x2e, 0x00, 0xef, 0xff, 0x34, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x0c, 0x00, 0x40, 0x00, 0x10, 0x00, 0x48, 0x00, 0x0f, 0x00, 0x56, 0x00, 0x0f, 0x00, 0x67, 0x00, 0x13, 0x00, 0x7b, 0x00, 0x1e, 0x00, 0x8e, 0x00, 0x2f, 0x00, 0x9c, 0x00, 0x42, 0x00, 0xa3, 0x00, 0x53, 0x00, 0xa5, 0x00, 0x5e, 0x00, 0xa2, 0x00, 0x62, 0x00, 0x9e, 0x00, 0x5f, 0x00, 0x9b, 0x00, 0x5b, 0x00, 0x9d, 0x00, 0x5a, 0x00, 0xa2, 0x00, 0x5d, 0x00, 0xa6, 0x00, 0x63, 0x00, 0xa8, 0x00, 0x6b, 0x00, 0xa2, 0x00, 0x70, 0x00, 0x94, 0x00, 0x6e, 0x00, 0x7e, 0x00, 0x65, 0x00, 0x68, 0x00, 0x58, 0x00, 0x58, 0x00, 0x4d, 0x00, 0x51, 0x00, 0x47, 0x00, 0x50, 0x00, 0x43, 0x00, 0x4f, 0x00, 0x42, 0x00, 0x4a, 0x00, 0x42, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x24, 0x00, 0x31, 0x00, 0x09, 0x00, 0x23, 0x00, 0xf2, 0xff, 0x16, 0x00, 0xe2, 0xff, 0x0c, 0x00, 0xda, 0xff, 0x07, 0x00, 0xd9, 0xff, 0x06, 0x00, 0xdb, 0xff, 0x07, 0x00, 0xda, 0xff, 0x0a, 0x00, 0xd6, 0xff, 0x0e, 0x00, 0xcf, 0xff, 0x12, 0x00, 0xc6, 0xff, 0x14, 0x00, 0xbc, 0xff, 0x11, 0x00, 0xb1, 0xff, 0x08, 0x00, 0xa6, 0xff, 0xfb, 0xff, 0x9f, 0xff, 0xee, 0xff, 0x9c, 0xff, 0xe8, 0xff, 0x9a, 0xff, 0xe8, 0xff, 0x9c, 0xff, 0xef, 0xff, 0xa0, 0xff, 0xfc, 0xff, 0xa4, 0xff, 0x09, 0x00, 0xa5, 0xff, 0x10, 0x00, 0xa1, 0xff, 0x0e, 0x00, 0x9a, 0xff, 0x03, 0x00, 0x90, 0xff, 0xf1, 0xff, 0x88, 0xff, 0xe2, 0xff, 0x84, 0xff, 0xd8, 0xff, 0x87, 0xff, 0xd6, 0xff, 0x8d, 0xff, 0xdb, 0xff, 0x95, 0xff, 0xe1, 0xff, 0x9b, 0xff, 0xe6, 0xff, 0x9d, 0xff, 0xe8, 0xff, 0x9e, 0xff, 0xe7, 0xff, 0x9e, 0xff, 0xe6, 0xff, 0xa1, 0xff, 0xe6, 0xff, 0xab, 0xff, 0xe8, 0xff, 0xbc, 0xff, 0xed, 0xff, 0xd2, 0xff, 0xf5, 0xff, 0xe7, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x14, 0x00, 0xfd, 0xff, 0x1c, 0x00, 0xfd, 0xff, 0x21, 0x00, 0x00, 0x00, 0x23, 0x00, 0x08, 0x00, 0x22, 0x00, 0x16, 0x00, 0x22, 0x00, 0x28, 0x00, 0x25, 0x00, 0x39, 0x00, 0x2d, 0x00, 0x45, 0x00, 0x38, 0x00, 0x49, 0x00, 0x42, 0x00, 0x47, 0x00, 0x49, 0x00, 0x43, 0x00, 0x4a, 0x00, 0x42, 0x00, 0x45, 0x00, 0x44, 0x00, 0x3c, 0x00, 0x4a, 0x00, 0x35, 0x00, 0x53, 0x00, 0x35, 0x00, 0x5b, 0x00, 0x3b, 0x00, 0x5f, 0x00, 0x44, 0x00, 0x5f, 0x00, 0x4e, 0x00, 0x5b, 0x00, 0x53, 0x00, 0x55, 0x00, 0x52, 0x00, 0x50, 0x00, 0x4a, 0x00, 0x4e, 0x00, 0x41, 0x00, 0x50, 0x00, 0x3b, 0x00, 0x54, 0x00, 0x38, 0x00, 0x56, 0x00, 0x39, 0x00, 0x56, 0x00, 0x3e, 0x00, 0x52, 0x00, 0x44, 0x00, 0x45, 0x00, 0x44, 0x00, 0x35, 0x00, 0x3e, 0x00, 0x24, 0x00, 0x33, 0x00, 0x16, 0x00, 0x24, 0x00, 0x0d, 0x00, 0x16, 0x00, 0x09, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x03, 0x00, 0x08, 0x00, 0xf1, 0xff, 0x05, 0x00, 0xda, 0xff, 0xfd, 0xff, 0xc1, 0xff, 0xef, 0xff, 0xac, 0xff, 0xdc, 0xff, 0x9e, 0xff, 0xc9, 0xff, 0x9a, 0xff, 0xbb, 0xff, 0x9b, 0xff, 0xb2, 0xff, 0x9c, 0xff, 0xaf, 0xff, 0x96, 0xff, 0xb0, 0xff, 0x86, 0xff, 0xb2, 0xff, 0x70, 0xff, 0xb3, 0xff, 0x57, 0xff, 0xad, 0xff, 0x45, 0xff, 0xa3, 0xff, 0x3e, 0xff, 0x96, 0xff, 0x41, 0xff, 0x87, 0xff, 0x4a, 0xff, 0x78, 0xff, 0x51, 0xff, 0x6d, 0xff, 0x52, 0xff, 0x69, 0xff, 0x4e, 0xff, 0x6d, 0xff, 0x47, 0xff, 0x76, 0xff, 0x43, 0xff, 0x7e, 0xff, 0x48, 0xff, 0x82, 0xff, 0x57, 0xff, 0x7f, 0xff, 0x6f, 0xff, 0x78, 0xff, 0x89, 0xff, 0x6f, 0xff, 0xa1, 0xff, 0x68, 0xff, 0xb1, 0xff, 0x64, 0xff, 0xbc, 0xff, 0x65, 0xff, 0xc3, 0xff, 0x69, 0xff, 0xca, 0xff, 0x6e, 0xff, 0xd7, 0xff, 0x74, 0xff, 0xec, 0xff, 0x79, 0xff, 0x07, 0x00, 0x7d, 0xff, 0x20, 0x00, 0x7c, 0xff, 0x34, 0x00, 0x76, 0xff, 0x42, 0x00, 0x71, 0xff, 0x4e, 0x00, 0x71, 0xff, 0x59, 0x00, 0x78, 0xff, 0x63, 0x00, 0x83, 0xff, 0x6d, 0x00, 0x91, 0xff, 0x77, 0x00, 0x9c, 0xff, 0x81, 0x00, 0xa4, 0xff, 0x8c, 0x00, 0xa8, 0xff, 0x96, 0x00, 0xaa, 0xff, 0x9f, 0x00, 0xac, 0xff, 0xa8, 0x00, 0xb2, 0xff, 0xb2, 0x00, 0xbe, 0xff, 0xbc, 0x00, 0xd3, 0xff, 0xc5, 0x00, 0xed, 0xff, 0xca, 0x00, 0x08, 0x00, 0xcc, 0x00, 0x1e, 0x00, 0xcd, 0x00, 0x2b, 0x00, 0xcd, 0x00, 0x2f, 0x00, 0xcd, 0x00, 0x2d, 0x00, 0xcf, 0x00, 0x2c, 0x00, 0xd2, 0x00, 0x2f, 0x00, 0xd5, 0x00, 0x3a, 0x00, 0xd7, 0x00, 0x4c, 0x00, 0xd6, 0x00, 0x5f, 0x00, 0xd0, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0x78, 0x00, 0xbe, 0x00, 0x79, 0x00, 0xb1, 0x00, 0x72, 0x00, 0xa1, 0x00, 0x65, 0x00, 0x91, 0x00, 0x58, 0x00, 0x84, 0x00, 0x50, 0x00, 0x79, 0x00, 0x4b, 0x00, 0x6f, 0x00, 0x4c, 0x00, 0x64, 0x00, 0x4f, 0x00, 0x55, 0x00, 0x51, 0x00, 0x43, 0x00, 0x50, 0x00, 0x30, 0x00, 0x4c, 0x00, 0x1d, 0x00, 0x44, 0x00, 0x0b, 0x00, 0x3a, 0x00, 0xfe, 0xff, 0x31, 0x00, 0xf3, 0xff, 0x2c, 0x00, 0xe8, 0xff, 0x2a, 0x00, 0xda, 0xff, 0x2b, 0x00, 0xc8, 0xff, 0x2d, 0x00, 0xb5, 0xff, 0x30, 0x00, 0xa3, 0xff, 0x2e, 0x00, 0x93, 0xff, 0x27, 0x00, 0x89, 0xff, 0x1d, 0x00, 0x84, 0xff, 0x10, 0x00, 0x82, 0xff, 0x05, 0x00, 0x81, 0xff, 0xff, 0xff, 0x7c, 0xff, 0xfe, 0xff, 0x72, 0xff, 0x01, 0x00, 0x65, 0xff, 0x02, 0x00, 0x59, 0xff, 0x01, 0x00, 0x54, 0xff, 0xfb, 0xff, 0x56, 0xff, 0xf2, 0xff, 0x5e, 0xff, 0xe8, 0xff, 0x68, 0xff, 0xe2, 0xff, 0x71, 0xff, 0xde, 0xff, 0x72, 0xff, 0xd9, 0xff, 0x6f, 0xff, 0xd5, 0xff, 0x6b, 0xff, 0xd0, 0xff, 0x68, 0xff, 0xcb, 0xff, 0x6c, 0xff, 0xc8, 0xff, 0x76, 0xff, 0xc6, 0xff, 0x81, 0xff, 0xc6, 0xff, 0x8a, 0xff, 0xc6, 0xff, 0x8f, 0xff, 0xc8, 0xff, 0x91, 0xff, 0xca, 0xff, 0x92, 0xff, 0xc9, 0xff, 0x96, 0xff, 0xc9, 0xff, 0xa1, 0xff, 0xcb, 0xff, 0xb4, 0xff, 0xd2, 0xff, 0xcb, 0xff, 0xdc, 0xff, 0xe0, 0xff, 0xe6, 0xff, 0xf2, 0xff, 0xf1, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x09, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x14, 0x00, 0x22, 0x00, 0x1c, 0x00, 0x30, 0x00, 0x26, 0x00, 0x43, 0x00, 0x30, 0x00, 0x59, 0x00, 0x3a, 0x00, 0x6c, 0x00, 0x40, 0x00, 0x78, 0x00, 0x41, 0x00, 0x7c, 0x00, 0x3f, 0x00, 0x7d, 0x00, 0x3f, 0x00, 0x7c, 0x00, 0x42, 0x00, 0x7c, 0x00, 0x4a, 0x00, 0x7e, 0x00, 0x51, 0x00, 0x81, 0x00, 0x54, 0x00, 0x85, 0x00, 0x55, 0x00, 0x88, 0x00, 0x51, 0x00, 0x89, 0x00, 0x4b, 0x00, 0x85, 0x00, 0x47, 0x00, 0x7d, 0x00, 0x47, 0x00, 0x71, 0x00, 0x4b, 0x00, 0x66, 0x00, 0x55, 0x00, 0x5d, 0x00, 0x60, 0x00, 0x56, 0x00, 0x65, 0x00, 0x51, 0x00, 0x65, 0x00, 0x4b, 0x00, 0x5e, 0x00, 0x3f, 0x00, 0x54, 0x00, 0x2f, 0x00, 0x4d, 0x00, 0x18, 0x00, 0x48, 0x00, 0x01, 0x00, 0x46, 0x00, 0xed, 0xff, 0x45, 0x00, 0xe2, 0xff, 0x44, 0x00, 0xe0, 0xff, 0x41, 0x00, 0xe0, 0xff, 0x3b, 0x00, 0xdd, 0xff, 0x2f, 0x00, 0xd2, 0xff, 0x21, 0x00, 0xbf, 0xff, 0x13, 0x00, 0xa7, 0xff, 0x06, 0x00, 0x8f, 0xff, 0xfd, 0xff, 0x7e, 0xff, 0xfa, 0xff, 0x77, 0xff, 0xfb, 0xff, 0x78, 0xff, 0xff, 0xff, 0x80, 0xff, 0x05, 0x00, 0x89, 0xff, 0x08, 0x00, 0x8d, 0xff, 0x06, 0x00, 0x8c, 0xff, 0xfe, 0xff, 0x86, 0xff, 0xef, 0xff, 0x7e, 0xff, 0xdf, 0xff, 0x79, 0xff, 0xd3, 0xff, 0x79, 0xff, 0xcf, 0xff, 0x7e, 0xff, 0xd1, 0xff, 0x86, 0xff, 0xd7, 0xff, 0x90, 0xff, 0xdd, 0xff, 0x9a, 0xff, 0xdc, 0xff, 0x9e, 0xff, 0xd0, 0xff, 0x9f, 0xff, 0xbe, 0xff, 0xa1, 0xff, 0xaa, 0xff, 0xa3, 0xff, 0x9a, 0xff, 0xa6, 0xff, 0x91, 0xff, 0xaa, 0xff, 0x90, 0xff, 0xb3, 0xff, 0x95, 0xff, 0xbf, 0xff, 0x9a, 0xff, 0xcc, 0xff, 0x9a, 0xff, 0xd8, 0xff, 0x92, 0xff, 0xe0, 0xff, 0x87, 0xff, 0xe4, 0xff, 0x7b, 0xff, 0xe3, 0xff, 0x72, 0xff, 0xe1, 0xff, 0x70, 0xff, 0xe1, 0xff, 0x75, 0xff, 0xe5, 0xff, 0x7f, 0xff, 0xef, 0xff, 0x8b, 0xff, 0xfc, 0xff, 0x93, 0xff, 0x0b, 0x00, 0x98, 0xff, 0x18, 0x00, 0x9a, 0xff, 0x21, 0x00, 0x9c, 0xff, 0x24, 0x00, 0xa1, 0xff, 0x26, 0x00, 0xac, 0xff, 0x2a, 0x00, 0xbc, 0xff, 0x32, 0x00, 0xcf, 0xff, 0x3e, 0x00, 0xe2, 0xff, 0x4c, 0x00, 0xf4, 0xff, 0x5a, 0x00, 0x04, 0x00, 0x66, 0x00, 0x13, 0x00, 0x6c, 0x00, 0x21, 0x00, 0x6e, 0x00, 0x2f, 0x00, 0x6f, 0x00, 0x3c, 0x00, 0x72, 0x00, 0x49, 0x00, 0x77, 0x00, 0x53, 0x00, 0x7f, 0x00, 0x5a, 0x00, 0x88, 0x00, 0x5f, 0x00, 0x92, 0x00, 0x63, 0x00, 0x99, 0x00, 0x66, 0x00, 0x9c, 0x00, 0x69, 0x00, 0x9c, 0x00, 0x6a, 0x00, 0x98, 0x00, 0x69, 0x00, 0x90, 0x00, 0x65, 0x00, 0x85, 0x00, 0x5e, 0x00, 0x79, 0x00, 0x54, 0x00, 0x6f, 0x00, 0x4a, 0x00, 0x69, 0x00, 0x42, 0x00, 0x66, 0x00, 0x3a, 0x00, 0x62, 0x00, 0x33, 0x00, 0x5a, 0x00, 0x2e, 0x00, 0x4d, 0x00, 0x2c, 0x00, 0x39, 0x00, 0x2d, 0x00, 0x21, 0x00, 0x2e, 0x00, 0x07, 0x00, 0x30, 0x00, 0xf0, 0xff, 0x31, 0x00, 0xe0, 0xff, 0x32, 0x00, 0xda, 0xff, 0x32, 0x00, 0xdc, 0xff, 0x31, 0x00, 0xe0, 0xff, 0x30, 0x00, 0xe0, 0xff, 0x2e, 0x00, 0xd7, 0xff, 0x2e, 0x00, 0xc4, 0xff, 0x2f, 0x00, 0xac, 0xff, 0x2f, 0x00, 0x97, 0xff, 0x30, 0x00, 0x8d, 0xff, 0x32, 0x00, 0x8c, 0xff, 0x31, 0x00, 0x91, 0xff, 0x2a, 0x00, 0x99, 0xff, 0x1e, 0x00, 0x9d, 0xff, 0x0f, 0x00, 0x97, 0xff, 0xff, 0xff, 0x88, 0xff, 0xf1, 0xff, 0x76, 0xff, 0xe9, 0xff, 0x68, 0xff, 0xe7, 0xff, 0x61, 0xff, 0xeb, 0xff, 0x65, 0xff, 0xf1, 0xff, 0x71, 0xff, 0xf7, 0xff, 0x80, 0xff, 0xf9, 0xff, 0x8c, 0xff, 0xf5, 0xff, 0x92, 0xff, 0xee, 0xff, 0x91, 0xff, 0xe8, 0xff, 0x8d, 0xff, 0xe7, 0xff, 0x8a, 0xff, 0xec, 0xff, 0x8b, 0xff, 0xf6, 0xff, 0x93, 0xff, 0x01, 0x00, 0xa0, 0xff, 0x09, 0x00, 0xaf, 0xff, 0x0c, 0x00, 0xbe, 0xff, 0x09, 0x00, 0xcb, 0xff, 0x03, 0x00, 0xd4, 0xff, 0xfc, 0xff, 0xdb, 0xff, 0xf9, 0xff, 0xe1, 0xff, 0xfc, 0xff, 0xe6, 0xff, 0x03, 0x00, 0xea, 0xff, 0x0a, 0x00, 0xef, 0xff, 0x0f, 0x00, 0xfb, 0xff, 0x12, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x1d, 0x00, 0x08, 0x00, 0x2e, 0x00, 0xff, 0xff, 0x39, 0x00, 0xf6, 0xff, 0x3e, 0x00, 0xf0, 0xff, 0x3f, 0x00, 0xee, 0xff, 0x40, 0x00, 0xf2, 0xff, 0x45, 0x00, 0xf8, 0xff, 0x4d, 0x00, 0xfd, 0xff, 0x58, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x72, 0x00, 0xfd, 0xff, 0x78, 0x00, 0xf7, 0xff, 0x77, 0x00, 0xf1, 0xff, 0x71, 0x00, 0xee, 0xff, 0x6c, 0x00, 0xf2, 0xff, 0x6a, 0x00, 0xfc, 0xff, 0x6c, 0x00, 0x08, 0x00, 0x70, 0x00, 0x11, 0x00, 0x74, 0x00, 0x16, 0x00, 0x76, 0x00, 0x16, 0x00, 0x74, 0x00, 0x13, 0x00, 0x6c, 0x00, 0x10, 0x00, 0x61, 0x00, 0x0e, 0x00, 0x55, 0x00, 0x11, 0x00, 0x4a, 0x00, 0x15, 0x00, 0x40, 0x00, 0x19, 0x00, 0x37, 0x00, 0x1c, 0x00, 0x30, 0x00, 0x19, 0x00, 0x27, 0x00, 0x10, 0x00, 0x1c, 0x00, 0x03, 0x00, 0x10, 0x00, 0xf3, 0xff, 0x03, 0x00, 0xe6, 0xff, 0xf9, 0xff, 0xe1, 0xff, 0xf0, 0xff, 0xe3, 0xff, 0xe9, 0xff, 0xea, 0xff, 0xe2, 0xff, 0xf1, 0xff, 0xd9, 0xff, 0xf3, 0xff, 0xd2, 0xff, 0xef, 0xff, 0xcc, 0xff, 0xe7, 0xff, 0xc9, 0xff, 0xde, 0xff, 0xc7, 0xff, 0xd7, 0xff, 0xc4, 0xff, 0xd1, 0xff, 0xc0, 0xff, 0xcf, 0xff, 0xbb, 0xff, 0xd1, 0xff, 0xb8, 0xff, 0xd6, 0xff, 0xb5, 0xff, 0xda, 0xff, 0xb5, 0xff, 0xdd, 0xff, 0xb7, 0xff, 0xde, 0xff, 0xbc, 0xff, 0xdc, 0xff, 0xc3, 0xff, 0xd7, 0xff, 0xc7, 0xff, 0xcf, 0xff, 0xc7, 0xff, 0xc7, 0xff, 0xc5, 0xff, 0xc1, 0xff, 0xc1, 0xff, 0xc0, 0xff, 0xc0, 0xff, 0xc3, 0xff, 0xc4, 0xff, 0xc9, 0xff, 0xce, 0xff, 0xd0, 0xff, 0xdc, 0xff, 0xd4, 0xff, 0xe7, 0xff, 0xd3, 0xff, 0xeb, 0xff, 0xce, 0xff, 0xea, 0xff, 0xc9, 0xff, 0xe9, 0xff, 0xca, 0xff, 0xec, 0xff, 0xd0, 0xff, 0xf3, 0xff, 0xd8, 0xff, 0xfd, 0xff, 0xde, 0xff, 0x07, 0x00, 0xe0, 0xff, 0x10, 0x00, 0xdf, 0xff, 0x16, 0x00, 0xdb, 0xff, 0x1a, 0x00, 0xd8, 0xff, 0x1c, 0x00, 0xd9, 0xff, 0x1c, 0x00, 0xdf, 0xff, 0x1d, 0x00, 0xe7, 0xff, 0x24, 0x00, 0xf1, 0xff, 0x31, 0x00, 0xfb, 0xff, 0x41, 0x00, 0xff, 0xff, 0x50, 0x00, 0xfe, 0xff, 0x5b, 0x00, 0xfc, 0xff, 0x62, 0x00, 0xfc, 0xff, 0x66, 0x00, 0xff, 0xff, 0x6b, 0x00, 0x07, 0x00, 0x70, 0x00, 0x11, 0x00, 0x76, 0x00, 0x1a, 0x00, 0x7d, 0x00, 0x21, 0x00, 0x83, 0x00, 0x22, 0x00, 0x87, 0x00, 0x1e, 0x00, 0x88, 0x00, 0x18, 0x00, 0x84, 0x00, 0x12, 0x00, 0x7d, 0x00, 0x10, 0x00, 0x76, 0x00, 0x13, 0x00, 0x6e, 0x00, 0x18, 0x00, 0x68, 0x00, 0x1e, 0x00, 0x62, 0x00, 0x23, 0x00, 0x5e, 0x00, 0x27, 0x00, 0x5a, 0x00, 0x2a, 0x00, 0x55, 0x00, 0x2a, 0x00, 0x4d, 0x00, 0x28, 0x00, 0x40, 0x00, 0x25, 0x00, 0x32, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x1b, 0x00, 0x2c, 0x00, 0x16, 0x00, 0x34, 0x00, 0x13, 0x00, 0x3c, 0x00, 0x0f, 0x00, 0x42, 0x00, 0x0b, 0x00, 0x46, 0x00, 0x05, 0x00, 0x47, 0x00, 0xfb, 0xff, 0x44, 0x00, 0xed, 0xff, 0x3f, 0x00, 0xde, 0xff, 0x3b, 0x00, 0xcf, 0xff, 0x38, 0x00, 0xc2, 0xff, 0x39, 0x00, 0xba, 0xff, 0x3c, 0x00, 0xb5, 0xff, 0x3e, 0x00, 0xb1, 0xff, 0x3d, 0x00, 0xab, 0xff, 0x36, 0x00, 0xa2, 0xff, 0x2b, 0x00, 0x97, 0xff, 0x1e, 0x00, 0x8a, 0xff, 0x14, 0x00, 0x81, 0xff, 0x10, 0x00, 0x7b, 0xff, 0x11, 0x00, 0x78, 0xff, 0x17, 0x00, 0x78, 0xff, 0x1d, 0x00, 0x7a, 0xff, 0x21, 0x00, 0x7c, 0xff, 0x1f, 0x00, 0x7d, 0xff, 0x18, 0x00, 0x7e, 0xff, 0x10, 0x00, 0x7f, 0xff, 0x0a, 0x00, 0x80, 0xff, 0x04, 0x00, 0x82, 0xff, 0x02, 0x00, 0x86, 0xff, 0x04, 0x00, 0x8c, 0xff, 0x08, 0x00, 0x92, 0xff, 0x0b, 0x00, 0x9a, 0xff, 0x0b, 0x00, 0xa5, 0xff, 0x09, 0x00, 0xb1, 0xff, 0x03, 0x00, 0xbe, 0xff, 0xfb, 0xff, 0xcd, 0xff, 0xf5, 0xff, 0xde, 0xff, 0xf2, 0xff, 0xef, 0xff, 0xf4, 0xff, 0xff, 0xff, 0xf9, 0xff, 0x0e, 0x00, 0xff, 0xff, 0x1c, 0x00, 0x05, 0x00, 0x2a, 0x00, 0x09, 0x00, 0x3a, 0x00, 0x08, 0x00, 0x47, 0x00, 0x02, 0x00, 0x4e, 0x00, 0xf7, 0xff, 0x4f, 0x00, 0xec, 0xff, 0x4b, 0x00, 0xe3, 0xff, 0x44, 0x00, 0xde, 0xff, 0x3f, 0x00, 0xdc, 0xff, 0x3f, 0x00, 0xde, 0xff, 0x46, 0x00, 0xe5, 0xff, 0x51, 0x00, 0xed, 0xff, 0x59, 0x00, 0xf0, 0xff, 0x5d, 0x00, 0xef, 0xff, 0x5b, 0x00, 0xea, 0xff, 0x51, 0x00, 0xe2, 0xff, 0x44, 0x00, 0xde, 0xff, 0x3a, 0x00, 0xdf, 0xff, 0x37, 0x00, 0xe6, 0xff, 0x3c, 0x00, 0xef, 0xff, 0x46, 0x00, 0xf9, 0xff, 0x52, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x05, 0x00, 0x5c, 0x00, 0x07, 0x00, 0x55, 0x00, 0x04, 0x00, 0x4a, 0x00, 0xff, 0xff, 0x40, 0x00, 0xfc, 0xff, 0x3b, 0x00, 0xfe, 0xff, 0x3d, 0x00, 0x04, 0x00, 0x45, 0x00, 0x0e, 0x00, 0x4c, 0x00, 0x17, 0x00, 0x4e, 0x00, 0x1b, 0x00, 0x48, 0x00, 0x1a, 0x00, 0x3a, 0x00, 0x16, 0x00, 0x2a, 0x00, 0x11, 0x00, 0x1c, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x0d, 0x00, 0x12, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x05, 0x00, 0x13, 0x00, 0xfc, 0xff, 0x13, 0x00, 0xed, 0xff, 0x11, 0x00, 0xda, 0xff, 0x0e, 0x00, 0xc7, 0xff, 0x0a, 0x00, 0xb7, 0xff, 0x05, 0x00, 0xac, 0xff, 0x00, 0x00, 0xa4, 0xff, 0xf8, 0xff, 0x9c, 0xff, 0xf0, 0xff, 0x92, 0xff, 0xe9, 0xff, 0x88, 0xff, 0xe6, 0xff, 0x7d, 0xff, 0xe6, 0xff, 0x71, 0xff, 0xe6, 0xff, 0x67, 0xff, 0xe5, 0xff, 0x61, 0xff, 0xe1, 0xff, 0x60, 0xff, 0xdd, 0xff, 0x64, 0xff, 0xda, 0xff, 0x6a, 0xff, 0xd8, 0xff, 0x71, 0xff, 0xd9, 0xff, 0x77, 0xff, 0xdb, 0xff, 0x79, 0xff, 0xdb, 0xff, 0x79, 0xff, 0xda, 0xff, 0x7a, 0xff, 0xda, 0xff, 0x7e, 0xff, 0xd9, 0xff, 0x86, 0xff, 0xd9, 0xff, 0x93, 0xff, 0xd9, 0xff, 0xa4, 0xff, 0xd9, 0xff, 0xb4, 0xff, 0xd8, 0xff, 0xc2, 0xff, 0xd5, 0xff, 0xcd, 0xff, 0xd2, 0xff, 0xd3, 0xff, 0xce, 0xff, 0xd6, 0xff, 0xca, 0xff, 0xd9, 0xff, 0xc8, 0xff, 0xdf, 0xff, 0xc9, 0xff, 0xe8, 0xff, 0xcb, 0xff, 0xf4, 0xff, 0xcd, 0xff, 0x02, 0x00, 0xcc, 0xff, 0x10, 0x00, 0xc8, 0xff, 0x1b, 0x00, 0xc2, 0xff, 0x22, 0x00, 0xbc, 0xff, 0x28, 0x00, 0xb8, 0xff, 0x2c, 0x00, 0xba, 0xff, 0x2f, 0x00, 0xbe, 0xff, 0x32, 0x00, 0xc5, 0xff, 0x38, 0x00, 0xca, 0xff, 0x3f, 0x00, 0xcf, 0xff, 0x49, 0x00, 0xd2, 0xff, 0x52, 0x00, 0xd2, 0xff, 0x5a, 0x00, 0xd1, 0xff, 0x62, 0x00, 0xd2, 0xff, 0x69, 0x00, 0xd5, 0xff, 0x6e, 0x00, 0xda, 0xff, 0x6f, 0x00, 0xe0, 0xff, 0x71, 0x00, 0xe6, 0xff, 0x73, 0x00, 0xec, 0xff, 0x78, 0x00, 0xf2, 0xff, 0x7f, 0x00, 0xf7, 0xff, 0x86, 0x00, 0xfc, 0xff, 0x8b, 0x00, 0x01, 0x00, 0x8d, 0x00, 0x05, 0x00, 0x89, 0x00, 0x09, 0x00, 0x7f, 0x00, 0x0b, 0x00, 0x74, 0x00, 0x0e, 0x00, 0x6a, 0x00, 0x13, 0x00, 0x64, 0x00, 0x1a, 0x00, 0x61, 0x00, 0x25, 0x00, 0x5f, 0x00, 0x30, 0x00, 0x5a, 0x00, 0x39, 0x00, 0x4f, 0x00, 0x3d, 0x00, 0x3f, 0x00, 0x3d, 0x00, 0x2c, 0x00, 0x3b, 0x00, 0x19, 0x00, 0x3c, 0x00, 0x0a, 0x00, 0x41, 0x00, 0xfe, 0xff, 0x48, 0x00, 0xf8, 0xff, 0x52, 0x00, 0xf8, 0xff, 0x5d, 0x00, 0xfa, 0xff, 0x66, 0x00, 0xfa, 0xff, 0x6a, 0x00, 0xf2, 0xff, 0x67, 0x00, 0xe4, 0xff, 0x5e, 0x00, 0xd3, 0xff, 0x53, 0x00, 0xc4, 0xff, 0x4c, 0x00, 0xbb, 0xff, 0x49, 0x00, 0xba, 0xff, 0x4b, 0x00, 0xbe, 0xff, 0x4f, 0x00, 0xc3, 0xff, 0x50, 0x00, 0xc6, 0xff, 0x4e, 0x00, 0xc5, 0xff, 0x49, 0x00, 0xbe, 0xff, 0x42, 0x00, 0xb2, 0xff, 0x39, 0x00, 0xa5, 0xff, 0x30, 0x00, 0x99, 0xff, 0x26, 0x00, 0x94, 0xff, 0x1f, 0x00, 0x95, 0xff, 0x1b, 0x00, 0x9b, 0xff, 0x1c, 0x00, 0xa2, 0xff, 0x1f, 0x00, 0xa4, 0xff, 0x22, 0x00, 0xa0, 0xff, 0x23, 0x00, 0x99, 0xff, 0x21, 0x00, 0x91, 0xff, 0x1c, 0x00, 0x8d, 0xff, 0x12, 0x00, 0x8e, 0xff, 0x07, 0x00, 0x94, 0xff, 0xfe, 0xff, 0x9e, 0xff, 0xfb, 0xff, 0xa9, 0xff, 0xfd, 0xff, 0xb3, 0xff, 0x05, 0x00, 0xbc, 0xff, 0x0d, 0x00, 0xc4, 0xff, 0x13, 0x00, 0xcc, 0xff, 0x14, 0x00, 0xd5, 0xff, 0x0e, 0x00, 0xdf, 0xff, 0x04, 0x00, 0xeb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xf5, 0xff, 0x0b, 0x00, 0xf5, 0xff, 0x1a, 0x00, 0xf8, 0xff, 0x26, 0x00, 0xfc, 0xff, 0x30, 0x00, 0xfd, 0xff, 0x39, 0x00, 0xfb, 0xff, 0x41, 0x00, 0xf7, 0xff, 0x4a, 0x00, 0xf2, 0xff, 0x53, 0x00, 0xee, 0xff, 0x5b, 0x00, 0xea, 0xff, 0x61, 0x00, 0xe6, 0xff, 0x64, 0x00, 0xe3, 0xff, 0x66, 0x00, 0xe1, 0xff, 0x65, 0x00, 0xe0, 0xff, 0x64, 0x00, 0xde, 0xff, 0x65, 0x00, 0xdc, 0xff, 0x66, 0x00, 0xdb, 0xff, 0x67, 0x00, 0xdb, 0xff, 0x6a, 0x00, 0xdc, 0xff, 0x6c, 0x00, 0xde, 0xff, 0x6c, 0x00, 0xe0, 0xff, 0x68, 0x00, 0xe0, 0xff, 0x61, 0x00, 0xde, 0xff, 0x58, 0x00, 0xda, 0xff, 0x50, 0x00, 0xd8, 0xff, 0x4a, 0x00, 0xd9, 0xff, 0x47, 0x00, 0xdd, 0xff, 0x45, 0x00, 0xe4, 0xff, 0x43, 0x00, 0xea, 0xff, 0x41, 0x00, 0xee, 0xff, 0x3e, 0x00, 0xf0, 0xff, 0x3a, 0x00, 0xf0, 0xff, 0x33, 0x00, 0xef, 0xff, 0x2c, 0x00, 0xee, 0xff, 0x24, 0x00, 0xed, 0xff, 0x1e, 0x00, 0xf0, 0xff, 0x1b, 0x00, 0xf4, 0xff, 0x1c, 0x00, 0xfa, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x22, 0x00, 0x04, 0x00, 0x23, 0x00, 0x08, 0x00, 0x1f, 0x00, 0x08, 0x00, 0x16, 0x00, 0x04, 0x00, 0x0a, 0x00, 0xfe, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xf2, 0xff, 0xf1, 0xff, 0xeb, 0xff, 0xee, 0xff, 0xe7, 0xff, 0xed, 0xff, 0xe6, 0xff, 0xee, 0xff, 0xe5, 0xff, 0xed, 0xff, 0xe1, 0xff, 0xea, 0xff, 0xd8, 0xff, 0xe4, 0xff, 0xcd, 0xff, 0xdc, 0xff, 0xbf, 0xff, 0xd6, 0xff, 0xb1, 0xff, 0xcf, 0xff, 0xa6, 0xff, 0xcc, 0xff, 0xa0, 0xff, 0xcb, 0xff, 0x9e, 0xff, 0xcc, 0xff, 0xa0, 0xff, 0xcd, 0xff, 0xa4, 0xff, 0xcd, 0xff, 0xa7, 0xff, 0xcd, 0xff, 0xa8, 0xff, 0xcd, 0xff, 0xa8, 0xff, 0xcd, 0xff, 0xa8, 0xff, 0xd1, 0xff, 0xa9, 0xff, 0xd7, 0xff, 0xac, 0xff, 0xde, 0xff, 0xb3, 0xff, 0xe5, 0xff, 0xbe, 0xff, 0xe9, 0xff, 0xc8, 0xff, 0xeb, 0xff, 0xd0, 0xff, 0xeb, 0xff, 0xd6, 0xff, 0xed, 0xff, 0xda, 0xff, 0xf1, 0xff, 0xdc, 0xff, 0xf5, 0xff, 0xde, 0xff, 0xfa, 0xff, 0xe0, 0xff, 0xfd, 0xff, 0xe5, 0xff, 0xff, 0xff, 0xed, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x0d, 0x00, 0xff, 0xff, 0x15, 0x00, 0x01, 0x00, 0x1a, 0x00, 0x05, 0x00, 0x1c, 0x00, 0x08, 0x00, 0x1d, 0x00, 0x0b, 0x00, 0x1e, 0x00, 0x0d, 0x00, 0x22, 0x00, 0x0f, 0x00, 0x25, 0x00, 0x12, 0x00, 0x29, 0x00, 0x16, 0x00, 0x2b, 0x00, 0x1b, 0x00, 0x2d, 0x00, 0x1f, 0x00, 0x2c, 0x00, 0x23, 0x00, 0x2b, 0x00, 0x25, 0x00, 0x2a, 0x00, 0x26, 0x00, 0x29, 0x00, 0x27, 0x00, 0x29, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2b, 0x00, 0x28, 0x00, 0x30, 0x00, 0x24, 0x00, 0x35, 0x00, 0x1f, 0x00, 0x39, 0x00, 0x19, 0x00, 0x3b, 0x00, 0x15, 0x00, 0x3b, 0x00, 0x15, 0x00, 0x39, 0x00, 0x16, 0x00, 0x37, 0x00, 0x17, 0x00, 0x34, 0x00, 0x15, 0x00, 0x33, 0x00, 0x11, 0x00, 0x34, 0x00, 0x0a, 0x00, 0x36, 0x00, 0x02, 0x00, 0x37, 0x00, 0xfb, 0xff, 0x35, 0x00, 0xf5, 0xff, 0x32, 0x00, 0xf1, 0xff, 0x2d, 0x00, 0xef, 0xff, 0x28, 0x00, 0xed, 0xff, 0x25, 0x00, 0xea, 0xff, 0x24, 0x00, 0xe7, 0xff, 0x25, 0x00, 0xe3, 0xff, 0x25, 0x00, 0xde, 0xff, 0x25, 0x00, 0xd7, 0xff, 0x22, 0x00, 0xcf, 0xff, 0x1d, 0x00, 0xc6, 0xff, 0x16, 0x00, 0xbd, 0xff, 0x10, 0x00, 0xb6, 0xff, 0x0b, 0x00, 0xb0, 0xff, 0x08, 0x00, 0xac, 0xff, 0x05, 0x00, 0xab, 0xff, 0x03, 0x00, 0xac, 0xff, 0x02, 0x00, 0xad, 0xff, 0x01, 0x00, 0xab, 0xff, 0xfd, 0xff, 0xa6, 0xff, 0xf6, 0xff, 0x9f, 0xff, 0xed, 0xff, 0x9a, 0xff, 0xe4, 0xff, 0x9a, 0xff, 0xdd, 0xff, 0x9e, 0xff, 0xd9, 0xff, 0xa7, 0xff, 0xd9, 0xff, 0xb2, 0xff, 0xdd, 0xff, 0xb9, 0xff, 0xe0, 0xff, 0xbd, 0xff, 0xe1, 0xff, 0xbf, 0xff, 0xe0, 0xff, 0xc1, 0xff, 0xdd, 0xff, 0xc4, 0xff, 0xd8, 0xff, 0xc9, 0xff, 0xd3, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xdd, 0xff, 0xd4, 0xff, 0xe8, 0xff, 0xd9, 0xff, 0xf1, 0xff, 0xde, 0xff, 0xf8, 0xff, 0xe1, 0xff, 0xfe, 0xff, 0xe1, 0xff, 0x02, 0x00, 0xde, 0xff, 0x07, 0x00, 0xdb, 0xff, 0x0c, 0x00, 0xd8, 0xff, 0x13, 0x00, 0xd8, 0xff, 0x1c, 0x00, 0xd9, 0xff, 0x24, 0x00, 0xdb, 0xff, 0x2c, 0x00, 0xdc, 0xff, 0x33, 0x00, 0xda, 0xff, 0x38, 0x00, 0xd6, 0xff, 0x3e, 0x00, 0xd1, 0xff, 0x43, 0x00, 0xcb, 0xff, 0x46, 0x00, 0xc6, 0xff, 0x46, 0x00, 0xc2, 0xff, 0x43, 0x00, 0xc1, 0xff, 0x3f, 0x00, 0xc0, 0xff, 0x3d, 0x00, 0xc2, 0xff, 0x3f, 0x00, 0xc5, 0xff, 0x44, 0x00, 0xca, 0xff, 0x49, 0x00, 0xce, 0xff, 0x4c, 0x00, 0xd1, 0xff, 0x4d, 0x00, 0xd5, 0xff, 0x4c, 0x00, 0xda, 0xff, 0x4a, 0x00, 0xe1, 0xff, 0x47, 0x00, 0xe9, 0xff, 0x45, 0x00, 0xf1, 0xff, 0x46, 0x00, 0xfb, 0xff, 0x48, 0x00, 0x04, 0x00, 0x4a, 0x00, 0x0c, 0x00, 0x4a, 0x00, 0x14, 0x00, 0x48, 0x00, 0x1a, 0x00, 0x43, 0x00, 0x1e, 0x00, 0x3d, 0x00, 0x21, 0x00, 0x36, 0x00, 0x25, 0x00, 0x30, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x32, 0x00, 0x29, 0x00, 0x38, 0x00, 0x26, 0x00, 0x3b, 0x00, 0x21, 0x00, 0x3a, 0x00, 0x1c, 0x00, 0x36, 0x00, 0x16, 0x00, 0x33, 0x00, 0x10, 0x00, 0x32, 0x00, 0x0b, 0x00, 0x34, 0x00, 0x05, 0x00, 0x37, 0x00, 0xff, 0xff, 0x3a, 0x00, 0xf9, 0xff, 0x3a, 0x00, 0xf4, 0xff, 0x37, 0x00, 0xef, 0xff, 0x30, 0x00, 0xec, 0xff, 0x29, 0x00, 0xe9, 0xff, 0x23, 0x00, 0xe6, 0xff, 0x1d, 0x00, 0xe0, 0xff, 0x19, 0x00, 0xd9, 0xff, 0x16, 0x00, 0xd3, 0xff, 0x14, 0x00, 0xcc, 0xff, 0x11, 0x00, 0xc7, 0xff, 0x0c, 0x00, 0xc5, 0xff, 0x08, 0x00, 0xc5, 0xff, 0x06, 0x00, 0xc5, 0xff, 0x04, 0x00, 0xc5, 0xff, 0x03, 0x00, 0xc5, 0xff, 0x02, 0x00, 0xc3, 0xff, 0xff, 0xff, 0xc1, 0xff, 0xfa, 0xff, 0xbe, 0xff, 0xf5, 0xff, 0xbd, 0xff, 0xf1, 0xff, 0xbe, 0xff, 0xed, 0xff, 0xc0, 0xff, 0xeb, 0xff, 0xc3, 0xff, 0xe9, 0xff, 0xc8, 0xff, 0xe8, 0xff, 0xcc, 0xff, 0xe6, 0xff, 0xcf, 0xff, 0xe3, 0xff, 0xd3, 0xff, 0xdf, 0xff, 0xd9, 0xff, 0xdd, 0xff, 0xe2, 0xff, 0xde, 0xff, 0xec, 0xff, 0xe2, 0xff, 0xf6, 0xff, 0xe5, 0xff, 0xfe, 0xff, 0xe6, 0xff, 0x03, 0x00, 0xe7, 0xff, 0x07, 0x00, 0xe8, 0xff, 0x09, 0x00, 0xe8, 0xff, 0x0b, 0x00, 0xe9, 0xff, 0x0e, 0x00, 0xee, 0xff, 0x12, 0x00, 0xf4, 0xff, 0x17, 0x00, 0xfd, 0xff, 0x1c, 0x00, 0x06, 0x00, 0x20, 0x00, 0x0e, 0x00, 0x20, 0x00, 0x13, 0x00, 0x1d, 0x00, 0x13, 0x00, 0x19, 0x00, 0x12, 0x00, 0x14, 0x00, 0x11, 0x00, 0x10, 0x00, 0x11, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x0d, 0x00, 0x1c, 0x00, 0x0c, 0x00, 0x1d, 0x00, 0x08, 0x00, 0x1b, 0x00, 0x03, 0x00, 0x18, 0x00, 0xfe, 0xff, 0x13, 0x00, 0xfb, 0xff, 0x0e, 0x00, 0xf9, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x09, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x14, 0x00, 0x09, 0x00, 0x18, 0x00, 0x08, 0x00, 0x1a, 0x00, 0x05, 0x00, 0x1b, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x1f, 0x00, 0x04, 0x00, 0x25, 0x00, 0x0b, 0x00, 0x2c, 0x00, 0x14, 0x00, 0x34, 0x00, 0x1e, 0x00, 0x3c, 0x00, 0x26, 0x00, 0x42, 0x00, 0x2c, 0x00, 0x46, 0x00, 0x30, 0x00, 0x45, 0x00, 0x32, 0x00, 0x41, 0x00, 0x34, 0x00, 0x3b, 0x00, 0x38, 0x00, 0x36, 0x00, 0x3e, 0x00, 0x32, 0x00, 0x46, 0x00, 0x2f, 0x00, 0x4b, 0x00, 0x2d, 0x00, 0x4e, 0x00, 0x2b, 0x00, 0x4e, 0x00, 0x26, 0x00, 0x4b, 0x00, 0x1f, 0x00, 0x47, 0x00, 0x16, 0x00, 0x43, 0x00, 0x0d, 0x00, 0x40, 0x00, 0x04, 0x00, 0x3c, 0x00, 0xfd, 0xff, 0x38, 0x00, 0xf9, 0xff, 0x32, 0x00, 0xf7, 0xff, 0x27, 0x00, 0xf4, 0xff, 0x19, 0x00, 0xf3, 0xff, 0x0a, 0x00, 0xf2, 0xff, 0xfe, 0xff, 0xf1, 0xff, 0xf5, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xee, 0xff, 0xed, 0xff, 0xec, 0xff, 0xea, 0xff, 0xeb, 0xff, 0xe6, 0xff, 0xeb, 0xff, 0xe1, 0xff, 0xeb, 0xff, 0xda, 0xff, 0xed, 0xff, 0xd5, 0xff, 0xf0, 0xff, 0xd3, 0xff, 0xf5, 0xff, 0xd3, 0xff, 0xf9, 0xff, 0xd4, 0xff, 0xfd, 0xff, 0xd6, 0xff, 0xff, 0xff, 0xd8, 0xff, 0xff, 0xff, 0xdb, 0xff, 0xfd, 0xff, 0xdf, 0xff, 0xfa, 0xff, 0xe1, 0xff, 0xf9, 0xff, 0xe2, 0xff, 0xf8, 0xff, 0xe1, 0xff, 0xf8, 0xff, 0xde, 0xff, 0xf9, 0xff, 0xdb, 0xff, 0xf8, 0xff, 0xd7, 0xff, 0xf5, 0xff, 0xd3, 0xff, 0xf2, 0xff, 0xd0, 0xff, 0xf1, 0xff, 0xcf, 0xff, 0xf0, 0xff, 0xcd, 0xff, 0xf1, 0xff, 0xca, 0xff, 0xf4, 0xff, 0xc6, 0xff, 0xfa, 0xff, 0xc1, 0xff, 0xff, 0xff, 0xbc, 0xff, 0x04, 0x00, 0xb7, 0xff, 0x08, 0x00, 0xb6, 0xff, 0x0c, 0x00, 0xb7, 0xff, 0x10, 0x00, 0xba, 0xff, 0x16, 0x00, 0xbe, 0xff, 0x1c, 0x00, 0xc1, 0xff, 0x1f, 0x00, 0xc2, 0xff, 0x21, 0x00, 0xc1, 0xff, 0x22, 0x00, 0xc0, 0xff, 0x22, 0x00, 0xbf, 0xff, 0x23, 0x00, 0xc0, 0xff, 0x24, 0x00, 0xc2, 0xff, 0x26, 0x00, 0xc8, 0xff, 0x28, 0x00, 0xcf, 0xff, 0x2a, 0x00, 0xd6, 0xff, 0x2b, 0x00, 0xdd, 0xff, 0x2a, 0x00, 0xe2, 0xff, 0x26, 0x00, 0xe5, 0xff, 0x21, 0x00, 0xe6, 0xff, 0x1c, 0x00, 0xe7, 0xff, 0x19, 0x00, 0xe9, 0xff, 0x16, 0x00, 0xea, 0xff, 0x12, 0x00, 0xec, 0xff, 0x0f, 0x00, 0xf1, 0xff, 0x0d, 0x00, 0xf7, 0xff, 0x0d, 0x00, 0xfe, 0xff, 0x0e, 0x00, 0x05, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x11, 0x00, 0x0d, 0x00, 0x0f, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x09, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x15, 0x00, 0x13, 0x00, 0x19, 0x00, 0x15, 0x00, 0x1b, 0x00, 0x16, 0x00, 0x1b, 0x00, 0x13, 0x00, 0x19, 0x00, 0x0f, 0x00, 0x15, 0x00, 0x0c, 0x00, 0x11, 0x00, 0x0c, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x13, 0x00, 0x10, 0x00, 0x16, 0x00, 0x0d, 0x00, 0x16, 0x00, 0x06, 0x00, 0x13, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xf6, 0xff, 0x0b, 0x00, 0xef, 0xff, 0x07, 0x00, 0xe9, 0xff, 0x05, 0x00, 0xe3, 0xff, 0x03, 0x00, 0xde, 0xff, 0x00, 0x00, 0xd9, 0xff, 0x00, 0x00, 0xd6, 0xff, 0xff, 0xff, 0xd3, 0xff, 0xff, 0xff, 0xd1, 0xff, 0xfe, 0xff, 0xd1, 0xff, 0xfc, 0xff, 0xd3, 0xff, 0xfa, 0xff, 0xd6, 0xff, 0xf7, 0xff, 0xda, 0xff, 0xf4, 0xff, 0xde, 0xff, 0xf0, 0xff, 0xe1, 0xff, 0xec, 0xff, 0xe3, 0xff, 0xe6, 0xff, 0xe5, 0xff, 0xe3, 0xff, 0xe8, 0xff, 0xe3, 0xff, 0xeb, 0xff, 0xe4, 0xff, 0xed, 0xff, 0xe6, 0xff, 0xec, 0xff, 0xe4, 0xff, 0xe9, 0xff, 0xde, 0xff, 0xe4, 0xff, 0xd8, 0xff, 0xe0, 0xff, 0xd5, 0xff, 0xdf, 0xff, 0xd4, 0xff, 0xdf, 0xff, 0xd4, 0xff, 0xde, 0xff, 0xd3, 0xff, 0xda, 0xff, 0xd3, 0xff, 0xd5, 0xff, 0xd3, 0xff, 0xce, 0xff, 0xd2, 0xff, 0xc8, 0xff, 0xd2, 0xff, 0xc2, 0xff, 0xd3, 0xff, 0xbe, 0xff, 0xd5, 0xff, 0xbb, 0xff, 0xd8, 0xff, 0xbb, 0xff, 0xde, 0xff, 0xbd, 0xff, 0xe6, 0xff, 0xc1, 0xff, 0xef, 0xff, 0xc6, 0xff, 0xf7, 0xff, 0xca, 0xff, 0xff, 0xff, 0xcd, 0xff, 0x05, 0x00, 0xd0, 0xff, 0x0d, 0x00, 0xd5, 0xff, 0x17, 0x00, 0xdd, 0xff, 0x24, 0x00, 0xe5, 0xff, 0x33, 0x00, 0xeb, 0xff, 0x41, 0x00, 0xee, 0xff, 0x4c, 0x00, 0xf1, 0xff, 0x56, 0x00, 0xf8, 0xff, 0x5e, 0x00, 0x02, 0x00, 0x66, 0x00, 0x0d, 0x00, 0x6e, 0x00, 0x14, 0x00, 0x74, 0x00, 0x15, 0x00, 0x7a, 0x00, 0x12, 0x00, 0x7f, 0x00, 0x0f, 0x00, 0x85, 0x00, 0x0e, 0x00, 0x8c, 0x00, 0x0e, 0x00, 0x91, 0x00, 0x0f, 0x00, 0x92, 0x00, 0x10, 0x00, 0x8d, 0x00, 0x0f, 0x00, 0x86, 0x00, 0x0f, 0x00, 0x7e, 0x00, 0x0d, 0x00, 0x79, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x05, 0x00, 0x76, 0x00, 0x00, 0x00, 0x76, 0x00, 0xfb, 0xff, 0x75, 0x00, 0xf7, 0xff, 0x71, 0x00, 0xf3, 0xff, 0x6a, 0x00, 0xef, 0xff, 0x5d, 0x00, 0xea, 0xff, 0x4f, 0x00, 0xe7, 0xff, 0x41, 0x00, 0xe7, 0xff, 0x37, 0x00, 0xe8, 0xff, 0x33, 0x00, 0xeb, 0xff, 0x31, 0x00, 0xec, 0xff, 0x2f, 0x00, 0xec, 0xff, 0x2b, 0x00, 0xeb, 0xff, 0x22, 0x00, 0xec, 0xff, 0x16, 0x00, 0xef, 0xff, 0x0a, 0x00, 0xf3, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xf5, 0xff, 0xf9, 0xff, 0xef, 0xff, 0xfa, 0xff, 0xec, 0xff, 0xf9, 0xff, 0xeb, 0xff, 0xf7, 0xff, 0xed, 0xff, 0xf6, 0xff, 0xef, 0xff, 0xf6, 0xff, 0xf1, 0xff, 0xf5, 0xff, 0xef, 0xff, 0xf4, 0xff, 0xec, 0xff, 0xf3, 0xff, 0xe7, 0xff, 0xef, 0xff, 0xe4, 0xff, 0xea, 0xff, 0xe2, 0xff, 0xe4, 0xff, 0xe5, 0xff, 0xdf, 0xff, 0xe9, 0xff, 0xdb, 0xff, 0xee, 0xff, 0xd8, 0xff, 0xf1, 0xff, 0xd6, 0xff, 0xf2, 0xff, 0xd4, 0xff, 0xef, 0xff, 0xd2, 0xff, 0xe7, 0xff, 0xcf, 0xff, 0xdd, 0xff, 0xcc, 0xff, 0xd3, 0xff, 0xca, 0xff, 0xcc, 0xff, 0xca, 0xff, 0xc9, 0xff, 0xcc, 0xff, 0xca, 0xff, 0xd3, 0xff, 0xce, 0xff, 0xda, 0xff, 0xd1, 0xff, 0xe2, 0xff, 0xd0, 0xff, 0xe9, 0xff, 0xcc, 0xff, 0xed, 0xff, 0xc6, 0xff, 0xf2, 0xff, 0xc1, 0xff, 0xf7, 0xff, 0xc0, 0xff, 0xfe, 0xff, 0xc2, 0xff, 0x07, 0x00, 0xc8, 0xff, 0x11, 0x00, 0xd1, 0xff, 0x1a, 0x00, 0xdb, 0xff, 0x22, 0x00, 0xe4, 0xff, 0x28, 0x00, 0xea, 0xff, 0x2d, 0x00, 0xed, 0xff, 0x30, 0x00, 0xee, 0xff, 0x32, 0x00, 0xee, 0xff, 0x35, 0x00, 0xef, 0xff, 0x39, 0x00, 0xf3, 0xff, 0x3e, 0x00, 0xfb, 0xff, 0x41, 0x00, 0x04, 0x00, 0x42, 0x00, 0x0e, 0x00, 0x3f, 0x00, 0x17, 0x00, 0x3a, 0x00, 0x1e, 0x00, 0x35, 0x00, 0x21, 0x00, 0x30, 0x00, 0x22, 0x00, 0x2d, 0x00, 0x20, 0x00, 0x2b, 0x00, 0x1f, 0x00, 0x2a, 0x00, 0x22, 0x00, 0x28, 0x00, 0x27, 0x00, 0x24, 0x00, 0x2d, 0x00, 0x20, 0x00, 0x31, 0x00, 0x1a, 0x00, 0x31, 0x00, 0x15, 0x00, 0x2d, 0x00, 0x0e, 0x00, 0x24, 0x00, 0x06, 0x00, 0x19, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xf8, 0xff, 0x08, 0x00, 0xf3, 0xff, 0x03, 0x00, 0xf1, 0xff, 0x01, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xfb, 0xff, 0xf1, 0xff, 0xf2, 0xff, 0xef, 0xff, 0xe6, 0xff, 0xec, 0xff, 0xd9, 0xff, 0xe8, 0xff, 0xce, 0xff, 0xe5, 0xff, 0xc8, 0xff, 0xe2, 0xff, 0xc7, 0xff, 0xe0, 0xff, 0xc7, 0xff, 0xe1, 0xff, 0xc8, 0xff, 0xe4, 0xff, 0xc6, 0xff, 0xe6, 0xff, 0xc1, 0xff, 0xe8, 0xff, 0xba, 0xff, 0xe8, 0xff, 0xb4, 0xff, 0xe6, 0xff, 0xb0, 0xff, 0xe2, 0xff, 0xaf, 0xff, 0xdc, 0xff, 0xae, 0xff, 0xd5, 0xff, 0xae, 0xff, 0xd1, 0xff, 0xad, 0xff, 0xcf, 0xff, 0xac, 0xff, 0xd0, 0xff, 0xaa, 0xff, 0xd2, 0xff, 0xa7, 0xff, 0xd6, 0xff, 0xa4, 0xff, 0xd9, 0xff, 0xa2, 0xff, 0xdc, 0xff, 0xa1, 0xff, 0xde, 0xff, 0xa4, 0xff, 0xe1, 0xff, 0xa9, 0xff, 0xe4, 0xff, 0xae, 0xff, 0xe8, 0xff, 0xb4, 0xff, 0xee, 0xff, 0xb9, 0xff, 0xf6, 0xff, 0xbd, 0xff, 0x00, 0x00, 0xc1, 0xff, 0x0c, 0x00, 0xc5, 0xff, 0x18, 0x00, 0xcb, 0xff, 0x21, 0x00, 0xd2, 0xff, 0x28, 0x00, 0xd9, 0xff, 0x2c, 0x00, 0xe1, 0xff, 0x2f, 0x00, 0xeb, 0xff, 0x33, 0x00, 0xf5, 0xff, 0x39, 0x00, 0xfd, 0xff, 0x41, 0x00, 0x04, 0x00, 0x49, 0x00, 0x08, 0x00, 0x50, 0x00, 0x0b, 0x00, 0x55, 0x00, 0x0f, 0x00, 0x58, 0x00, 0x16, 0x00, 0x5a, 0x00, 0x20, 0x00, 0x5d, 0x00, 0x2c, 0x00, 0x5f, 0x00, 0x35, 0x00, 0x62, 0x00, 0x3c, 0x00, 0x66, 0x00, 0x3f, 0x00, 0x6a, 0x00, 0x41, 0x00, 0x6d, 0x00, 0x41, 0x00, 0x6d, 0x00, 0x40, 0x00, 0x6b, 0x00, 0x40, 0x00, 0x6a, 0x00, 0x40, 0x00, 0x6a, 0x00, 0x40, 0x00, 0x6c, 0x00, 0x40, 0x00, 0x6d, 0x00, 0x3f, 0x00, 0x6e, 0x00, 0x3e, 0x00, 0x6d, 0x00, 0x3c, 0x00, 0x69, 0x00, 0x39, 0x00, 0x65, 0x00, 0x35, 0x00, 0x62, 0x00, 0x30, 0x00, 0x5e, 0x00, 0x2b, 0x00, 0x5c, 0x00, 0x26, 0x00, 0x5b, 0x00, 0x22, 0x00, 0x5c, 0x00, 0x20, 0x00, 0x5d, 0x00, 0x21, 0x00, 0x5e, 0x00, 0x24, 0x00, 0x5f, 0x00, 0x29, 0x00, 0x5e, 0x00, 0x2e, 0x00, 0x5d, 0x00, 0x31, 0x00, 0x5b, 0x00, 0x32, 0x00, 0x58, 0x00, 0x32, 0x00, 0x53, 0x00, 0x30, 0x00, 0x4b, 0x00, 0x2e, 0x00, 0x43, 0x00, 0x2d, 0x00, 0x3a, 0x00, 0x2d, 0x00, 0x33, 0x00, 0x2e, 0x00, 0x2b, 0x00, 0x2e, 0x00, 0x22, 0x00, 0x2d, 0x00, 0x17, 0x00, 0x2a, 0x00, 0x0a, 0x00, 0x25, 0x00, 0xfd, 0xff, 0x1f, 0x00, 0xef, 0xff, 0x16, 0x00, 0xe3, 0xff, 0x0f, 0x00, 0xd8, 0xff, 0x09, 0x00, 0xce, 0xff, 0x05, 0x00, 0xc5, 0xff, 0x02, 0x00, 0xbb, 0xff, 0xff, 0xff, 0xb1, 0xff, 0xfb, 0xff, 0xa8, 0xff, 0xf4, 0xff, 0x9f, 0xff, 0xec, 0xff, 0x99, 0xff, 0xe5, 0xff, 0x97, 0xff, 0xe0, 0xff, 0x96, 0xff, 0xde, 0xff, 0x96, 0xff, 0xdd, 0xff, 0x97, 0xff, 0xdd, 0xff, 0x97, 0xff, 0xdd, 0xff, 0x98, 0xff, 0xdb, 0xff, 0x99, 0xff, 0xd9, 0xff, 0x9c, 0xff, 0xd5, 0xff, 0xa0, 0xff, 0xd0, 0xff, 0xa4, 0xff, 0xcd, 0xff, 0xa9, 0xff, 0xcd, 0xff, 0xb0, 0xff, 0xcd, 0xff, 0xb7, 0xff, 0xcf, 0xff, 0xbf, 0xff, 0xd2, 0xff, 0xc8, 0xff, 0xd6, 0xff, 0xd1, 0xff, 0xda, 0xff, 0xda, 0xff, 0xdf, 0xff, 0xe1, 0xff, 0xe3, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xe8, 0xff, 0xea, 0xff, 0xe9, 0xff, 0xed, 0xff, 0xeb, 0xff, 0xef, 0xff, 0xee, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xf2, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf6, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xfb, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xf5, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x05, 0x00, 0xf5, 0xff, 0x08, 0x00, 0xf5, 0xff, 0x0c, 0x00, 0xf6, 0xff, 0x12, 0x00, 0xf8, 0xff, 0x16, 0x00, 0xf9, 0xff, 0x19, 0x00, 0xfb, 0xff, 0x1b, 0x00, 0xfd, 0xff, 0x1b, 0x00, 0xff, 0xff, 0x1b, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x1e, 0x00, 0x02, 0x00, 0x1f, 0x00, 0x05, 0x00, 0x1f, 0x00, 0x08, 0x00, 0x1e, 0x00, 0x0c, 0x00, 0x1c, 0x00, 0x0f, 0x00, 0x18, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x08, 0x00, 0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xf6, 0xff, 0xfd, 0xff, 0xf2, 0xff, 0xf6, 0xff, 0xf0, 0xff, 0xef, 0xff, 0xef, 0xff, 0xea, 0xff, 0xf0, 0xff, 0xe7, 0xff, 0xf0, 0xff, 0xe7, 0xff, 0xef, 0xff, 0xe6, 0xff, 0xed, 0xff, 0xe4, 0xff, 0xe9, 0xff, 0xdf, 0xff, 0xe3, 0xff, 0xd9, 0xff, 0xdc, 0xff, 0xd2, 0xff, 0xd4, 0xff, 0xce, 0xff, 0xd0, 0xff, 0xcd, 0xff, 0xcd, 0xff, 0xcf, 0xff, 0xcd, 0xff, 0xd4, 0xff, 0xce, 0xff, 0xd7, 0xff, 0xcf, 0xff, 0xd8, 0xff, 0xcf, 0xff, 0xd6, 0xff, 0xcc, 0xff, 0xd1, 0xff, 0xc7, 0xff, 0xcc, 0xff, 0xc2, 0xff, 0xcb, 0xff, 0xbf, 0xff, 0xcd, 0xff, 0xc0, 0xff, 0xd0, 0xff, 0xc6, 0xff, 0xd3, 0xff, 0xcf, 0xff, 0xd4, 0xff, 0xda, 0xff, 0xd3, 0xff, 0xe2, 0xff, 0xd3, 0xff, 0xe7, 0xff, 0xd2, 0xff, 0xe8, 0xff, 0xd3, 0xff, 0xe8, 0xff, 0xd5, 0xff, 0xe7, 0xff, 0xd6, 0xff, 0xe8, 0xff, 0xd8, 0xff, 0xed, 0xff, 0xd9, 0xff, 0xf3, 0xff, 0xda, 0xff, 0xfa, 0xff, 0xdb, 0xff, 0xfe, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xfe, 0xff, 0xe5, 0xff, 0xfc, 0xff, 0xea, 0xff, 0xfc, 0xff, 0xed, 0xff, 0xff, 0xff, 0xee, 0xff, 0x02, 0x00, 0xf0, 0xff, 0x06, 0x00, 0xf3, 0xff, 0x09, 0x00, 0xf8, 0xff, 0x0d, 0x00, 0xfe, 0xff, 0x12, 0x00, 0x04, 0x00, 0x17, 0x00, 0x08, 0x00, 0x1d, 0x00, 0x0b, 0x00, 0x23, 0x00, 0x0c, 0x00, 0x29, 0x00, 0x0c, 0x00, 0x2c, 0x00, 0x0e, 0x00, 0x2e, 0x00, 0x13, 0x00, 0x2e, 0x00, 0x1a, 0x00, 0x2e, 0x00, 0x23, 0x00, 0x2f, 0x00, 0x2a, 0x00, 0x32, 0x00, 0x2f, 0x00, 0x36, 0x00, 0x31, 0x00, 0x3a, 0x00, 0x33, 0x00, 0x3b, 0x00, 0x36, 0x00, 0x38, 0x00, 0x3b, 0x00, 0x33, 0x00, 0x42, 0x00, 0x2d, 0x00, 0x49, 0x00, 0x29, 0x00, 0x4f, 0x00, 0x26, 0x00, 0x54, 0x00, 0x24, 0x00, 0x57, 0x00, 0x22, 0x00, 0x5a, 0x00, 0x20, 0x00, 0x5b, 0x00, 0x1d, 0x00, 0x5c, 0x00, 0x1b, 0x00, 0x5d, 0x00, 0x19, 0x00, 0x5d, 0x00, 0x15, 0x00, 0x5c, 0x00, 0x11, 0x00, 0x58, 0x00, 0x0d, 0x00, 0x54, 0x00, 0x08, 0x00, 0x50, 0x00, 0x04, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x4c, 0x00, 0xfd, 0xff, 0x4a, 0x00, 0xfa, 0xff, 0x46, 0x00, 0xf8, 0xff, 0x3f, 0x00, 0xf5, 0xff, 0x36, 0x00, 0xf1, 0xff, 0x2d, 0x00, 0xeb, 0xff, 0x25, 0x00, 0xe5, 0xff, 0x1e, 0x00, 0xdf, 0xff, 0x18, 0x00, 0xdb, 0xff, 0x12, 0x00, 0xd8, 0xff, 0x0a, 0x00, 0xd7, 0xff, 0x01, 0x00, 0xd6, 0xff, 0xf7, 0xff, 0xd5, 0xff, 0xef, 0xff, 0xd2, 0xff, 0xe9, 0xff, 0xce, 0xff, 0xe5, 0xff, 0xcb, 0xff, 0xe4, 0xff, 0xc9, 0xff, 0xe1, 0xff, 0xc9, 0xff, 0xdb, 0xff, 0xca, 0xff, 0xd1, 0xff, 0xcc, 0xff, 0xc6, 0xff, 0xcd, 0xff, 0xbd, 0xff, 0xce, 0xff, 0xb7, 0xff, 0xce, 0xff, 0xb4, 0xff, 0xcd, 0xff, 0xb5, 0xff, 0xce, 0xff, 0xb7, 0xff, 0xd1, 0xff, 0xb8, 0xff, 0xd6, 0xff, 0xb7, 0xff, 0xdb, 0xff, 0xb4, 0xff, 0xe1, 0xff, 0xb0, 0xff, 0xe5, 0xff, 0xaf, 0xff, 0xe8, 0xff, 0xb2, 0xff, 0xeb, 0xff, 0xb9, 0xff, 0xef, 0xff, 0xc1, 0xff, 0xf4, 0xff, 0xc7, 0xff, 0xfc, 0xff, 0xcb, 0xff, 0x05, 0x00, 0xce, 0xff, 0x0e, 0x00, 0xd1, 0xff, 0x15, 0x00, 0xd4, 0xff, 0x18, 0x00, 0xda, 0xff, 0x18, 0x00, 0xe1, 0xff, 0x19, 0x00, 0xe9, 0xff, 0x1a, 0x00, 0xf2, 0xff, 0x1c, 0x00, 0xfc, 0xff, 0x1d, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x0c, 0x00, 0x1e, 0x00, 0x12, 0x00, 0x1c, 0x00, 0x17, 0x00, 0x1a, 0x00, 0x1c, 0x00, 0x18, 0x00, 0x21, 0x00, 0x15, 0x00, 0x25, 0x00, 0x13, 0x00, 0x28, 0x00, 0x10, 0x00, 0x2c, 0x00, 0x0e, 0x00, 0x30, 0x00, 0x0b, 0x00, 0x33, 0x00, 0x09, 0x00, 0x36, 0x00, 0x07, 0x00, 0x36, 0x00, 0x07, 0x00, 0x33, 0x00, 0x0a, 0x00, 0x2d, 0x00, 0x0d, 0x00, 0x27, 0x00, 0x11, 0x00, 0x21, 0x00, 0x14, 0x00, 0x1c, 0x00, 0x17, 0x00, 0x18, 0x00, 0x18, 0x00, 0x16, 0x00, 0x1b, 0x00, 0x13, 0x00, 0x21, 0x00, 0x0f, 0x00, 0x28, 0x00, 0x07, 0x00, 0x30, 0x00, 0xfe, 0xff, 0x37, 0x00, 0xf6, 0xff, 0x3c, 0x00, 0xf1, 0xff, 0x3d, 0x00, 0xee, 0xff, 0x3b, 0x00, 0xed, 0xff, 0x38, 0x00, 0xec, 0xff, 0x36, 0x00, 0xec, 0xff, 0x37, 0x00, 0xe9, 0xff, 0x3b, 0x00, 0xe5, 0xff, 0x41, 0x00, 0xdf, 0xff, 0x45, 0x00, 0xda, 0xff, 0x47, 0x00, 0xd5, 0xff, 0x45, 0x00, 0xd3, 0xff, 0x40, 0x00, 0xd3, 0xff, 0x3a, 0x00, 0xd3, 0xff, 0x35, 0x00, 0xd2, 0xff, 0x32, 0x00, 0xd0, 0xff, 0x30, 0x00, 0xcc, 0xff, 0x31, 0x00, 0xc6, 0xff, 0x32, 0x00, 0xc1, 0xff, 0x31, 0x00, 0xbd, 0xff, 0x2d, 0x00, 0xbc, 0xff, 0x27, 0x00, 0xbc, 0xff, 0x20, 0x00, 0xbf, 0xff, 0x18, 0x00, 0xc2, 0xff, 0x12, 0x00, 0xc5, 0xff, 0x0d, 0x00, 0xc6, 0xff, 0x09, 0x00, 0xc5, 0xff, 0x08, 0x00, 0xc3, 0xff, 0x07, 0x00, 0xc2, 0xff, 0x06, 0x00, 0xc2, 0xff, 0x04, 0x00, 0xc4, 0xff, 0x01, 0x00, 0xc9, 0xff, 0xfd, 0xff, 0xcf, 0xff, 0xf9, 0xff, 0xd4, 0xff, 0xf6, 0xff, 0xd9, 0xff, 0xf7, 0xff, 0xdb, 0xff, 0xfb, 0xff, 0xdc, 0xff, 0x01, 0x00, 0xdd, 0xff, 0x08, 0x00, 0xe0, 0xff, 0x0d, 0x00, 0xe4, 0xff, 0x0e, 0x00, 0xeb, 0xff, 0x0d, 0x00, 0xf4, 0xff, 0x09, 0x00, 0xfc, 0xff, 0x06, 0x00, 0x03, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0x13, 0x00, 0x0a, 0x00, 0x19, 0x00, 0x06, 0x00, 0x1f, 0x00, 0x02, 0x00, 0x25, 0x00, 0xff, 0xff, 0x29, 0x00, 0xfc, 0xff, 0x2c, 0x00, 0xf8, 0xff, 0x2e, 0x00, 0xf5, 0xff, 0x30, 0x00, 0xf2, 0xff, 0x33, 0x00, 0xee, 0xff, 0x37, 0x00, 0xeb, 0xff, 0x3c, 0x00, 0xe9, 0xff, 0x41, 0x00, 0xe9, 0xff, 0x44, 0x00, 0xea, 0xff, 0x46, 0x00, 0xe9, 0xff, 0x46, 0x00, 0xe6, 0xff, 0x45, 0x00, 0xe1, 0xff, 0x45, 0x00, 0xdb, 0xff, 0x44, 0x00, 0xd7, 0xff, 0x43, 0x00, 0xd5, 0xff, 0x44, 0x00, 0xd6, 0xff, 0x46, 0x00, 0xd8, 0xff, 0x48, 0x00, 0xdb, 0xff, 0x4a, 0x00, 0xdc, 0xff, 0x49, 0x00, 0xdb, 0xff, 0x46, 0x00, 0xd9, 0xff, 0x41, 0x00, 0xd7, 0xff, 0x3c, 0x00, 0xd6, 0xff, 0x37, 0x00, 0xd7, 0xff, 0x34, 0x00, 0xda, 0xff, 0x31, 0x00, 0xdc, 0xff, 0x30, 0x00, 0xde, 0xff, 0x2e, 0x00, 0xdf, 0xff, 0x2c, 0x00, 0xde, 0xff, 0x2a, 0x00, 0xdd, 0xff, 0x27, 0x00, 0xdc, 0xff, 0x23, 0x00, 0xdc, 0xff, 0x1e, 0x00, 0xdc, 0xff, 0x18, 0x00, 0xdc, 0xff, 0x13, 0x00, 0xdc, 0xff, 0x0e, 0x00, 0xdb, 0xff, 0x09, 0x00, 0xda, 0xff, 0x04, 0x00, 0xdb, 0xff, 0xff, 0xff, 0xdb, 0xff, 0xfa, 0xff, 0xdc, 0xff, 0xf7, 0xff, 0xdb, 0xff, 0xf4, 0xff, 0xd9, 0xff, 0xf2, 0xff, 0xd8, 0xff, 0xf0, 0xff, 0xd7, 0xff, 0xef, 0xff, 0xd7, 0xff, 0xef, 0xff, 0xda, 0xff, 0xef, 0xff, 0xde, 0xff, 0xef, 0xff, 0xe3, 0xff, 0xee, 0xff, 0xe7, 0xff, 0xec, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0xec, 0xff, 0xeb, 0xff, 0xee, 0xff, 0xed, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xf5, 0xff, 0xf4, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0x02, 0x00, 0xff, 0xff, 0x08, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x05, 0x00, 0x12, 0x00, 0x05, 0x00, 0x15, 0x00, 0x04, 0x00, 0x19, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x06, 0x00, 0x1e, 0x00, 0x09, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x1b, 0x00, 0x14, 0x00, 0x18, 0x00, 0x1a, 0x00, 0x15, 0x00, 0x1e, 0x00, 0x12, 0x00, 0x21, 0x00, 0x10, 0x00, 0x20, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x0c, 0x00, 0x1d, 0x00, 0x09, 0x00, 0x1f, 0x00, 0x04, 0x00, 0x22, 0x00, 0xff, 0xff, 0x26, 0x00, 0xf9, 0xff, 0x2a, 0x00, 0xf5, 0xff, 0x2e, 0x00, 0xf3, 0xff, 0x31, 0x00, 0xf2, 0xff, 0x33, 0x00, 0xf2, 0xff, 0x33, 0x00, 0xf2, 0xff, 0x31, 0x00, 0xf2, 0xff, 0x2f, 0x00, 0xf2, 0xff, 0x2f, 0x00, 0xf3, 0xff, 0x30, 0x00, 0xf4, 0xff, 0x32, 0x00, 0xf5, 0xff, 0x33, 0x00, 0xf5, 0xff, 0x33, 0x00, 0xf5, 0xff, 0x2f, 0x00, 0xf4, 0xff, 0x29, 0x00, 0xf4, 0xff, 0x1f, 0x00, 0xf5, 0xff, 0x14, 0x00, 0xf7, 0xff, 0x0b, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfb, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf1, 0xff, 0xfd, 0xff, 0xe6, 0xff, 0xff, 0xff, 0xdb, 0xff, 0x03, 0x00, 0xd0, 0xff, 0x08, 0x00, 0xc8, 0xff, 0x0e, 0x00, 0xc1, 0xff, 0x13, 0x00, 0xbc, 0xff, 0x16, 0x00, 0xb9, 0xff, 0x17, 0x00, 0xb7, 0xff, 0x16, 0x00, 0xb3, 0xff, 0x15, 0x00, 0xaf, 0xff, 0x16, 0x00, 0xaa, 0xff, 0x17, 0x00, 0xa8, 0xff, 0x1a, 0x00, 0xa8, 0xff, 0x1d, 0x00, 0xab, 0xff, 0x1d, 0x00, 0xb0, 0xff, 0x1c, 0x00, 0xb3, 0xff, 0x1a, 0x00, 0xb3, 0xff, 0x18, 0x00, 0xb1, 0xff, 0x17, 0x00, 0xb0, 0xff, 0x17, 0x00, 0xb0, 0xff, 0x17, 0x00, 0xb3, 0xff, 0x18, 0x00, 0xb5, 0xff, 0x1a, 0x00, 0xb7, 0xff, 0x1c, 0x00, 0xb6, 0xff, 0x20, 0x00, 0xb5, 0xff, 0x23, 0x00, 0xb3, 0xff, 0x27, 0x00, 0xb1, 0xff, 0x29, 0x00, 0xb0, 0xff, 0x2b, 0x00, 0xb1, 0xff, 0x2c, 0x00, 0xb5, 0xff, 0x2e, 0x00, 0xb9, 0xff, 0x2f, 0x00, 0xbe, 0xff, 0x32, 0x00, 0xc0, 0xff, 0x35, 0x00, 0xc2, 0xff, 0x3a, 0x00, 0xc3, 0xff, 0x3f, 0x00, 0xc5, 0xff, 0x43, 0x00, 0xca, 0xff, 0x43, 0x00, 0xd2, 0xff, 0x3e, 0x00, 0xdb, 0xff, 0x37, 0x00, 0xe6, 0xff, 0x30, 0x00, 0xf1, 0xff, 0x2a, 0x00, 0xfc, 0xff, 0x26, 0x00, 0x06, 0x00, 0x23, 0x00, 0x10, 0x00, 0x20, 0x00, 0x1a, 0x00, 0x1c, 0x00, 0x25, 0x00, 0x17, 0x00, 0x31, 0x00, 0x10, 0x00, 0x3d, 0x00, 0x08, 0x00, 0x49, 0x00, 0xff, 0xff, 0x53, 0x00, 0xf8, 0xff, 0x5c, 0x00, 0xf1, 0xff, 0x64, 0x00, 0xed, 0xff, 0x6b, 0x00, 0xea, 0xff, 0x71, 0x00, 0xe6, 0xff, 0x74, 0x00, 0xe1, 0xff, 0x75, 0x00, 0xdb, 0xff, 0x75, 0x00, 0xd6, 0xff, 0x75, 0x00, 0xd2, 0xff, 0x77, 0x00, 0xce, 0xff, 0x79, 0x00, 0xcb, 0xff, 0x7a, 0x00, 0xc9, 0xff, 0x77, 0x00, 0xc8, 0xff, 0x72, 0x00, 0xc9, 0xff, 0x6b, 0x00, 0xcc, 0xff, 0x63, 0x00, 0xd0, 0xff, 0x5b, 0x00, 0xd3, 0xff, 0x54, 0x00, 0xd5, 0xff, 0x4e, 0x00, 0xd6, 0xff, 0x49, 0x00, 0xd5, 0xff, 0x45, 0x00, 0xd3, 0xff, 0x3f, 0x00, 0xd3, 0xff, 0x35, 0x00, 0xd5, 0xff, 0x2a, 0x00, 0xd8, 0xff, 0x1f, 0x00, 0xdc, 0xff, 0x17, 0x00, 0xe0, 0xff, 0x13, 0x00, 0xe2, 0xff, 0x11, 0x00, 0xe1, 0xff, 0x0e, 0x00, 0xe0, 0xff, 0x08, 0x00, 0xde, 0xff, 0x00, 0x00, 0xde, 0xff, 0xf6, 0xff, 0xe0, 0xff, 0xed, 0xff, 0xe3, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xe5, 0xff, 0xeb, 0xff, 0xe4, 0xff, 0xef, 0xff, 0xe4, 0xff, 0xf3, 0xff, 0xe2, 0xff, 0xf5, 0xff, 0xdc, 0xff, 0xf7, 0xff, 0xd3, 0xff, 0xf9, 0xff, 0xc9, 0xff, 0xfc, 0xff, 0xbf, 0xff, 0x01, 0x00, 0xb8, 0xff, 0x06, 0x00, 0xb5, 0xff, 0x0a, 0x00, 0xb4, 0xff, 0x0d, 0x00, 0xb5, 0xff, 0x10, 0x00, 0xb6, 0xff, 0x12, 0x00, 0xb5, 0xff, 0x13, 0x00, 0xb3, 0xff, 0x14, 0x00, 0xaf, 0xff, 0x14, 0x00, 0xaa, 0xff, 0x15, 0x00, 0xa5, 0xff, 0x14, 0x00, 0xa2, 0xff, 0x14, 0x00, 0xa2, 0xff, 0x12, 0x00, 0xa4, 0xff, 0x11, 0x00, 0xa8, 0xff, 0x10, 0x00, 0xad, 0xff, 0x0e, 0x00, 0xb4, 0xff, 0x0b, 0x00, 0xba, 0xff, 0x08, 0x00, 0xbe, 0xff, 0x03, 0x00, 0xbf, 0xff, 0xff, 0xff, 0xbe, 0xff, 0xfc, 0xff, 0xbe, 0xff, 0xfb, 0xff, 0xc0, 0xff, 0xfa, 0xff, 0xc7, 0xff, 0xf8, 0xff, 0xd2, 0xff, 0xf4, 0xff, 0xdf, 0xff, 0xef, 0xff, 0xe9, 0xff, 0xea, 0xff, 0xf0, 0xff, 0xe5, 0xff, 0xf1, 0xff, 0xe2, 0xff, 0xf1, 0xff, 0xe2, 0xff, 0xf2, 0xff, 0xe3, 0xff, 0xf7, 0xff, 0xe5, 0xff, 0x01, 0x00, 0xe6, 0xff, 0x0f, 0x00, 0xe5, 0xff, 0x1d, 0x00, 0xe2, 0xff, 0x28, 0x00, 0xdf, 0xff, 0x2f, 0x00, 0xdd, 0xff, 0x32, 0x00, 0xdd, 0xff, 0x31, 0x00, 0xde, 0xff, 0x31, 0x00, 0xe0, 0xff, 0x33, 0x00, 0xe0, 0xff, 0x39, 0x00, 0xde, 0xff, 0x42, 0x00, 0xda, 0xff, 0x4a, 0x00, 0xd5, 0xff, 0x4f, 0x00, 0xd2, 0xff, 0x4f, 0x00, 0xd0, 0xff, 0x4b, 0x00, 0xd0, 0xff, 0x46, 0x00, 0xd2, 0xff, 0x42, 0x00, 0xd3, 0xff, 0x41, 0x00, 0xd4, 0xff, 0x41, 0x00, 0xd4, 0xff, 0x41, 0x00, 0xd4, 0xff, 0x41, 0x00, 0xd5, 0xff, 0x3f, 0x00, 0xd8, 0xff, 0x3c, 0x00, 0xdc, 0xff, 0x37, 0x00, 0xe1, 0xff, 0x32, 0x00, 0xe6, 0xff, 0x2d, 0x00, 0xeb, 0xff, 0x27, 0x00, 0xf1, 0xff, 0x22, 0x00, 0xf9, 0xff, 0x1c, 0x00, 0x00, 0x00, 0x17, 0x00, 0x07, 0x00, 0x13, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x11, 0x00, 0x09, 0x00, 0x14, 0x00, 0x02, 0x00, 0x16, 0x00, 0xf9, 0xff, 0x17, 0x00, 0xee, 0xff, 0x19, 0x00, 0xe2, 0xff, 0x1d, 0x00, 0xd7, 0xff, 0x24, 0x00, 0xce, 0xff, 0x2b, 0x00, 0xc7, 0xff, 0x2f, 0x00, 0xc4, 0xff, 0x30, 0x00, 0xc3, 0xff, 0x2f, 0x00, 0xc1, 0xff, 0x2d, 0x00, 0xbd, 0xff, 0x2b, 0x00, 0xb7, 0xff, 0x2a, 0x00, 0xae, 0xff, 0x2b, 0x00, 0xa7, 0xff, 0x2d, 0x00, 0xa4, 0xff, 0x2f, 0x00, 0xa6, 0xff, 0x31, 0x00, 0xac, 0xff, 0x31, 0x00, 0xb4, 0xff, 0x30, 0x00, 0xb9, 0xff, 0x2f, 0x00, 0xbb, 0xff, 0x2c, 0x00, 0xba, 0xff, 0x29, 0x00, 0xb9, 0xff, 0x24, 0x00, 0xb9, 0xff, 0x1e, 0x00, 0xbb, 0xff, 0x18, 0x00, 0xc1, 0xff, 0x12, 0x00, 0xc8, 0xff, 0x0d, 0x00, 0xd1, 0xff, 0x0a, 0x00, 0xd8, 0xff, 0x08, 0x00, 0xdd, 0xff, 0x05, 0x00, 0xdf, 0xff, 0x01, 0x00, 0xe0, 0xff, 0xfb, 0xff, 0xe1, 0xff, 0xf5, 0xff, 0xe5, 0xff, 0xf0, 0xff, 0xed, 0xff, 0xee, 0xff, 0xf7, 0xff, 0xed, 0xff, 0x02, 0x00, 0xf0, 0xff, 0x0c, 0x00, 0xf3, 0xff, 0x14, 0x00, 0xf6, 0xff, 0x1a, 0x00, 0xf7, 0xff, 0x1e, 0x00, 0xf5, 0xff, 0x22, 0x00, 0xf1, 0xff, 0x28, 0x00, 0xed, 0xff, 0x2f, 0x00, 0xeb, 0xff, 0x38, 0x00, 0xec, 0xff, 0x41, 0x00, 0xf1, 0xff, 0x4a, 0x00, 0xf8, 0xff, 0x52, 0x00, 0xfe, 0xff, 0x58, 0x00, 0x02, 0x00, 0x5c, 0x00, 0x03, 0x00, 0x5e, 0x00, 0x03, 0x00, 0x5f, 0x00, 0x01, 0x00, 0x61, 0x00, 0xff, 0xff, 0x64, 0x00, 0xff, 0xff, 0x69, 0x00, 0x01, 0x00, 0x70, 0x00, 0x06, 0x00, 0x76, 0x00, 0x0d, 0x00, 0x7a, 0x00, 0x14, 0x00, 0x7a, 0x00, 0x1b, 0x00, 0x75, 0x00, 0x20, 0x00, 0x6d, 0x00, 0x23, 0x00, 0x65, 0x00, 0x25, 0x00, 0x5f, 0x00, 0x26, 0x00, 0x5c, 0x00, 0x28, 0x00, 0x5b, 0x00, 0x2b, 0x00, 0x5a, 0x00, 0x2e, 0x00, 0x57, 0x00, 0x31, 0x00, 0x52, 0x00, 0x33, 0x00, 0x48, 0x00, 0x32, 0x00, 0x3b, 0x00, 0x2f, 0x00, 0x2d, 0x00, 0x2a, 0x00, 0x21, 0x00, 0x24, 0x00, 0x18, 0x00, 0x1e, 0x00, 0x13, 0x00, 0x1b, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x08, 0x00, 0x17, 0x00, 0x01, 0x00, 0x17, 0x00, 0xf7, 0xff, 0x17, 0x00, 0xeb, 0xff, 0x16, 0x00, 0xdf, 0xff, 0x13, 0x00, 0xd2, 0xff, 0x11, 0x00, 0xc8, 0xff, 0x11, 0x00, 0xbf, 0xff, 0x15, 0x00, 0xb7, 0xff, 0x1b, 0x00, 0xb1, 0xff, 0x20, 0x00, 0xac, 0xff, 0x24, 0x00, 0xa8, 0xff, 0x25, 0x00, 0xa4, 0xff, 0x24, 0x00, 0x9e, 0xff, 0x22, 0x00, 0x98, 0xff, 0x1f, 0x00, 0x90, 0xff, 0x1c, 0x00, 0x89, 0xff, 0x19, 0x00, 0x84, 0xff, 0x16, 0x00, 0x82, 0xff, 0x13, 0x00, 0x84, 0xff, 0x0f, 0x00, 0x88, 0xff, 0x0a, 0x00, 0x8d, 0xff, 0x04, 0x00, 0x90, 0xff, 0xfe, 0xff, 0x92, 0xff, 0xf7, 0xff, 0x92, 0xff, 0xf0, 0xff, 0x92, 0xff, 0xe9, 0xff, 0x94, 0xff, 0xe3, 0xff, 0x98, 0xff, 0xdf, 0xff, 0xa1, 0xff, 0xdb, 0xff, 0xab, 0xff, 0xd7, 0xff, 0xb7, 0xff, 0xd1, 0xff, 0xc1, 0xff, 0xcb, 0xff, 0xc7, 0xff, 0xc5, 0xff, 0xcc, 0xff, 0xbf, 0xff, 0xd0, 0xff, 0xba, 0xff, 0xd5, 0xff, 0xb8, 0xff, 0xdd, 0xff, 0xb8, 0xff, 0xe6, 0xff, 0xbb, 0xff, 0xf0, 0xff, 0xbd, 0xff, 0xfb, 0xff, 0xbd, 0xff, 0x04, 0x00, 0xbd, 0xff, 0x0d, 0x00, 0xbb, 0xff, 0x16, 0x00, 0xbb, 0xff, 0x1e, 0x00, 0xbd, 0xff, 0x27, 0x00, 0xc1, 0xff, 0x31, 0x00, 0xc7, 0xff, 0x3b, 0x00, 0xcf, 0xff, 0x43, 0x00, 0xd6, 0xff, 0x4b, 0x00, 0xdc, 0xff, 0x52, 0x00, 0xe1, 0xff, 0x5a, 0x00, 0xe4, 0xff, 0x63, 0x00, 0xe7, 0xff, 0x6b, 0x00, 0xea, 0xff, 0x70, 0x00, 0xed, 0xff, 0x72, 0x00, 0xef, 0xff, 0x71, 0x00, 0xee, 0xff, 0x6f, 0x00, 0xed, 0xff, 0x6d, 0x00, 0xec, 0xff, 0x6b, 0x00, 0xeb, 0xff, 0x68, 0x00, 0xea, 0xff, 0x64, 0x00, 0xea, 0xff, 0x60, 0x00, 0xea, 0xff, 0x5a, 0x00, 0xea, 0xff, 0x51, 0x00, 0xe9, 0xff, 0x46, 0x00, 0xe9, 0xff, 0x3b, 0x00, 0xe9, 0xff, 0x32, 0x00, 0xed, 0xff, 0x2a, 0x00, 0xf5, 0xff, 0x23, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x0b, 0x00, 0x19, 0x00, 0x14, 0x00, 0x13, 0x00, 0x1a, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x09, 0x00, 0x1c, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x02, 0x00, 0x22, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x32, 0x00, 0xff, 0xff, 0x38, 0x00, 0xfc, 0xff, 0x3b, 0x00, 0xfa, 0xff, 0x39, 0x00, 0xf7, 0xff, 0x36, 0x00, 0xf4, 0xff, 0x31, 0x00, 0xf2, 0xff, 0x2d, 0x00, 0xf1, 0xff, 0x29, 0x00, 0xef, 0xff, 0x26, 0x00, 0xed, 0xff, 0x25, 0x00, 0xea, 0xff, 0x24, 0x00, 0xe6, 0xff, 0x23, 0x00, 0xe3, 0xff, 0x21, 0x00, 0xdf, 0xff, 0x1f, 0x00, 0xda, 0xff, 0x1c, 0x00, 0xd6, 0xff, 0x18, 0x00, 0xd1, 0xff, 0x12, 0x00, 0xcc, 0xff, 0x0c, 0x00, 0xc8, 0xff, 0x05, 0x00, 0xc5, 0xff, 0x00, 0x00, 0xc2, 0xff, 0xfe, 0xff, 0xc0, 0xff, 0xfe, 0xff, 0xbe, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xfd, 0xff, 0xb7, 0xff, 0xf8, 0xff, 0xb4, 0xff, 0xf1, 0xff, 0xb2, 0xff, 0xe7, 0xff, 0xb4, 0xff, 0xde, 0xff, 0xb8, 0xff, 0xd8, 0xff, 0xbe, 0xff, 0xd6, 0xff, 0xc4, 0xff, 0xd9, 0xff, 0xc8, 0xff, 0xde, 0xff, 0xcb, 0xff, 0xe1, 0xff, 0xcc, 0xff, 0xe0, 0xff, 0xcd, 0xff, 0xdb, 0xff, 0xd0, 0xff, 0xd7, 0xff, 0xd5, 0xff, 0xd4, 0xff, 0xde, 0xff, 0xd4, 0xff, 0xe9, 0xff, 0xd8, 0xff, 0xf5, 0xff, 0xdd, 0xff, 0x00, 0x00, 0xe2, 0xff, 0x09, 0x00, 0xe5, 0xff, 0x0f, 0x00, 0xe6, 0xff, 0x15, 0x00, 0xe6, 0xff, 0x1a, 0x00, 0xe6, 0xff, 0x20, 0x00, 0xe5, 0xff, 0x27, 0x00, 0xe5, 0xff, 0x2f, 0x00, 0xe7, 0xff, 0x37, 0x00, 0xeb, 0xff, 0x3f, 0x00, 0xef, 0xff, 0x45, 0x00, 0xf2, 0xff, 0x49, 0x00, 0xf6, 0xff, 0x4b, 0x00, 0xf8, 0xff, 0x4c, 0x00, 0xfb, 0xff, 0x4d, 0x00, 0xfe, 0xff, 0x4e, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x02, 0x00, 0x4f, 0x00, 0x04, 0x00, 0x4e, 0x00, 0x07, 0x00, 0x4b, 0x00, 0x0b, 0x00, 0x47, 0x00, 0x10, 0x00, 0x43, 0x00, 0x15, 0x00, 0x3d, 0x00, 0x18, 0x00, 0x36, 0x00, 0x19, 0x00, 0x2f, 0x00, 0x18, 0x00, 0x29, 0x00, 0x17, 0x00, 0x22, 0x00, 0x17, 0x00, 0x1c, 0x00, 0x19, 0x00, 0x16, 0x00, 0x1d, 0x00, 0x11, 0x00, 0x25, 0x00, 0x0c, 0x00, 0x2d, 0x00, 0x07, 0x00, 0x34, 0x00, 0x01, 0x00, 0x39, 0x00, 0xfa, 0xff, 0x3c, 0x00, 0xf2, 0xff, 0x3e, 0x00, 0xec, 0xff, 0x40, 0x00, 0xe7, 0xff, 0x44, 0x00, 0xe3, 0xff, 0x49, 0x00, 0xe1, 0xff, 0x4f, 0x00, 0xe0, 0xff, 0x54, 0x00, 0xde, 0xff, 0x57, 0x00, 0xdd, 0xff, 0x56, 0x00, 0xda, 0xff, 0x54, 0x00, 0xd5, 0xff, 0x51, 0x00, 0xcf, 0xff, 0x4e, 0x00, 0xc9, 0xff, 0x4a, 0x00, 0xc4, 0xff, 0x45, 0x00, 0xc1, 0xff, 0x3e, 0x00, 0xc1, 0xff, 0x37, 0x00, 0xc4, 0xff, 0x2f, 0x00, 0xc7, 0xff, 0x26, 0x00, 0xc8, 0xff, 0x1c, 0x00, 0xc7, 0xff, 0x12, 0x00, 0xc4, 0xff, 0x06, 0x00, 0xc0, 0xff, 0xfa, 0xff, 0xbc, 0xff, 0xed, 0xff, 0xbb, 0xff, 0xe1, 0xff, 0xbd, 0xff, 0xd7, 0xff, 0xc1, 0xff, 0xcf, 0xff, 0xc6, 0xff, 0xcb, 0xff, 0xcb, 0xff, 0xc8, 0xff, 0xcd, 0xff, 0xc5, 0xff, 0xcc, 0xff, 0xc0, 0xff, 0xcb, 0xff, 0xba, 0xff, 0xcb, 0xff, 0xb3, 0xff, 0xd0, 0xff, 0xb0, 0xff, 0xd9, 0xff, 0xb0, 0xff, 0xe4, 0xff, 0xb5, 0xff, 0xf0, 0xff, 0xbc, 0xff, 0xfa, 0xff, 0xc3, 0xff, 0x00, 0x00, 0xc8, 0xff, 0x03, 0x00, 0xc9, 0xff, 0x04, 0x00, 0xca, 0xff, 0x07, 0x00, 0xca, 0xff, 0x0d, 0x00, 0xcd, 0xff, 0x16, 0x00, 0xd3, 0xff, 0x22, 0x00, 0xdd, 0xff, 0x2e, 0x00, 0xe8, 0xff, 0x39, 0x00, 0xf2, 0xff, 0x40, 0x00, 0xf9, 0xff, 0x43, 0x00, 0xfd, 0xff, 0x44, 0x00, 0xfe, 0xff, 0x43, 0x00, 0xfd, 0xff, 0x43, 0x00, 0xfe, 0xff, 0x45, 0x00, 0x01, 0x00, 0x48, 0x00, 0x06, 0x00, 0x4c, 0x00, 0x0b, 0x00, 0x4e, 0x00, 0x11, 0x00, 0x4f, 0x00, 0x14, 0x00, 0x4d, 0x00, 0x16, 0x00, 0x4a, 0x00, 0x16, 0x00, 0x47, 0x00, 0x15, 0x00, 0x45, 0x00, 0x13, 0x00, 0x44, 0x00, 0x13, 0x00, 0x45, 0x00, 0x14, 0x00, 0x46, 0x00, 0x18, 0x00, 0x47, 0x00, 0x1e, 0x00, 0x48, 0x00, 0x25, 0x00, 0x48, 0x00, 0x29, 0x00, 0x47, 0x00, 0x2b, 0x00, 0x46, 0x00, 0x2b, 0x00, 0x43, 0x00, 0x2a, 0x00, 0x3f, 0x00, 0x29, 0x00, 0x3b, 0x00, 0x2a, 0x00, 0x37, 0x00, 0x30, 0x00, 0x33, 0x00, 0x38, 0x00, 0x30, 0x00, 0x40, 0x00, 0x2d, 0x00, 0x46, 0x00, 0x2a, 0x00, 0x48, 0x00, 0x26, 0x00, 0x46, 0x00, 0x20, 0x00, 0x43, 0x00, 0x18, 0x00, 0x40, 0x00, 0x0e, 0x00, 0x3f, 0x00, 0x04, 0x00, 0x40, 0x00, 0xfa, 0xff, 0x43, 0x00, 0xf1, 0xff, 0x44, 0x00, 0xea, 0xff, 0x42, 0x00, 0xe4, 0xff, 0x3c, 0x00, 0xde, 0xff, 0x32, 0x00, 0xd7, 0xff, 0x27, 0x00, 0xcf, 0xff, 0x1d, 0x00, 0xc6, 0xff, 0x17, 0x00, 0xbe, 0xff, 0x13, 0x00, 0xb5, 0xff, 0x10, 0x00, 0xad, 0xff, 0x0c, 0x00, 0xa6, 0xff, 0x07, 0x00, 0xa1, 0xff, 0xff, 0xff, 0x9d, 0xff, 0xf7, 0xff, 0x9b, 0xff, 0xf0, 0xff, 0x9a, 0xff, 0xea, 0xff, 0x99, 0xff, 0xe7, 0xff, 0x9a, 0xff, 0xe4, 0xff, 0x9b, 0xff, 0xe1, 0xff, 0x9f, 0xff, 0xdd, 0xff, 0xa4, 0xff, 0xd8, 0xff, 0xab, 0xff, 0xd3, 0xff, 0xb0, 0xff, 0xcf, 0xff, 0xb5, 0xff, 0xcb, 0xff, 0xb8, 0xff, 0xc8, 0xff, 0xba, 0xff, 0xc4, 0xff, 0xbb, 0xff, 0xc0, 0xff, 0xbd, 0xff, 0xbd, 0xff, 0xc0, 0xff, 0xbb, 0xff, 0xc4, 0xff, 0xba, 0xff, 0xcb, 0xff, 0xb9, 0xff, 0xd2, 0xff, 0xba, 0xff, 0xd6, 0xff, 0xba, 0xff, 0xd7, 0xff, 0xbb, 0xff, 0xd5, 0xff, 0xbb, 0xff, 0xd2, 0xff, 0xba, 0xff, 0xd1, 0xff, 0xbb, 0xff, 0xd2, 0xff, 0xbd, 0xff, 0xd6, 0xff, 0xc2, 0xff, 0xdd, 0xff, 0xc8, 0xff, 0xe4, 0xff, 0xce, 0xff, 0xeb, 0xff, 0xd3, 0xff, 0xf0, 0xff, 0xd6, 0xff, 0xf4, 0xff, 0xd8, 0xff, 0xf7, 0xff, 0xd9, 0xff, 0xf9, 0xff, 0xdb, 0xff, 0xfc, 0xff, 0xdf, 0xff, 0x00, 0x00, 0xe2, 0xff, 0x05, 0x00, 0xe6, 0xff, 0x0b, 0x00, 0xe8, 0xff, 0x12, 0x00, 0xe9, 0xff, 0x17, 0x00, 0xe9, 0xff, 0x1b, 0x00, 0xe8, 0xff, 0x1d, 0x00, 0xe8, 0xff, 0x1e, 0x00, 0xe9, 0xff, 0x1e, 0x00, 0xea, 0xff, 0x20, 0x00, 0xec, 0xff, 0x23, 0x00, 0xef, 0xff, 0x28, 0x00, 0xf3, 0xff, 0x2e, 0x00, 0xf7, 0xff, 0x36, 0x00, 0xfd, 0xff, 0x3d, 0x00, 0x02, 0x00, 0x41, 0x00, 0x06, 0x00, 0x44, 0x00, 0x09, 0x00, 0x46, 0x00, 0x0b, 0x00, 0x48, 0x00, 0x0b, 0x00, 0x4a, 0x00, 0x0c, 0x00, 0x4d, 0x00, 0x0e, 0x00, 0x4f, 0x00, 0x12, 0x00, 0x50, 0x00, 0x18, 0x00, 0x4e, 0x00, 0x1d, 0x00, 0x4b, 0x00, 0x21, 0x00, 0x45, 0x00, 0x21, 0x00, 0x3d, 0x00, 0x1f, 0x00, 0x36, 0x00, 0x1b, 0x00, 0x2f, 0x00, 0x18, 0x00, 0x29, 0x00, 0x18, 0x00, 0x22, 0x00, 0x19, 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x12, 0x00, 0x1d, 0x00, 0x08, 0x00, 0x1c, 0x00, 0xfe, 0xff, 0x19, 0x00, 0xf4, 0xff, 0x14, 0x00, 0xeb, 0xff, 0x0e, 0x00, 0xe3, 0xff, 0x08, 0x00, 0xdb, 0xff, 0x03, 0x00, 0xd3, 0xff, 0xff, 0xff, 0xcc, 0xff, 0xfd, 0xff, 0xc6, 0xff, 0xfd, 0xff, 0xc1, 0xff, 0xfc, 0xff, 0xbc, 0xff, 0xf9, 0xff, 0xb6, 0xff, 0xf5, 0xff, 0xb1, 0xff, 0xf0, 0xff, 0xad, 0xff, 0xec, 0xff, 0xab, 0xff, 0xeb, 0xff, 0xaa, 0xff, 0xeb, 0xff, 0xad, 0xff, 0xee, 0xff, 0xb2, 0xff, 0xf2, 0xff, 0xba, 0xff, 0xf6, 0xff, 0xc2, 0xff, 0xfa, 0xff, 0xca, 0xff, 0xfc, 0xff, 0xcf, 0xff, 0xfd, 0xff, 0xd4, 0xff, 0xfe, 0xff, 0xd7, 0xff, 0x00, 0x00, 0xdd, 0xff, 0x03, 0x00, 0xe4, 0xff, 0x07, 0x00, 0xee, 0xff, 0x0b, 0x00, 0xfa, 0xff, 0x0f, 0x00, 0x06, 0x00, 0x11, 0x00, 0x10, 0x00, 0x12, 0x00, 0x17, 0x00, 0x11, 0x00, 0x19, 0x00, 0x0e, 0x00, 0x19, 0x00, 0x0b, 0x00, 0x19, 0x00, 0x09, 0x00, 0x1a, 0x00, 0x08, 0x00, 0x1d, 0x00, 0x08, 0x00, 0x21, 0x00, 0x09, 0x00, 0x26, 0x00, 0x08, 0x00, 0x2b, 0x00, 0x08, 0x00, 0x30, 0x00, 0x06, 0x00, 0x35, 0x00, 0x04, 0x00, 0x38, 0x00, 0x01, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x44, 0x00, 0x04, 0x00, 0x4c, 0x00, 0x07, 0x00, 0x55, 0x00, 0x0a, 0x00, 0x5d, 0x00, 0x0b, 0x00, 0x63, 0x00, 0x09, 0x00, 0x69, 0x00, 0x07, 0x00, 0x6f, 0x00, 0x04, 0x00, 0x75, 0x00, 0x03, 0x00, 0x79, 0x00, 0x04, 0x00, 0x7c, 0x00, 0x06, 0x00, 0x7e, 0x00, 0x08, 0x00, 0x80, 0x00, 0x09, 0x00, 0x80, 0x00, 0x08, 0x00, 0x80, 0x00, 0x05, 0x00, 0x7e, 0x00, 0x02, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x02, 0x00, 0x69, 0x00, 0x04, 0x00, 0x61, 0x00, 0x04, 0x00, 0x59, 0x00, 0x02, 0x00, 0x51, 0x00, 0xfe, 0xff, 0x49, 0x00, 0xf8, 0xff, 0x40, 0x00, 0xf4, 0xff, 0x37, 0x00, 0xf0, 0xff, 0x2c, 0x00, 0xef, 0xff, 0x20, 0x00, 0xee, 0xff, 0x15, 0x00, 0xec, 0xff, 0x0b, 0x00, 0xe9, 0xff, 0x04, 0x00, 0xe5, 0xff, 0xfd, 0xff, 0xe0, 0xff, 0xf5, 0xff, 0xdc, 0xff, 0xeb, 0xff, 0xda, 0xff, 0xe0, 0xff, 0xdb, 0xff, 0xd5, 0xff, 0xdd, 0xff, 0xcb, 0xff, 0xe1, 0xff, 0xc2, 0xff, 0xe3, 0xff, 0xbc, 0xff, 0xe2, 0xff, 0xb7, 0xff, 0xe1, 0xff, 0xb2, 0xff, 0xe0, 0xff, 0xac, 0xff, 0xe1, 0xff, 0xa4, 0xff, 0xe6, 0xff, 0x9c, 0xff, 0xed, 0xff, 0x96, 0xff, 0xf5, 0xff, 0x91, 0xff, 0xfd, 0xff, 0x8e, 0xff, 0x02, 0x00, 0x8d, 0xff, 0x04, 0x00, 0x8c, 0xff, 0x06, 0x00, 0x8b, 0xff, 0x07, 0x00, 0x8a, 0xff, 0x0a, 0x00, 0x8a, 0xff, 0x0c, 0x00, 0x8c, 0xff, 0x0e, 0x00, 0x92, 0xff, 0x0f, 0x00, 0x9a, 0xff, 0x0e, 0x00, 0xa2, 0xff, 0x0c, 0x00, 0xaa, 0xff, 0x0a, 0x00, 0xb1, 0xff, 0x0a, 0x00, 0xb7, 0xff, 0x0c, 0x00, 0xbd, 0xff, 0x11, 0x00, 0xc4, 0xff, 0x15, 0x00, 0xcc, 0xff, 0x18, 0x00, 0xd5, 0xff, 0x19, 0x00, 0xdf, 0xff, 0x17, 0x00, 0xe8, 0xff, 0x14, 0x00, 0xf0, 0xff, 0x12, 0x00, 0xf7, 0xff, 0x11, 0x00, 0xfb, 0xff, 0x11, 0x00, 0xfe, 0xff, 0x14, 0x00, 0x01, 0x00, 0x18, 0x00, 0x06, 0x00, 0x1b, 0x00, 0x0c, 0x00, 0x1d, 0x00, 0x12, 0x00, 0x1e, 0x00, 0x16, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x1b, 0x00, 0x17, 0x00, 0x17, 0x00, 0x19, 0x00, 0x13, 0x00, 0x1d, 0x00, 0x0e, 0x00, 0x22, 0x00, 0x0b, 0x00, 0x28, 0x00, 0x0a, 0x00, 0x2c, 0x00, 0x0c, 0x00, 0x2d, 0x00, 0x0f, 0x00, 0x2b, 0x00, 0x12, 0x00, 0x28, 0x00, 0x12, 0x00, 0x25, 0x00, 0x0f, 0x00, 0x25, 0x00, 0x0b, 0x00, 0x28, 0x00, 0x09, 0x00, 0x2e, 0x00, 0x08, 0x00, 0x33, 0x00, 0x0c, 0x00, 0x36, 0x00, 0x11, 0x00, 0x36, 0x00, 0x17, 0x00, 0x34, 0x00, 0x1a, 0x00, 0x30, 0x00, 0x1a, 0x00, 0x2e, 0x00, 0x15, 0x00, 0x2e, 0x00, 0x0f, 0x00, 0x2f, 0x00, 0x09, 0x00, 0x30, 0x00, 0x07, 0x00, 0x30, 0x00, 0x09, 0x00, 0x2d, 0x00, 0x0d, 0x00, 0x27, 0x00, 0x10, 0x00, 0x1e, 0x00, 0x10, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x08, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xf3, 0xff, 0x0b, 0x00, 0xec, 0xff, 0x10, 0x00, 0xe4, 0xff, 0x16, 0x00, 0xdc, 0xff, 0x1c, 0x00, 0xd3, 0xff, 0x1f, 0x00, 0xca, 0xff, 0x20, 0x00, 0xc1, 0xff, 0x21, 0x00, 0xba, 0xff, 0x23, 0x00, 0xb5, 0xff, 0x26, 0x00, 0xb2, 0xff, 0x29, 0x00, 0xb1, 0xff, 0x28, 0x00, 0xb2, 0xff, 0x25, 0x00, 0xb5, 0xff, 0x1f, 0x00, 0xb9, 0xff, 0x18, 0x00, 0xbd, 0xff, 0x12, 0x00, 0xbf, 0xff, 0x10, 0x00, 0xbe, 0xff, 0x10, 0x00, 0xbd, 0xff, 0x12, 0x00, 0xbd, 0xff, 0x14, 0x00, 0xc0, 0xff, 0x13, 0x00, 0xc5, 0xff, 0x0e, 0x00, 0xcb, 0xff, 0x07, 0x00, 0xd0, 0xff, 0x01, 0x00, 0xd4, 0xff, 0xfd, 0xff, 0xd5, 0xff, 0xfd, 0xff, 0xd7, 0xff, 0xff, 0xff, 0xd9, 0xff, 0x02, 0x00, 0xdc, 0xff, 0x03, 0x00, 0xdf, 0xff, 0x01, 0x00, 0xe4, 0xff, 0xfc, 0xff, 0xe7, 0xff, 0xf7, 0xff, 0xea, 0xff, 0xf2, 0xff, 0xec, 0xff, 0xef, 0xff, 0xed, 0xff, 0xed, 0xff, 0xef, 0xff, 0xec, 0xff, 0xf3, 0xff, 0xea, 0xff, 0xf9, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xe1, 0xff, 0x04, 0x00, 0xdb, 0xff, 0x06, 0x00, 0xd4, 0xff, 0x05, 0x00, 0xce, 0xff, 0x04, 0x00, 0xc9, 0xff, 0x03, 0x00, 0xc5, 0xff, 0x05, 0x00, 0xc1, 0xff, 0x09, 0x00, 0xbe, 0xff, 0x0e, 0x00, 0xbd, 0xff, 0x14, 0x00, 0xbc, 0xff, 0x1a, 0x00, 0xbc, 0xff, 0x1e, 0x00, 0xbb, 0xff, 0x22, 0x00, 0xb8, 0xff, 0x24, 0x00, 0xb5, 0xff, 0x25, 0x00, 0xb2, 0xff, 0x25, 0x00, 0xaf, 0xff, 0x24, 0x00, 0xad, 0xff, 0x24, 0x00, 0xac, 0xff, 0x23, 0x00, 0xaa, 0xff, 0x22, 0x00, 0xa9, 0xff, 0x22, 0x00, 0xa7, 0xff, 0x23, 0x00, 0xa6, 0xff, 0x23, 0x00, 0xa7, 0xff, 0x23, 0x00, 0xab, 0xff, 0x21, 0x00, 0xb2, 0xff, 0x1d, 0x00, 0xbb, 0xff, 0x17, 0x00, 0xc4, 0xff, 0x11, 0x00, 0xcd, 0xff, 0x0e, 0x00, 0xd4, 0xff, 0x0e, 0x00, 0xdb, 0xff, 0x10, 0x00, 0xe2, 0xff, 0x14, 0x00, 0xec, 0xff, 0x15, 0x00, 0xf9, 0xff, 0x14, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x15, 0x00, 0x07, 0x00, 0x21, 0x00, 0x00, 0x00, 0x2a, 0x00, 0xfb, 0xff, 0x31, 0x00, 0xfb, 0xff, 0x35, 0x00, 0xff, 0xff, 0x3b, 0x00, 0x03, 0x00, 0x43, 0x00, 0x06, 0x00, 0x4e, 0x00, 0x06, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x64, 0x00, 0xfc, 0xff, 0x6a, 0x00, 0xf5, 0xff, 0x6a, 0x00, 0xf0, 0xff, 0x66, 0x00, 0xed, 0xff, 0x62, 0x00, 0xee, 0xff, 0x5e, 0x00, 0xf2, 0xff, 0x5e, 0x00, 0xf6, 0xff, 0x61, 0x00, 0xf9, 0xff, 0x64, 0x00, 0xfa, 0xff, 0x66, 0x00, 0xfa, 0xff, 0x65, 0x00, 0xf7, 0xff, 0x61, 0x00, 0xf3, 0xff, 0x5a, 0x00, 0xef, 0xff, 0x51, 0x00, 0xed, 0xff, 0x48, 0x00, 0xed, 0xff, 0x41, 0x00, 0xf0, 0xff, 0x3a, 0x00, 0xf5, 0xff, 0x35, 0x00, 0xfb, 0xff, 0x31, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x03, 0x00, 0x27, 0x00, 0x03, 0x00, 0x20, 0x00, 0x03, 0x00, 0x19, 0x00, 0x03, 0x00, 0x12, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x15, 0x00, 0x00, 0x00, 0x1d, 0x00, 0xfd, 0xff, 0x23, 0x00, 0xf9, 0xff, 0x27, 0x00, 0xf3, 0xff, 0x29, 0x00, 0xeb, 0xff, 0x2a, 0x00, 0xe2, 0xff, 0x2c, 0x00, 0xda, 0xff, 0x31, 0x00, 0xd4, 0xff, 0x36, 0x00, 0xd0, 0xff, 0x3b, 0x00, 0xcd, 0xff, 0x3e, 0x00, 0xca, 0xff, 0x3d, 0x00, 0xc5, 0xff, 0x3a, 0x00, 0xbe, 0xff, 0x36, 0x00, 0xb4, 0xff, 0x34, 0x00, 0xa8, 0xff, 0x34, 0x00, 0x9d, 0xff, 0x34, 0x00, 0x94, 0xff, 0x34, 0x00, 0x8e, 0xff, 0x32, 0x00, 0x8d, 0xff, 0x2d, 0x00, 0x8f, 0xff, 0x27, 0x00, 0x92, 0xff, 0x22, 0x00, 0x94, 0xff, 0x1d, 0x00, 0x95, 0xff, 0x1b, 0x00, 0x96, 0xff, 0x19, 0x00, 0x98, 0xff, 0x18, 0x00, 0x9c, 0xff, 0x16, 0x00, 0xa2, 0xff, 0x12, 0x00, 0xab, 0xff, 0x0d, 0x00, 0xb4, 0xff, 0x07, 0x00, 0xbd, 0xff, 0x00, 0x00, 0xc6, 0xff, 0xfb, 0xff, 0xce, 0xff, 0xf6, 0xff, 0xd5, 0xff, 0xf4, 0xff, 0xdc, 0xff, 0xf3, 0xff, 0xe4, 0xff, 0xf4, 0xff, 0xeb, 0xff, 0xf4, 0xff, 0xf2, 0xff, 0xf1, 0xff, 0xf8, 0xff, 0xeb, 0xff, 0xff, 0xff, 0xe2, 0xff, 0x05, 0x00, 0xd8, 0xff, 0x0b, 0x00, 0xd1, 0xff, 0x10, 0x00, 0xce, 0xff, 0x13, 0x00, 0xce, 0xff, 0x16, 0x00, 0xd1, 0xff, 0x19, 0x00, 0xd5, 0xff, 0x1e, 0x00, 0xd8, 0xff, 0x25, 0x00, 0xd8, 0xff, 0x2d, 0x00, 0xd5, 0xff, 0x36, 0x00, 0xd0, 0xff, 0x3e, 0x00, 0xca, 0xff, 0x46, 0x00, 0xc7, 0xff, 0x4d, 0x00, 0xc7, 0xff, 0x51, 0x00, 0xcd, 0xff, 0x53, 0x00, 0xd6, 0xff, 0x53, 0x00, 0xdf, 0xff, 0x55, 0x00, 0xe7, 0xff, 0x58, 0x00, 0xec, 0xff, 0x5e, 0x00, 0xed, 0xff, 0x65, 0x00, 0xec, 0xff, 0x6b, 0x00, 0xeb, 0xff, 0x6d, 0x00, 0xec, 0xff, 0x6d, 0x00, 0xf0, 0xff, 0x6a, 0x00, 0xf6, 0xff, 0x65, 0x00, 0xfe, 0xff, 0x61, 0x00, 0x05, 0x00, 0x5e, 0x00, 0x0a, 0x00, 0x5d, 0x00, 0x0b, 0x00, 0x5b, 0x00, 0x08, 0x00, 0x58, 0x00, 0x04, 0x00, 0x50, 0x00, 0xff, 0xff, 0x46, 0x00, 0xfe, 0xff, 0x39, 0x00, 0xff, 0xff, 0x2b, 0x00, 0x02, 0x00, 0x1f, 0x00, 0x05, 0x00, 0x15, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x07, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf6, 0xff, 0xf8, 0xff, 0xe7, 0xff, 0xf2, 0xff, 0xd6, 0xff, 0xee, 0xff, 0xc6, 0xff, 0xee, 0xff, 0xba, 0xff, 0xf1, 0xff, 0xb2, 0xff, 0xf8, 0xff, 0xae, 0xff, 0xff, 0xff, 0xac, 0xff, 0x05, 0x00, 0xab, 0xff, 0x08, 0x00, 0xa9, 0xff, 0x09, 0x00, 0xa5, 0xff, 0x09, 0x00, 0xa1, 0xff, 0x0b, 0x00, 0x9c, 0xff, 0x0d, 0x00, 0x97, 0xff, 0x10, 0x00, 0x94, 0xff, 0x15, 0x00, 0x95, 0xff, 0x1b, 0x00, 0x99, 0xff, 0x21, 0x00, 0x9f, 0xff, 0x25, 0x00, 0xa4, 0xff, 0x26, 0x00, 0xa8, 0xff, 0x24, 0x00, 0xa8, 0xff, 0x1f, 0x00, 0xa6, 0xff, 0x1a, 0x00, 0xa3, 0xff, 0x15, 0x00, 0xa2, 0xff, 0x10, 0x00, 0xa3, 0xff, 0x0c, 0x00, 0xa8, 0xff, 0x08, 0x00, 0xaf, 0xff, 0x04, 0x00, 0xb6, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xf8, 0xff, 0xc0, 0xff, 0xf1, 0xff, 0xc4, 0xff, 0xea, 0xff, 0xc8, 0xff, 0xe4, 0xff, 0xcd, 0xff, 0xe1, 0xff, 0xd4, 0xff, 0xe0, 0xff, 0xde, 0xff, 0xdf, 0xff, 0xea, 0xff, 0xde, 0xff, 0xf8, 0xff, 0xdc, 0xff, 0x07, 0x00, 0xda, 0xff, 0x14, 0x00, 0xd8, 0xff, 0x20, 0x00, 0xd8, 0xff, 0x29, 0x00, 0xdb, 0xff, 0x30, 0x00, 0xdf, 0xff, 0x38, 0x00, 0xe3, 0xff, 0x41, 0x00, 0xe6, 0xff, 0x4b, 0x00, 0xe9, 0xff, 0x55, 0x00, 0xea, 0xff, 0x5e, 0x00, 0xeb, 0xff, 0x67, 0x00, 0xeb, 0xff, 0x6e, 0x00, 0xed, 0xff, 0x74, 0x00, 0xf2, 0xff, 0x76, 0x00, 0xf8, 0xff, 0x75, 0x00, 0xff, 0xff, 0x72, 0x00, 0x04, 0x00, 0x70, 0x00, 0x07, 0x00, 0x6f, 0x00, 0x08, 0x00, 0x71, 0x00, 0x08, 0x00, 0x73, 0x00, 0x08, 0x00, 0x73, 0x00, 0x08, 0x00, 0x72, 0x00, 0x0a, 0x00, 0x6e, 0x00, 0x0d, 0x00, 0x68, 0x00, 0x10, 0x00, 0x61, 0x00, 0x15, 0x00, 0x5b, 0x00, 0x18, 0x00, 0x55, 0x00, 0x19, 0x00, 0x50, 0x00, 0x18, 0x00, 0x4c, 0x00, 0x15, 0x00, 0x4a, 0x00, 0x12, 0x00, 0x45, 0x00, 0x0f, 0x00, 0x3f, 0x00, 0x0f, 0x00, 0x35, 0x00, 0x13, 0x00, 0x2a, 0x00, 0x19, 0x00, 0x20, 0x00, 0x20, 0x00, 0x18, 0x00, 0x25, 0x00, 0x13, 0x00, 0x26, 0x00, 0x0e, 0x00, 0x24, 0x00, 0x0a, 0x00, 0x20, 0x00, 0x05, 0x00, 0x1b, 0x00, 0xfe, 0xff, 0x17, 0x00, 0xf6, 0xff, 0x15, 0x00, 0xed, 0xff, 0x16, 0x00, 0xe5, 0xff, 0x18, 0x00, 0xde, 0xff, 0x19, 0x00, 0xd9, 0xff, 0x17, 0x00, 0xd5, 0xff, 0x12, 0x00, 0xcf, 0xff, 0x09, 0x00, 0xc8, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xf8, 0xff, 0xb7, 0xff, 0xf3, 0xff, 0xb0, 0xff, 0xf2, 0xff, 0xa9, 0xff, 0xf2, 0xff, 0xa4, 0xff, 0xf2, 0xff, 0xa1, 0xff, 0xf2, 0xff, 0x9e, 0xff, 0xf0, 0xff, 0x9b, 0xff, 0xee, 0xff, 0x98, 0xff, 0xeb, 0xff, 0x97, 0xff, 0xe8, 0xff, 0x97, 0xff, 0xe6, 0xff, 0x99, 0xff, 0xe5, 0xff, 0x9c, 0xff, 0xe8, 0xff, 0xa0, 0xff, 0xeb, 0xff, 0xa3, 0xff, 0xed, 0xff, 0xa7, 0xff, 0xee, 0xff, 0xac, 0xff, 0xec, 0xff, 0xb4, 0xff, 0xea, 0xff, 0xbd, 0xff, 0xe9, 0xff, 0xc7, 0xff, 0xe8, 0xff, 0xd0, 0xff, 0xe6, 0xff, 0xd9, 0xff, 0xe4, 0xff, 0xe0, 0xff, 0xe1, 0xff, 0xe6, 0xff, 0xe0, 0xff, 0xec, 0xff, 0xdf, 0xff, 0xf3, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xdc, 0xff, 0x04, 0x00, 0xdb, 0xff, 0x0e, 0x00, 0xda, 0xff, 0x19, 0x00, 0xda, 0xff, 0x23, 0x00, 0xdc, 0xff, 0x2a, 0x00, 0xdd, 0xff, 0x30, 0x00, 0xdd, 0xff, 0x34, 0x00, 0xdc, 0xff, 0x39, 0x00, 0xdb, 0xff, 0x41, 0x00, 0xdb, 0xff, 0x4a, 0x00, 0xdd, 0xff, 0x55, 0x00, 0xe1, 0xff, 0x60, 0x00, 0xe6, 0xff, 0x69, 0x00, 0xeb, 0xff, 0x6e, 0x00, 0xee, 0xff, 0x71, 0x00, 0xf2, 0xff, 0x73, 0x00, 0xf4, 0xff, 0x76, 0x00, 0xf6, 0xff, 0x7a, 0x00, 0xf9, 0xff, 0x7e, 0x00, 0xfc, 0xff, 0x82, 0x00, 0x00, 0x00, 0x84, 0x00, 0x05, 0x00, 0x84, 0x00, 0x0c, 0x00, 0x82, 0x00, 0x14, 0x00, 0x7e, 0x00, 0x1c, 0x00, 0x78, 0x00, 0x24, 0x00, 0x71, 0x00, 0x2b, 0x00, 0x6a, 0x00, 0x32, 0x00, 0x64, 0x00, 0x39, 0x00, 0x5e, 0x00, 0x40, 0x00, 0x56, 0x00, 0x45, 0x00, 0x4c, 0x00, 0x49, 0x00, 0x3f, 0x00, 0x4b, 0x00, 0x30, 0x00, 0x4d, 0x00, 0x22, 0x00, 0x4f, 0x00, 0x15, 0x00, 0x52, 0x00, 0x09, 0x00, 0x56, 0x00, 0x00, 0x00, 0x5a, 0x00, 0xf7, 0xff, 0x5c, 0x00, 0xef, 0xff, 0x5e, 0x00, 0xe4, 0xff, 0x60, 0x00, 0xd7, 0xff, 0x60, 0x00, 0xc8, 0xff, 0x60, 0x00, 0xba, 0xff, 0x5f, 0x00, 0xad, 0xff, 0x5e, 0x00, 0xa4, 0xff, 0x5d, 0x00, 0x9f, 0xff, 0x5a, 0x00, 0x9c, 0xff, 0x56, 0x00, 0x9a, 0xff, 0x52, 0x00, 0x96, 0xff, 0x4d, 0x00, 0x90, 0xff, 0x48, 0x00, 0x88, 0xff, 0x42, 0x00, 0x7e, 0xff, 0x3c, 0x00, 0x75, 0xff, 0x35, 0x00, 0x71, 0xff, 0x2d, 0x00, 0x71, 0xff, 0x25, 0x00, 0x74, 0xff, 0x1b, 0x00, 0x7a, 0xff, 0x11, 0x00, 0x7e, 0xff, 0x07, 0x00, 0x81, 0xff, 0xfe, 0xff, 0x82, 0xff, 0xf7, 0xff, 0x81, 0xff, 0xf3, 0xff, 0x81, 0xff, 0xf1, 0xff, 0x83, 0xff, 0xef, 0xff, 0x87, 0xff, 0xec, 0xff, 0x8f, 0xff, 0xe8, 0xff, 0x99, 0xff, 0xe4, 0xff, 0xa2, 0xff, 0xdf, 0xff, 0xa9, 0xff, 0xdb, 0xff, 0xaf, 0xff, 0xd9, 0xff, 0xb4, 0xff, 0xda, 0xff, 0xbb, 0xff, 0xdd, 0xff, 0xc4, 0xff, 0xe1, 0xff, 0xce, 0xff, 0xe4, 0xff, 0xd9, 0xff, 0xe5, 0xff, 0xe3, 0xff, 0xe4, 0xff, 0xec, 0xff, 0xe3, 0xff, 0xf3, 0xff, 0xe3, 0xff, 0xfb, 0xff, 0xe4, 0xff, 0x04, 0x00, 0xe8, 0xff, 0x0e, 0x00, 0xec, 0xff, 0x19, 0x00, 0xef, 0xff, 0x24, 0x00, 0xf0, 0xff, 0x2d, 0x00, 0xf1, 0xff, 0x34, 0x00, 0xf2, 0xff, 0x38, 0x00, 0xf5, 0xff, 0x3c, 0x00, 0xf9, 0xff, 0x40, 0x00, 0x00, 0x00, 0x44, 0x00, 0x07, 0x00, 0x49, 0x00, 0x0e, 0x00, 0x4e, 0x00, 0x13, 0x00, 0x4f, 0x00, 0x15, 0x00, 0x4d, 0x00, 0x13, 0x00, 0x48, 0x00, 0x10, 0x00, 0x42, 0x00, 0x0d, 0x00, 0x3d, 0x00, 0x0b, 0x00, 0x3c, 0x00, 0x0a, 0x00, 0x3c, 0x00, 0x0a, 0x00, 0x3d, 0x00, 0x09, 0x00, 0x3c, 0x00, 0x08, 0x00, 0x38, 0x00, 0x05, 0x00, 0x34, 0x00, 0x01, 0x00, 0x2f, 0x00, 0xff, 0xff, 0x2d, 0x00, 0xfe, 0xff, 0x2d, 0x00, 0xff, 0xff, 0x2e, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2e, 0x00, 0xfe, 0xff, 0x2b, 0x00, 0xfb, 0xff, 0x26, 0x00, 0xf9, 0xff, 0x1f, 0x00, 0xf9, 0xff, 0x19, 0x00, 0xfb, 0xff, 0x14, 0x00, 0xfe, 0xff, 0x10, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0xfc, 0xff, 0xf8, 0xff, 0xf7, 0xff, 0xee, 0xff, 0xf1, 0xff, 0xe3, 0xff, 0xec, 0xff, 0xda, 0xff, 0xe7, 0xff, 0xd1, 0xff, 0xe2, 0xff, 0xca, 0xff, 0xdd, 0xff, 0xc5, 0xff, 0xd7, 0xff, 0xc0, 0xff, 0xd1, 0xff, 0xba, 0xff, 0xcb, 0xff, 0xb5, 0xff, 0xc7, 0xff, 0xaf, 0xff, 0xc3, 0xff, 0xab, 0xff, 0xc1, 0xff, 0xa6, 0xff, 0xbc, 0xff, 0xa2, 0xff, 0xb6, 0xff, 0x9e, 0xff, 0xaf, 0xff, 0x9a, 0xff, 0xa8, 0xff, 0x97, 0xff, 0xa2, 0xff, 0x96, 0xff, 0x9e, 0xff, 0x97, 0xff, 0x9b, 0xff, 0x9a, 0xff, 0x98, 0xff, 0x9d, 0xff, 0x95, 0xff, 0xa1, 0xff, 0x91, 0xff, 0xa5, 0xff, 0x8e, 0xff, 0xa9, 0xff, 0x8c, 0xff, 0xae, 0xff, 0x8c, 0xff, 0xb6, 0xff, 0x8e, 0xff, 0xc2, 0xff, 0x90, 0xff, 0xd0, 0xff, 0x93, 0xff, 0xe0, 0xff, 0x94, 0xff, 0xef, 0xff, 0x96, 0xff, 0xfc, 0xff, 0x98, 0xff, 0x07, 0x00, 0x9e, 0xff, 0x11, 0x00, 0xa6, 0xff, 0x1a, 0x00, 0xb1, 0xff, 0x25, 0x00, 0xbd, 0xff, 0x31, 0x00, 0xc9, 0xff, 0x3e, 0x00, 0xd4, 0xff, 0x49, 0x00, 0xdd, 0xff, 0x53, 0x00, 0xe3, 0xff, 0x5c, 0x00, 0xe7, 0xff, 0x62, 0x00, 0xec, 0xff, 0x67, 0x00, 0xf1, 0xff, 0x6b, 0x00, 0xf9, 0xff, 0x6f, 0x00, 0x00, 0x00, 0x72, 0x00, 0x07, 0x00, 0x75, 0x00, 0x0c, 0x00, 0x77, 0x00, 0x0f, 0x00, 0x78, 0x00, 0x11, 0x00, 0x79, 0x00, 0x13, 0x00, 0x7a, 0x00, 0x16, 0x00, 0x7b, 0x00, 0x1a, 0x00, 0x7b, 0x00, 0x1f, 0x00, 0x78, 0x00, 0x26, 0x00, 0x75, 0x00, 0x2e, 0x00, 0x71, 0x00, 0x35, 0x00, 0x6f, 0x00, 0x3a, 0x00, 0x6e, 0x00, 0x3f, 0x00, 0x6d, 0x00, 0x42, 0x00, 0x6b, 0x00, 0x43, 0x00, 0x67, 0x00, 0x45, 0x00, 0x61, 0x00, 0x46, 0x00, 0x59, 0x00, 0x49, 0x00, 0x4f, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x51, 0x00, 0x3c, 0x00, 0x55, 0x00, 0x34, 0x00, 0x57, 0x00, 0x2f, 0x00, 0x56, 0x00, 0x2a, 0x00, 0x52, 0x00, 0x25, 0x00, 0x4a, 0x00, 0x1f, 0x00, 0x41, 0x00, 0x17, 0x00, 0x3a, 0x00, 0x0e, 0x00, 0x37, 0x00, 0x04, 0x00, 0x37, 0x00, 0xfb, 0xff, 0x38, 0x00, 0xf3, 0xff, 0x39, 0x00, 0xec, 0xff, 0x37, 0x00, 0xe6, 0xff, 0x33, 0x00, 0xe2, 0xff, 0x2b, 0x00, 0xde, 0xff, 0x23, 0x00, 0xd9, 0xff, 0x1a, 0x00, 0xd4, 0xff, 0x14, 0x00, 0xcd, 0xff, 0x10, 0x00, 0xc4, 0xff, 0x0d, 0x00, 0xba, 0xff, 0x0b, 0x00, 0xb1, 0xff, 0x06, 0x00, 0xa9, 0xff, 0x01, 0x00, 0xa3, 0xff, 0xf9, 0xff, 0xa0, 0xff, 0xf2, 0xff, 0x9f, 0xff, 0xea, 0xff, 0x9e, 0xff, 0xe4, 0xff, 0x9d, 0xff, 0xdf, 0xff, 0x9a, 0xff, 0xda, 0xff, 0x96, 0xff, 0xd7, 0xff, 0x92, 0xff, 0xd3, 0xff, 0x8f, 0xff, 0xd1, 0xff, 0x8f, 0xff, 0xcf, 0xff, 0x92, 0xff, 0xcd, 0xff, 0x98, 0xff, 0xcc, 0xff, 0xa0, 0xff, 0xcb, 0xff, 0xa9, 0xff, 0xcb, 0xff, 0xb0, 0xff, 0xcb, 0xff, 0xb6, 0xff, 0xce, 0xff, 0xbb, 0xff, 0xd2, 0xff, 0xbf, 0xff, 0xd8, 0xff, 0xc4, 0xff, 0xdf, 0xff, 0xcb, 0xff, 0xe4, 0xff, 0xd4, 0xff, 0xe8, 0xff, 0xe0, 0xff, 0xea, 0xff, 0xec, 0xff, 0xec, 0xff, 0xf8, 0xff, 0xef, 0xff, 0x02, 0x00, 0xf4, 0xff, 0x09, 0x00, 0xfb, 0xff, 0x0e, 0x00, 0x03, 0x00, 0x12, 0x00, 0x0c, 0x00, 0x17, 0x00, 0x13, 0x00, 0x1d, 0x00, 0x19, 0x00, 0x26, 0x00, 0x1d, 0x00, 0x30, 0x00, 0x1f, 0x00, 0x3a, 0x00, 0x22, 0x00, 0x41, 0x00, 0x26, 0x00, 0x47, 0x00, 0x2b, 0x00, 0x4a, 0x00, 0x31, 0x00, 0x4c, 0x00, 0x36, 0x00, 0x4e, 0x00, 0x3a, 0x00, 0x50, 0x00, 0x3e, 0x00, 0x51, 0x00, 0x40, 0x00, 0x52, 0x00, 0x44, 0x00, 0x51, 0x00, 0x48, 0x00, 0x4f, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x51, 0x00, 0x49, 0x00, 0x56, 0x00, 0x48, 0x00, 0x59, 0x00, 0x47, 0x00, 0x5c, 0x00, 0x48, 0x00, 0x5c, 0x00, 0x49, 0x00, 0x5b, 0x00, 0x4a, 0x00, 0x5a, 0x00, 0x4a, 0x00, 0x59, 0x00, 0x47, 0x00, 0x5a, 0x00, 0x44, 0x00, 0x5b, 0x00, 0x3f, 0x00, 0x5b, 0x00, 0x3b, 0x00, 0x5a, 0x00, 0x37, 0x00, 0x58, 0x00, 0x33, 0x00, 0x54, 0x00, 0x2e, 0x00, 0x4d, 0x00, 0x29, 0x00, 0x46, 0x00, 0x22, 0x00, 0x3e, 0x00, 0x1c, 0x00, 0x37, 0x00, 0x16, 0x00, 0x32, 0x00, 0x10, 0x00, 0x2f, 0x00, 0x0a, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2b, 0x00, 0xf5, 0xff, 0x26, 0x00, 0xe8, 0xff, 0x1d, 0x00, 0xdd, 0xff, 0x11, 0x00, 0xd5, 0xff, 0x04, 0x00, 0xcf, 0xff, 0xf7, 0xff, 0xcc, 0xff, 0xee, 0xff, 0xca, 0xff, 0xe8, 0xff, 0xc7, 0xff, 0xe5, 0xff, 0xc2, 0xff, 0xe3, 0xff, 0xbc, 0xff, 0xe0, 0xff, 0xb5, 0xff, 0xd9, 0xff, 0xb0, 0xff, 0xcf, 0xff, 0xab, 0xff, 0xc2, 0xff, 0xaa, 0xff, 0xb6, 0xff, 0xa9, 0xff, 0xad, 0xff, 0xa8, 0xff, 0xa7, 0xff, 0xa6, 0xff, 0xa4, 0xff, 0xa4, 0xff, 0xa2, 0xff, 0xa1, 0xff, 0xa0, 0xff, 0x9e, 0xff, 0x9c, 0xff, 0x9d, 0xff, 0x97, 0xff, 0x9e, 0xff, 0x90, 0xff, 0xa1, 0xff, 0x8b, 0xff, 0xa4, 0xff, 0x88, 0xff, 0xa7, 0xff, 0x87, 0xff, 0xab, 0xff, 0x89, 0xff, 0xb1, 0xff, 0x8b, 0xff, 0xb8, 0xff, 0x8e, 0xff, 0xc2, 0xff, 0x92, 0xff, 0xcc, 0xff, 0x95, 0xff, 0xd5, 0xff, 0x98, 0xff, 0xdd, 0xff, 0x9a, 0xff, 0xe2, 0xff, 0x9c, 0xff, 0xe5, 0xff, 0x9e, 0xff, 0xe9, 0xff, 0xa3, 0xff, 0xee, 0xff, 0xaa, 0xff, 0xf4, 0xff, 0xb3, 0xff, 0xfc, 0xff, 0xbd, 0xff, 0x03, 0x00, 0xc9, 0xff, 0x08, 0x00, 0xd5, 0xff, 0x0b, 0x00, 0xde, 0xff, 0x0d, 0x00, 0xe6, 0xff, 0x0e, 0x00, 0xec, 0xff, 0x0e, 0x00, 0xf3, 0xff, 0x0f, 0x00, 0xfb, 0xff, 0x11, 0x00, 0x05, 0x00, 0x13, 0x00, 0x11, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x1a, 0x00, 0x2b, 0x00, 0x1f, 0x00, 0x35, 0x00, 0x24, 0x00, 0x3c, 0x00, 0x29, 0x00, 0x40, 0x00, 0x2d, 0x00, 0x43, 0x00, 0x30, 0x00, 0x45, 0x00, 0x30, 0x00, 0x48, 0x00, 0x2f, 0x00, 0x4c, 0x00, 0x2d, 0x00, 0x50, 0x00, 0x2d, 0x00, 0x54, 0x00, 0x2d, 0x00, 0x58, 0x00, 0x2f, 0x00, 0x5a, 0x00, 0x30, 0x00, 0x5a, 0x00, 0x30, 0x00, 0x57, 0x00, 0x2e, 0x00, 0x55, 0x00, 0x2a, 0x00, 0x53, 0x00, 0x27, 0x00, 0x53, 0x00, 0x23, 0x00, 0x52, 0x00, 0x21, 0x00, 0x50, 0x00, 0x1e, 0x00, 0x4d, 0x00, 0x1b, 0x00, 0x4b, 0x00, 0x17, 0x00, 0x4a, 0x00, 0x11, 0x00, 0x48, 0x00, 0x0c, 0x00, 0x45, 0x00, 0x07, 0x00, 0x3f, 0x00, 0x02, 0x00, 0x38, 0x00, 0x00, 0x00, 0x30, 0x00, 0xff, 0xff, 0x29, 0x00, 0x00, 0x00, 0x24, 0x00, 0xff, 0xff, 0x21, 0x00, 0xfb, 0xff, 0x20, 0x00, 0xf4, 0xff, 0x1c, 0x00, 0xec, 0xff, 0x17, 0x00, 0xe6, 0xff, 0x0e, 0x00, 0xe3, 0xff, 0x03, 0x00, 0xe3, 0xff, 0xf7, 0xff, 0xe5, 0xff, 0xed, 0xff, 0xe8, 0xff, 0xe6, 0xff, 0xe8, 0xff, 0xe3, 0xff, 0xe6, 0xff, 0xe2, 0xff, 0xe2, 0xff, 0xe1, 0xff, 0xdc, 0xff, 0xdf, 0xff, 0xd8, 0xff, 0xda, 0xff, 0xd8, 0xff, 0xd5, 0xff, 0xda, 0xff, 0xd0, 0xff, 0xe0, 0xff, 0xcc, 0xff, 0xe6, 0xff, 0xc9, 0xff, 0xeb, 0xff, 0xc8, 0xff, 0xed, 0xff, 0xc7, 0xff, 0xec, 0xff, 0xc7, 0xff, 0xe8, 0xff, 0xc8, 0xff, 0xe6, 0xff, 0xc8, 0xff, 0xe6, 0xff, 0xc9, 0xff, 0xe9, 0xff, 0xcb, 0xff, 0xf1, 0xff, 0xce, 0xff, 0xf9, 0xff, 0xd2, 0xff, 0x01, 0x00, 0xd6, 0xff, 0x06, 0x00, 0xda, 0xff, 0x09, 0x00, 0xdc, 0xff, 0x09, 0x00, 0xe0, 0xff, 0x07, 0x00, 0xe6, 0xff, 0x06, 0x00, 0xee, 0xff, 0x07, 0x00, 0xf6, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x11, 0x00, 0x01, 0x00, 0x1a, 0x00, 0x05, 0x00, 0x24, 0x00, 0x09, 0x00, 0x2d, 0x00, 0x0e, 0x00, 0x32, 0x00, 0x15, 0x00, 0x34, 0x00, 0x1d, 0x00, 0x33, 0x00, 0x26, 0x00, 0x32, 0x00, 0x2e, 0x00, 0x33, 0x00, 0x34, 0x00, 0x37, 0x00, 0x38, 0x00, 0x3d, 0x00, 0x3a, 0x00, 0x45, 0x00, 0x3c, 0x00, 0x4c, 0x00, 0x40, 0x00, 0x51, 0x00, 0x43, 0x00, 0x52, 0x00, 0x46, 0x00, 0x4f, 0x00, 0x48, 0x00, 0x4a, 0x00, 0x48, 0x00, 0x46, 0x00, 0x47, 0x00, 0x44, 0x00, 0x46, 0x00, 0x45, 0x00, 0x47, 0x00, 0x49, 0x00, 0x48, 0x00, 0x4d, 0x00, 0x49, 0x00, 0x4f, 0x00, 0x48, 0x00, 0x4e, 0x00, 0x45, 0x00, 0x48, 0x00, 0x40, 0x00, 0x40, 0x00, 0x3b, 0x00, 0x38, 0x00, 0x36, 0x00, 0x32, 0x00, 0x34, 0x00, 0x2e, 0x00, 0x34, 0x00, 0x2c, 0x00, 0x34, 0x00, 0x2c, 0x00, 0x35, 0x00, 0x2a, 0x00, 0x32, 0x00, 0x27, 0x00, 0x2d, 0x00, 0x23, 0x00, 0x26, 0x00, 0x1b, 0x00, 0x1e, 0x00, 0x11, 0x00, 0x18, 0x00, 0x05, 0x00, 0x11, 0x00, 0xf9, 0xff, 0x0b, 0x00, 0xf0, 0xff, 0x05, 0x00, 0xea, 0xff, 0xfe, 0xff, 0xe7, 0xff, 0xf6, 0xff, 0xe5, 0xff, 0xef, 0xff, 0xe5, 0xff, 0xe7, 0xff, 0xe3, 0xff, 0xe0, 0xff, 0xe0, 0xff, 0xd9, 0xff, 0xda, 0xff, 0xd2, 0xff, 0xd2, 0xff, 0xcb, 0xff, 0xca, 0xff, 0xc3, 0xff, 0xc4, 0xff, 0xba, 0xff, 0xc0, 0xff, 0xb2, 0xff, 0xc0, 0xff, 0xac, 0xff, 0xc2, 0xff, 0xa7, 0xff, 0xc4, 0xff, 0xa4, 0xff, 0xc5, 0xff, 0xa1, 0xff, 0xc5, 0xff, 0x9d, 0xff, 0xc2, 0xff, 0x99, 0xff, 0xbf, 0xff, 0x94, 0xff, 0xbd, 0xff, 0x8f, 0xff, 0xbc, 0xff, 0x8c, 0xff, 0xbd, 0xff, 0x8c, 0xff, 0xbf, 0xff, 0x8e, 0xff, 0xc3, 0xff, 0x93, 0xff, 0xc7, 0xff, 0x97, 0xff, 0xcc, 0xff, 0x9b, 0xff, 0xd2, 0xff, 0x9e, 0xff, 0xd8, 0xff, 0xa0, 0xff, 0xde, 0xff, 0xa3, 0xff, 0xe6, 0xff, 0xa7, 0xff, 0xee, 0xff, 0xad, 0xff, 0xf5, 0xff, 0xb5, 0xff, 0xfa, 0xff, 0xbe, 0xff, 0xff, 0xff, 0xc8, 0xff, 0x05, 0x00, 0xd2, 0xff, 0x0b, 0x00, 0xdb, 0xff, 0x13, 0x00, 0xe4, 0xff, 0x1c, 0x00, 0xeb, 0xff, 0x24, 0x00, 0xf0, 0xff, 0x2b, 0x00, 0xf5, 0xff, 0x30, 0x00, 0xf9, 0xff, 0x32, 0x00, 0xfd, 0xff, 0x33, 0x00, 0x01, 0x00, 0x33, 0x00, 0x06, 0x00, 0x33, 0x00, 0x0b, 0x00, 0x34, 0x00, 0x10, 0x00, 0x36, 0x00, 0x15, 0x00, 0x37, 0x00, 0x19, 0x00, 0x39, 0x00, 0x1a, 0x00, 0x3b, 0x00, 0x19, 0x00, 0x3c, 0x00, 0x18, 0x00, 0x3c, 0x00, 0x18, 0x00, 0x3b, 0x00, 0x18, 0x00, 0x3a, 0x00, 0x19, 0x00, 0x37, 0x00, 0x1a, 0x00, 0x35, 0x00, 0x1a, 0x00, 0x32, 0x00, 0x18, 0x00, 0x30, 0x00, 0x16, 0x00, 0x2f, 0x00, 0x12, 0x00, 0x2f, 0x00, 0x0e, 0x00, 0x2f, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x08, 0x00, 0x2d, 0x00, 0x06, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x25, 0x00, 0x01, 0x00, 0x1f, 0x00, 0xfe, 0xff, 0x19, 0x00, 0xfd, 0xff, 0x15, 0x00, 0xfb, 0xff, 0x13, 0x00, 0xfb, 0xff, 0x12, 0x00, 0xfa, 0xff, 0x10, 0x00, 0xf9, 0xff, 0x0c, 0x00, 0xf7, 0xff, 0x05, 0x00, 0xf6, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xf6, 0xff, 0xf7, 0xff, 0xf0, 0xff, 0xf9, 0xff, 0xec, 0xff, 0xf9, 0xff, 0xe7, 0xff, 0xf8, 0xff, 0xe1, 0xff, 0xf6, 0xff, 0xd9, 0xff, 0xf1, 0xff, 0xcf, 0xff, 0xec, 0xff, 0xc4, 0xff, 0xe7, 0xff, 0xbc, 0xff, 0xe3, 0xff, 0xb8, 0xff, 0xe1, 0xff, 0xb9, 0xff, 0xe1, 0xff, 0xbb, 0xff, 0xe0, 0xff, 0xbd, 0xff, 0xde, 0xff, 0xbb, 0xff, 0xda, 0xff, 0xb7, 0xff, 0xd4, 0xff, 0xb2, 0xff, 0xcf, 0xff, 0xaf, 0xff, 0xcc, 0xff, 0xae, 0xff, 0xcb, 0xff, 0xb2, 0xff, 0xcd, 0xff, 0xb9, 0xff, 0xd1, 0xff, 0xc1, 0xff, 0xd7, 0xff, 0xc7, 0xff, 0xdc, 0xff, 0xcb, 0xff, 0xe1, 0xff, 0xcd, 0xff, 0xe4, 0xff, 0xcf, 0xff, 0xe6, 0xff, 0xd0, 0xff, 0xe9, 0xff, 0xd4, 0xff, 0xed, 0xff, 0xda, 0xff, 0xf4, 0xff, 0xe0, 0xff, 0xfd, 0xff, 0xe7, 0xff, 0x08, 0x00, 0xec, 0xff, 0x12, 0x00, 0xef, 0xff, 0x1c, 0x00, 0xf0, 0xff, 0x23, 0x00, 0xf1, 0xff, 0x28, 0x00, 0xf2, 0xff, 0x2c, 0x00, 0xf4, 0xff, 0x2f, 0x00, 0xf6, 0xff, 0x32, 0x00, 0xf9, 0xff, 0x35, 0x00, 0xfd, 0xff, 0x3a, 0x00, 0x01, 0x00, 0x40, 0x00, 0x06, 0x00, 0x45, 0x00, 0x0c, 0x00, 0x49, 0x00, 0x10, 0x00, 0x4a, 0x00, 0x14, 0x00, 0x49, 0x00, 0x15, 0x00, 0x47, 0x00, 0x15, 0x00, 0x46, 0x00, 0x16, 0x00, 0x46, 0x00, 0x18, 0x00, 0x49, 0x00, 0x1d, 0x00, 0x4c, 0x00, 0x24, 0x00, 0x4f, 0x00, 0x2d, 0x00, 0x51, 0x00, 0x35, 0x00, 0x4f, 0x00, 0x3b, 0x00, 0x4c, 0x00, 0x3f, 0x00, 0x49, 0x00, 0x40, 0x00, 0x48, 0x00, 0x40, 0x00, 0x49, 0x00, 0x40, 0x00, 0x4c, 0x00, 0x42, 0x00, 0x51, 0x00, 0x46, 0x00, 0x55, 0x00, 0x48, 0x00, 0x58, 0x00, 0x48, 0x00, 0x57, 0x00, 0x45, 0x00, 0x53, 0x00, 0x3e, 0x00, 0x4c, 0x00, 0x36, 0x00, 0x46, 0x00, 0x2f, 0x00, 0x40, 0x00, 0x28, 0x00, 0x3b, 0x00, 0x22, 0x00, 0x38, 0x00, 0x1c, 0x00, 0x34, 0x00, 0x15, 0x00, 0x30, 0x00, 0x0b, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x26, 0x00, 0xf3, 0xff, 0x20, 0x00, 0xe6, 0xff, 0x18, 0x00, 0xd9, 0xff, 0x10, 0x00, 0xce, 0xff, 0x0a, 0x00, 0xc6, 0xff, 0x06, 0x00, 0xbf, 0xff, 0x04, 0x00, 0xb9, 0xff, 0x01, 0x00, 0xb4, 0xff, 0xfe, 0xff, 0xae, 0xff, 0xf9, 0xff, 0xa8, 0xff, 0xf3, 0xff, 0xa3, 0xff, 0xec, 0xff, 0x9e, 0xff, 0xe4, 0xff, 0x9b, 0xff, 0xdd, 0xff, 0x99, 0xff, 0xd7, 0xff, 0x97, 0xff, 0xd2, 0xff, 0x96, 0xff, 0xcf, 0xff, 0x95, 0xff, 0xcf, 0xff, 0x96, 0xff, 0xcf, 0xff, 0x97, 0xff, 0xcf, 0xff, 0x99, 0xff, 0xcd, 0xff, 0x9a, 0xff, 0xc9, 0xff, 0x9b, 0xff, 0xc5, 0xff, 0x9b, 0xff, 0xc2, 0xff, 0x9b, 0xff, 0xc1, 0xff, 0x9c, 0xff, 0xc1, 0xff, 0x9f, 0xff, 0xc5, 0xff, 0xa2, 0xff, 0xcc, 0xff, 0xa7, 0xff, 0xd2, 0xff, 0xaa, 0xff, 0xd6, 0xff, 0xac, 0xff, 0xd8, 0xff, 0xad, 0xff, 0xd7, 0xff, 0xaf, 0xff, 0xd6, 0xff, 0xb2, 0xff, 0xd6, 0xff, 0xb7, 0xff, 0xd8, 0xff, 0xbe, 0xff, 0xdb, 0xff, 0xc5, 0xff, 0xdf, 0xff, 0xcd, 0xff, 0xe3, 0xff, 0xd3, 0xff, 0xe6, 0xff, 0xd8, 0xff, 0xe8, 0xff, 0xdc, 0xff, 0xe8, 0xff, 0xe1, 0xff, 0xe9, 0xff, 0xe6, 0xff, 0xeb, 0xff, 0xec, 0xff, 0xef, 0xff, 0xf5, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x0a, 0x00, 0x04, 0x00, 0x14, 0x00, 0x0a, 0x00, 0x1d, 0x00, 0x0c, 0x00, 0x23, 0x00, 0x0d, 0x00, 0x28, 0x00, 0x0c, 0x00, 0x2a, 0x00, 0x0b, 0x00, 0x2b, 0x00, 0x0b, 0x00, 0x2c, 0x00, 0x0e, 0x00, 0x2e, 0x00, 0x12, 0x00, 0x33, 0x00, 0x17, 0x00, 0x39, 0x00, 0x1d, 0x00, 0x3f, 0x00, 0x20, 0x00, 0x43, 0x00, 0x20, 0x00, 0x43, 0x00, 0x1c, 0x00, 0x3f, 0x00, 0x16, 0x00, 0x39, 0x00, 0x10, 0x00, 0x33, 0x00, 0x0d, 0x00, 0x2d, 0x00, 0x0e, 0x00, 0x2b, 0x00, 0x12, 0x00, 0x2a, 0x00, 0x17, 0x00, 0x2c, 0x00, 0x1d, 0x00, 0x2e, 0x00, 0x1f, 0x00, 0x2d, 0x00, 0x1f, 0x00, 0x29, 0x00, 0x1d, 0x00, 0x23, 0x00, 0x19, 0x00, 0x1b, 0x00, 0x16, 0x00, 0x14, 0x00, 0x14, 0x00, 0x11, 0x00, 0x14, 0x00, 0x0f, 0x00, 0x15, 0x00, 0x10, 0x00, 0x16, 0x00, 0x13, 0x00, 0x15, 0x00, 0x15, 0x00, 0x12, 0x00, 0x15, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x03, 0x00, 0x0f, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf6, 0xff, 0x01, 0x00, 0xf4, 0xff, 0x00, 0x00, 0xf2, 0xff, 0x00, 0x00, 0xef, 0xff, 0x01, 0x00, 0xea, 0xff, 0x02, 0x00, 0xe4, 0xff, 0x01, 0x00, 0xdd, 0xff, 0xff, 0xff, 0xd8, 0xff, 0xfc, 0xff, 0xd3, 0xff, 0xf9, 0xff, 0xd0, 0xff, 0xf7, 0xff, 0xce, 0xff, 0xf5, 0xff, 0xcb, 0xff, 0xf4, 0xff, 0xc9, 0xff, 0xf4, 0xff, 0xc8, 0xff, 0xf5, 0xff, 0xc7, 0xff, 0xf6, 0xff, 0xc8, 0xff, 0xf7, 0xff, 0xc9, 0xff, 0xf7, 0xff, 0xca, 0xff, 0xf5, 0xff, 0xcc, 0xff, 0xf4, 0xff, 0xcd, 0xff, 0xf4, 0xff, 0xce, 0xff, 0xf6, 0xff, 0xd1, 0xff, 0xfa, 0xff, 0xd5, 0xff, 0xfe, 0xff, 0xd9, 0xff, 0x04, 0x00, 0xde, 0xff, 0x08, 0x00, 0xe2, 0xff, 0x0b, 0x00, 0xe6, 0xff, 0x0c, 0x00, 0xea, 0xff, 0x0c, 0x00, 0xf0, 0xff, 0x0c, 0x00, 0xf7, 0xff, 0x0c, 0x00, 0xff, 0xff, 0x0e, 0x00, 0x07, 0x00, 0x11, 0x00, 0x0d, 0x00, 0x17, 0x00, 0x11, 0x00, 0x1e, 0x00, 0x13, 0x00, 0x26, 0x00, 0x13, 0x00, 0x2c, 0x00, 0x14, 0x00, 0x31, 0x00, 0x17, 0x00, 0x33, 0x00, 0x20, 0x00, 0x34, 0x00, 0x2c, 0x00, 0x35, 0x00, 0x38, 0x00, 0x37, 0x00, 0x40, 0x00, 0x3b, 0x00, 0x44, 0x00, 0x3f, 0x00, 0x43, 0x00, 0x43, 0x00, 0x40, 0x00, 0x47, 0x00, 0x3d, 0x00, 0x4b, 0x00, 0x3c, 0x00, 0x4e, 0x00, 0x3e, 0x00, 0x50, 0x00, 0x42, 0x00, 0x52, 0x00, 0x47, 0x00, 0x53, 0x00, 0x4c, 0x00, 0x56, 0x00, 0x50, 0x00, 0x58, 0x00, 0x52, 0x00, 0x5a, 0x00, 0x51, 0x00, 0x5b, 0x00, 0x50, 0x00, 0x5b, 0x00, 0x4e, 0x00, 0x59, 0x00, 0x4b, 0x00, 0x57, 0x00, 0x48, 0x00, 0x56, 0x00, 0x47, 0x00, 0x54, 0x00, 0x46, 0x00, 0x52, 0x00, 0x48, 0x00, 0x51, 0x00, 0x4a, 0x00, 0x4f, 0x00, 0x4c, 0x00, 0x4e, 0x00, 0x4b, 0x00, 0x4b, 0x00, 0x47, 0x00, 0x46, 0x00, 0x41, 0x00, 0x40, 0x00, 0x3b, 0x00, 0x38, 0x00, 0x37, 0x00, 0x30, 0x00, 0x34, 0x00, 0x29, 0x00, 0x33, 0x00, 0x24, 0x00, 0x32, 0x00, 0x20, 0x00, 0x30, 0x00, 0x1d, 0x00, 0x2c, 0x00, 0x18, 0x00, 0x25, 0x00, 0x12, 0x00, 0x1d, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x02, 0x00, 0x10, 0x00, 0xfa, 0xff, 0x0c, 0x00, 0xf3, 0xff, 0x0a, 0x00, 0xed, 0xff, 0x09, 0x00, 0xe9, 0xff, 0x07, 0x00, 0xe6, 0xff, 0x04, 0x00, 0xe5, 0xff, 0xff, 0xff, 0xe5, 0xff, 0xf8, 0xff, 0xe5, 0xff, 0xf2, 0xff, 0xe4, 0xff, 0xed, 0xff, 0xe2, 0xff, 0xeb, 0xff, 0xe2, 0xff, 0xe9, 0xff, 0xe2, 0xff, 0xe8, 0xff, 0xe4, 0xff, 0xe4, 0xff, 0xe5, 0xff, 0xdf, 0xff, 0xe5, 0xff, 0xd8, 0xff, 0xe5, 0xff, 0xd0, 0xff, 0xe5, 0xff, 0xca, 0xff, 0xe5, 0xff, 0xc6, 0xff, 0xe5, 0xff, 0xc5, 0xff, 0xe4, 0xff, 0xc4, 0xff, 0xe2, 0xff, 0xc4, 0xff, 0xdf, 0xff, 0xc4, 0xff, 0xdd, 0xff, 0xc3, 0xff, 0xdd, 0xff, 0xc2, 0xff, 0xdf, 0xff, 0xc0, 0xff, 0xe1, 0xff, 0xbd, 0xff, 0xe3, 0xff, 0xbb, 0xff, 0xe4, 0xff, 0xbb, 0xff, 0xe2, 0xff, 0xbb, 0xff, 0xde, 0xff, 0xbe, 0xff, 0xda, 0xff, 0xc3, 0xff, 0xd8, 0xff, 0xc8, 0xff, 0xd8, 0xff, 0xcd, 0xff, 0xdb, 0xff, 0xd0, 0xff, 0xe0, 0xff, 0xd1, 0xff, 0xe5, 0xff, 0xd0, 0xff, 0xe8, 0xff, 0xce, 0xff, 0xe9, 0xff, 0xcf, 0xff, 0xe7, 0xff, 0xd2, 0xff, 0xe4, 0xff, 0xd8, 0xff, 0xe2, 0xff, 0xe0, 0xff, 0xe3, 0xff, 0xe7, 0xff, 0xe5, 0xff, 0xec, 0xff, 0xea, 0xff, 0xed, 0xff, 0xee, 0xff, 0xec, 0xff, 0xf1, 0xff, 0xe9, 0xff, 0xf3, 0xff, 0xe7, 0xff, 0xf4, 0xff, 0xea, 0xff, 0xf4, 0xff, 0xf0, 0xff, 0xf5, 0xff, 0xf9, 0xff, 0xf6, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x0b, 0x00, 0xf8, 0xff, 0x11, 0x00, 0xf9, 0xff, 0x14, 0x00, 0xfe, 0xff, 0x13, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x09, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x04, 0x00, 0x03, 0x00, 0x07, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xf6, 0xff, 0x0b, 0x00, 0xef, 0xff, 0x0b, 0x00, 0xec, 0xff, 0x09, 0x00, 0xed, 0xff, 0x06, 0x00, 0xf0, 0xff, 0x01, 0x00, 0xf2, 0xff, 0xfc, 0xff, 0xf2, 0xff, 0xf8, 0xff, 0xec, 0xff, 0xf6, 0xff, 0xe2, 0xff, 0xf6, 0xff, 0xd7, 0xff, 0xf7, 0xff, 0xce, 0xff, 0xf8, 0xff, 0xca, 0xff, 0xf7, 0xff, 0xca, 0xff, 0xf5, 0xff, 0xcd, 0xff, 0xf0, 0xff, 0xd0, 0xff, 0xea, 0xff, 0xd0, 0xff, 0xe4, 0xff, 0xcb, 0xff, 0xe0, 0xff, 0xc2, 0xff, 0xde, 0xff, 0xb8, 0xff, 0xdf, 0xff, 0xb0, 0xff, 0xe2, 0xff, 0xae, 0xff, 0xe5, 0xff, 0xb1, 0xff, 0xe6, 0xff, 0xb8, 0xff, 0xe4, 0xff, 0xc1, 0xff, 0xdf, 0xff, 0xc8, 0xff, 0xd8, 0xff, 0xce, 0xff, 0xd2, 0xff, 0xd1, 0xff, 0xd0, 0xff, 0xd2, 0xff, 0xd3, 0xff, 0xd2, 0xff, 0xda, 0xff, 0xd3, 0xff, 0xe2, 0xff, 0xd7, 0xff, 0xe7, 0xff, 0xdf, 0xff, 0xe8, 0xff, 0xe8, 0xff, 0xe3, 0xff, 0xf1, 0xff, 0xdc, 0xff, 0xf8, 0xff, 0xd7, 0xff, 0xfc, 0xff, 0xd6, 0xff, 0xfd, 0xff, 0xdb, 0xff, 0xfd, 0xff, 0xe4, 0xff, 0xfc, 0xff, 0xed, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0xfd, 0xff, 0xf4, 0xff, 0x01, 0x00, 0xf1, 0xff, 0x05, 0x00, 0xec, 0xff, 0x08, 0x00, 0xe7, 0xff, 0x0a, 0x00, 0xe6, 0xff, 0x09, 0x00, 0xe9, 0xff, 0x09, 0x00, 0xf2, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x0b, 0x00, 0x09, 0x00, 0x10, 0x00, 0x10, 0x00, 0x15, 0x00, 0x12, 0x00, 0x1b, 0x00, 0x10, 0x00, 0x1f, 0x00, 0x0b, 0x00, 0x23, 0x00, 0x08, 0x00, 0x26, 0x00, 0x08, 0x00, 0x27, 0x00, 0x0c, 0x00, 0x27, 0x00, 0x15, 0x00, 0x28, 0x00, 0x20, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x30, 0x00, 0x33, 0x00, 0x33, 0x00, 0x2e, 0x00, 0x34, 0x00, 0x24, 0x00, 0x36, 0x00, 0x1a, 0x00, 0x38, 0x00, 0x14, 0x00, 0x3a, 0x00, 0x14, 0x00, 0x3c, 0x00, 0x18, 0x00, 0x3c, 0x00, 0x1d, 0x00, 0x39, 0x00, 0x22, 0x00, 0x35, 0x00, 0x22, 0x00, 0x30, 0x00, 0x1d, 0x00, 0x2c, 0x00, 0x14, 0x00, 0x29, 0x00, 0x09, 0x00, 0x27, 0x00, 0x02, 0x00, 0x25, 0x00, 0x01, 0x00, 0x21, 0x00, 0x05, 0x00, 0x1c, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x14, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x07, 0x00, 0x18, 0x00, 0x06, 0x00, 0x13, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x07, 0x00, 0x09, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x01, 0x00, 0x0b, 0x00, 0xfa, 0xff, 0x0f, 0x00, 0xf4, 0xff, 0x10, 0x00, 0xf3, 0xff, 0x0e, 0x00, 0xf6, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x02, 0x00, 0x07, 0x00, 0xfb, 0xff, 0x0e, 0x00, 0xf6, 0xff, 0x10, 0x00, 0xf2, 0xff, 0x0e, 0x00, 0xf0, 0xff, 0x08, 0x00, 0xf0, 0xff, 0x02, 0x00, 0xf0, 0xff, 0xfe, 0xff, 0xef, 0xff, 0xfe, 0xff, 0xed, 0xff, 0x02, 0x00, 0xea, 0xff, 0x06, 0x00, 0xe8, 0xff, 0x0a, 0x00, 0xe8, 0xff, 0x0b, 0x00, 0xe8, 0xff, 0x08, 0x00, 0xe8, 0xff, 0x03, 0x00, 0xe8, 0xff, 0xfe, 0xff, 0xea, 0xff, 0xf9, 0xff, 0xee, 0xff, 0xf5, 0xff, 0xf2, 0xff, 0xf3, 0xff, 0xf7, 0xff, 0xf2, 0xff, 0xfb, 0xff, 0xf1, 0xff, 0xfe, 0xff, 0xf0, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x03, 0x00, 0xee, 0xff, 0x07, 0x00, 0xec, 0xff, 0x0c, 0x00, 0xe9, 0xff, 0x11, 0x00, 0xe7, 0xff, 0x16, 0x00, 0xe7, 0xff, 0x1a, 0x00, 0xe9, 0xff, 0x1c, 0x00, 0xee, 0xff, 0x1d, 0x00, 0xf3, 0xff, 0x1d, 0x00, 0xf6, 0xff, 0x1f, 0x00, 0xf7, 0xff, 0x22, 0x00, 0xf7, 0xff, 0x27, 0x00, 0xf4, 0xff, 0x2b, 0x00, 0xf3, 0xff, 0x2d, 0x00, 0xf2, 0xff, 0x2b, 0x00, 0xf5, 0xff, 0x27, 0x00, 0xf9, 0xff, 0x21, 0x00, 0xfd, 0xff, 0x1b, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x17, 0x00, 0xfc, 0xff, 0x19, 0x00, 0xf6, 0xff, 0x1b, 0x00, 0xf0, 0xff, 0x1c, 0x00, 0xed, 0xff, 0x19, 0x00, 0xec, 0xff, 0x14, 0x00, 0xed, 0xff, 0x0d, 0x00, 0xef, 0xff, 0x08, 0x00, 0xf0, 0xff, 0x07, 0x00, 0xef, 0xff, 0x0a, 0x00, 0xec, 0xff, 0x0f, 0x00, 0xe9, 0xff, 0x15, 0x00, 0xe6, 0xff, 0x19, 0x00, 0xe5, 0xff, 0x1b, 0x00, 0xe6, 0xff, 0x1a, 0x00, 0xe9, 0xff, 0x18, 0x00, 0xec, 0xff, 0x14, 0x00, 0xee, 0xff, 0x10, 0x00, 0xef, 0xff, 0x0f, 0x00, 0xed, 0xff, 0x11, 0x00, 0xea, 0xff, 0x15, 0x00, 0xe8, 0xff, 0x1a, 0x00, 0xe6, 0xff, 0x1e, 0x00, 0xe5, 0xff, 0x1d, 0x00, 0xe4, 0xff, 0x19, 0x00, 0xe5, 0xff, 0x11, 0x00, 0xe5, 0xff, 0x08, 0x00, 0xe5, 0xff, 0xff, 0xff, 0xe4, 0xff, 0xf9, 0xff, 0xe3, 0xff, 0xf6, 0xff, 0xe2, 0xff, 0xf5, 0xff, 0xe1, 0xff, 0xf6, 0xff, 0xdf, 0xff, 0xf5, 0xff, 0xde, 0xff, 0xf2, 0xff, 0xde, 0xff, 0xec, 0xff, 0xe0, 0xff, 0xe4, 0xff, 0xe3, 0xff, 0xdc, 0xff, 0xe7, 0xff, 0xd7, 0xff, 0xea, 0xff, 0xd6, 0xff, 0xed, 0xff, 0xd9, 0xff, 0xee, 0xff, 0xdf, 0xff, 0xed, 0xff, 0xe6, 0xff, 0xec, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0xee, 0xff, 0xea, 0xff, 0xef, 0xff, 0xea, 0xff, 0xef, 0xff, 0xec, 0xff, 0xf0, 0xff, 0xee, 0xff, 0xf2, 0xff, 0xf1, 0xff, 0xf6, 0xff, 0xf2, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0x02, 0x00, 0xf4, 0xff, 0x08, 0x00, 0xf5, 0xff, 0x0d, 0x00, 0xf7, 0xff, 0x10, 0x00, 0xfa, 0xff, 0x11, 0x00, 0xfd, 0xff, 0x11, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x03, 0x00, 0x06, 0x00, 0x07, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x11, 0x00, 0x09, 0x00, 0x16, 0x00, 0x08, 0x00, 0x19, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0xfc, 0xff, 0x1e, 0x00, 0xf9, 0xff, 0x22, 0x00, 0xf9, 0xff, 0x27, 0x00, 0xf9, 0xff, 0x2c, 0x00, 0xfb, 0xff, 0x31, 0x00, 0xfd, 0xff, 0x36, 0x00, 0xff, 0xff, 0x3b, 0x00, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, 0x46, 0x00, 0x01, 0x00, 0x4a, 0x00, 0x01, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x01, 0x00, 0x4a, 0x00, 0x04, 0x00, 0x48, 0x00, 0x08, 0x00, 0x46, 0x00, 0x0c, 0x00, 0x45, 0x00, 0x0f, 0x00, 0x45, 0x00, 0x10, 0x00, 0x44, 0x00, 0x0f, 0x00, 0x41, 0x00, 0x0c, 0x00, 0x3b, 0x00, 0x08, 0x00, 0x33, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x20, 0x00, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0xff, 0xff, 0x1f, 0x00, 0xfd, 0xff, 0x1c, 0x00, 0xf9, 0xff, 0x18, 0x00, 0xf6, 0xff, 0x15, 0x00, 0xf4, 0xff, 0x13, 0x00, 0xf4, 0xff, 0x15, 0x00, 0xf4, 0xff, 0x17, 0x00, 0xf5, 0xff, 0x1a, 0x00, 0xf6, 0xff, 0x19, 0x00, 0xf6, 0xff, 0x15, 0x00, 0xf6, 0xff, 0x0f, 0x00, 0xf5, 0xff, 0x09, 0x00, 0xf2, 0xff, 0x05, 0x00, 0xee, 0xff, 0x05, 0x00, 0xe8, 0xff, 0x07, 0x00, 0xe3, 0xff, 0x09, 0x00, 0xde, 0xff, 0x0a, 0x00, 0xdb, 0xff, 0x08, 0x00, 0xda, 0xff, 0x03, 0x00, 0xd9, 0xff, 0xff, 0xff, 0xd7, 0xff, 0xfb, 0xff, 0xd5, 0xff, 0xfa, 0xff, 0xd1, 0xff, 0xfa, 0xff, 0xcb, 0xff, 0xfb, 0xff, 0xc5, 0xff, 0xfd, 0xff, 0xc2, 0xff, 0xfd, 0xff, 0xc2, 0xff, 0xfd, 0xff, 0xc5, 0xff, 0xfb, 0xff, 0xcb, 0xff, 0xfa, 0xff, 0xd0, 0xff, 0xf9, 0xff, 0xd4, 0xff, 0xf8, 0xff, 0xd6, 0xff, 0xf7, 0xff, 0xd6, 0xff, 0xf6, 0xff, 0xd6, 0xff, 0xf4, 0xff, 0xd8, 0xff, 0xf3, 0xff, 0xdc, 0xff, 0xf1, 0xff, 0xe4, 0xff, 0xef, 0xff, 0xec, 0xff, 0xed, 0xff, 0xf6, 0xff, 0xec, 0xff, 0xfd, 0xff, 0xec, 0xff, 0x02, 0x00, 0xec, 0xff, 0x06, 0x00, 0xed, 0xff, 0x08, 0x00, 0xef, 0xff, 0x0a, 0x00, 0xf1, 0xff, 0x0c, 0x00, 0xf2, 0xff, 0x0e, 0x00, 0xf4, 0xff, 0x11, 0x00, 0xf4, 0xff, 0x13, 0x00, 0xf4, 0xff, 0x16, 0x00, 0xf4, 0xff, 0x19, 0x00, 0xf6, 0xff, 0x1d, 0x00, 0xfa, 0xff, 0x20, 0x00, 0xff, 0xff, 0x22, 0x00, 0x04, 0x00, 0x22, 0x00, 0x07, 0x00, 0x20, 0x00, 0x08, 0x00, 0x1c, 0x00, 0x06, 0x00, 0x18, 0x00, 0x02, 0x00, 0x16, 0x00, 0xff, 0xff, 0x16, 0x00, 0xfe, 0xff, 0x1a, 0x00, 0xff, 0xff, 0x1e, 0x00, 0x04, 0x00, 0x22, 0x00, 0x09, 0x00, 0x24, 0x00, 0x0c, 0x00, 0x23, 0x00, 0x0d, 0x00, 0x22, 0x00, 0x0b, 0x00, 0x20, 0x00, 0x08, 0x00, 0x20, 0x00, 0x06, 0x00, 0x21, 0x00, 0x05, 0x00, 0x24, 0x00, 0x06, 0x00, 0x27, 0x00, 0x07, 0x00, 0x28, 0x00, 0x07, 0x00, 0x28, 0x00, 0x06, 0x00, 0x27, 0x00, 0x04, 0x00, 0x25, 0x00, 0xff, 0xff, 0x23, 0x00, 0xfb, 0xff, 0x22, 0x00, 0xf7, 0xff, 0x20, 0x00, 0xf4, 0xff, 0x1e, 0x00, 0xf2, 0xff, 0x1c, 0x00, 0xef, 0xff, 0x19, 0x00, 0xe9, 0xff, 0x17, 0x00, 0xe3, 0xff, 0x16, 0x00, 0xdd, 0xff, 0x16, 0x00, 0xd8, 0xff, 0x15, 0x00, 0xd4, 0xff, 0x14, 0x00, 0xd2, 0xff, 0x11, 0x00, 0xd1, 0xff, 0x0d, 0x00, 0xd0, 0xff, 0x08, 0x00, 0xcf, 0xff, 0x04, 0x00, 0xcd, 0xff, 0x03, 0x00, 0xcc, 0xff, 0x03, 0x00, 0xcc, 0xff, 0x05, 0x00, 0xce, 0xff, 0x06, 0x00, 0xcf, 0xff, 0x06, 0x00, 0xd0, 0xff, 0x03, 0x00, 0xcf, 0xff, 0xff, 0xff, 0xce, 0xff, 0xfa, 0xff, 0xcd, 0xff, 0xf6, 0xff, 0xcd, 0xff, 0xf3, 0xff, 0xce, 0xff, 0xf3, 0xff, 0xd0, 0xff, 0xf4, 0xff, 0xd1, 0xff, 0xf7, 0xff, 0xd1, 0xff, 0xf9, 0xff, 0xd0, 0xff, 0xfa, 0xff, 0xcd, 0xff, 0xf9, 0xff, 0xcb, 0xff, 0xf7, 0xff, 0xc9, 0xff, 0xf3, 0xff, 0xc9, 0xff, 0xf0, 0xff, 0xca, 0xff, 0xed, 0xff, 0xcc, 0xff, 0xec, 0xff, 0xce, 0xff, 0xee, 0xff, 0xd0, 0xff, 0xf2, 0xff, 0xd1, 0xff, 0xf7, 0xff, 0xd3, 0xff, 0xfb, 0xff, 0xd6, 0xff, 0xff, 0xff, 0xdb, 0xff, 0x01, 0x00, 0xe1, 0xff, 0x03, 0x00, 0xe7, 0xff, 0x04, 0x00, 0xed, 0xff, 0x04, 0x00, 0xf2, 0xff, 0x06, 0x00, 0xf5, 0xff, 0x08, 0x00, 0xf9, 0xff, 0x0b, 0x00, 0xfc, 0xff, 0x0e, 0x00, 0x01, 0x00, 0x11, 0x00, 0x06, 0x00, 0x12, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x0f, 0x00, 0x15, 0x00, 0x12, 0x00, 0x16, 0x00, 0x13, 0x00, 0x17, 0x00, 0x13, 0x00, 0x18, 0x00, 0x13, 0x00, 0x18, 0x00, 0x13, 0x00, 0x19, 0x00, 0x14, 0x00, 0x19, 0x00, 0x15, 0x00, 0x19, 0x00, 0x13, 0x00, 0x18, 0x00, 0x12, 0x00, 0x15, 0x00, 0x10, 0x00, 0x11, 0x00, 0x11, 0x00, 0x0e, 0x00, 0x13, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x09, 0x00, 0x17, 0x00, 0x09, 0x00, 0x18, 0x00, 0x0a, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x0b, 0x00, 0x19, 0x00, 0x0b, 0x00, 0x1c, 0x00, 0x09, 0x00, 0x21, 0x00, 0x04, 0x00, 0x27, 0x00, 0xff, 0xff, 0x2c, 0x00, 0xf9, 0xff, 0x2e, 0x00, 0xf4, 0xff, 0x2e, 0x00, 0xf3, 0xff, 0x2b, 0x00, 0xf5, 0xff, 0x27, 0x00, 0xf8, 0xff, 0x22, 0x00, 0xfc, 0xff, 0x1f, 0x00, 0xfe, 0xff, 0x1f, 0x00, 0xfe, 0xff, 0x20, 0x00, 0xfc, 0xff, 0x22, 0x00, 0xf8, 0xff, 0x22, 0x00, 0xf3, 0xff, 0x1e, 0x00, 0xf0, 0xff, 0x18, 0x00, 0xef, 0xff, 0x11, 0x00, 0xef, 0xff, 0x0a, 0x00, 0xef, 0xff, 0x06, 0x00, 0xef, 0xff, 0x04, 0x00, 0xed, 0xff, 0x04, 0x00, 0xeb, 0xff, 0x05, 0x00, 0xe6, 0xff, 0x05, 0x00, 0xe2, 0xff, 0x04, 0x00, 0xde, 0xff, 0x00, 0x00, 0xdb, 0xff, 0xfb, 0xff, 0xd9, 0xff, 0xf6, 0xff, 0xd7, 0xff, 0xf4, 0xff, 0xd5, 0xff, 0xf4, 0xff, 0xd2, 0xff, 0xf6, 0xff, 0xcf, 0xff, 0xfa, 0xff, 0xcd, 0xff, 0xfd, 0xff, 0xcb, 0xff, 0x00, 0x00, 0xcc, 0xff, 0x00, 0x00, 0xcf, 0xff, 0xfe, 0xff, 0xd3, 0xff, 0xfa, 0xff, 0xd8, 0xff, 0xf7, 0xff, 0xdd, 0xff, 0xf5, 0xff, 0xe0, 0xff, 0xf6, 0xff, 0xe3, 0xff, 0xf9, 0xff, 0xe4, 0xff, 0xff, 0xff, 0xe7, 0xff, 0x04, 0x00, 0xec, 0xff, 0x06, 0x00, 0xf3, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x01, 0x00, 0x05, 0x00, 0xfd, 0xff, 0x0d, 0x00, 0xfa, 0xff, 0x12, 0x00, 0xfa, 0xff, 0x14, 0x00, 0xfd, 0xff, 0x15, 0x00, 0x02, 0x00, 0x16, 0x00, 0x07, 0x00, 0x19, 0x00, 0x09, 0x00, 0x1d, 0x00, 0x09, 0x00, 0x22, 0x00, 0x08, 0x00, 0x25, 0x00, 0x06, 0x00, 0x27, 0x00, 0x06, 0x00, 0x26, 0x00, 0x0a, 0x00, 0x22, 0x00, 0x10, 0x00, 0x1e, 0x00, 0x17, 0x00, 0x1b, 0x00, 0x1e, 0x00, 0x19, 0x00, 0x23, 0x00, 0x18, 0x00, 0x26, 0x00, 0x19, 0x00, 0x26, 0x00, 0x1a, 0x00, 0x24, 0x00, 0x1b, 0x00, 0x22, 0x00, 0x1a, 0x00, 0x20, 0x00, 0x17, 0x00, 0x1f, 0x00, 0x13, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x0a, 0x00, 0x1d, 0x00, 0x07, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x16, 0x00, 0x04, 0x00, 0x10, 0x00, 0x05, 0x00, 0x08, 0x00, 0x07, 0x00, 0x01, 0x00, 0x09, 0x00, 0xfa, 0xff, 0x09, 0x00, 0xf4, 0xff, 0x06, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xed, 0xff, 0xfb, 0xff, 0xec, 0xff, 0xf6, 0xff, 0xec, 0xff, 0xf4, 0xff, 0xed, 0xff, 0xf4, 0xff, 0xec, 0xff, 0xf7, 0xff, 0xea, 0xff, 0xf9, 0xff, 0xe6, 0xff, 0xf9, 0xff, 0xe4, 0xff, 0xf4, 0xff, 0xe4, 0xff, 0xec, 0xff, 0xe7, 0xff, 0xe2, 0xff, 0xec, 0xff, 0xda, 0xff, 0xf1, 0xff, 0xd6, 0xff, 0xf5, 0xff, 0xd6, 0xff, 0xf5, 0xff, 0xd8, 0xff, 0xf4, 0xff, 0xdb, 0xff, 0xf1, 0xff, 0xdb, 0xff, 0xf0, 0xff, 0xd8, 0xff, 0xf0, 0xff, 0xd2, 0xff, 0xf3, 0xff, 0xca, 0xff, 0xf6, 0xff, 0xc3, 0xff, 0xfa, 0xff, 0xbf, 0xff, 0xfb, 0xff, 0xc0, 0xff, 0xf9, 0xff, 0xc4, 0xff, 0xf5, 0xff, 0xca, 0xff, 0xf2, 0xff, 0xd1, 0xff, 0xf1, 0xff, 0xd6, 0xff, 0xf2, 0xff, 0xd9, 0xff, 0xf6, 0xff, 0xd8, 0xff, 0xfb, 0xff, 0xd6, 0xff, 0xfe, 0xff, 0xd5, 0xff, 0x00, 0x00, 0xd6, 0xff, 0x00, 0x00, 0xdb, 0xff, 0xfd, 0xff, 0xe4, 0xff, 0xfb, 0xff, 0xee, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x0a, 0x00, 0xf7, 0xff, 0x0c, 0x00, 0xf8, 0xff, 0x0d, 0x00, 0xfe, 0xff, 0x0e, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0x16, 0x00, 0x10, 0x00, 0x1a, 0x00, 0x13, 0x00, 0x1a, 0x00, 0x19, 0x00, 0x18, 0x00, 0x1e, 0x00, 0x16, 0x00, 0x22, 0x00, 0x16, 0x00, 0x24, 0x00, 0x19, 0x00, 0x23, 0x00, 0x1d, 0x00, 0x21, 0x00, 0x23, 0x00, 0x1f, 0x00, 0x28, 0x00, 0x1d, 0x00, 0x2b, 0x00, 0x1e, 0x00, 0x2d, 0x00, 0x22, 0x00, 0x2f, 0x00, 0x29, 0x00, 0x32, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x33, 0x00, 0x38, 0x00, 0x32, 0x00, 0x39, 0x00, 0x2d, 0x00, 0x39, 0x00, 0x26, 0x00, 0x38, 0x00, 0x1f, 0x00, 0x37, 0x00, 0x1a, 0x00, 0x36, 0x00, 0x18, 0x00, 0x36, 0x00, 0x18, 0x00, 0x35, 0x00, 0x19, 0x00, 0x35, 0x00, 0x19, 0x00, 0x34, 0x00, 0x17, 0x00, 0x32, 0x00, 0x13, 0x00, 0x2e, 0x00, 0x0e, 0x00, 0x28, 0x00, 0x07, 0x00, 0x20, 0x00, 0x02, 0x00, 0x18, 0x00, 0xff, 0xff, 0x11, 0x00, 0xfd, 0xff, 0x0b, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfb, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xf7, 0xff, 0xf9, 0xff, 0xf2, 0xff, 0xf6, 0xff, 0xef, 0xff, 0xf4, 0xff, 0xec, 0xff, 0xf1, 0xff, 0xe7, 0xff, 0xef, 0xff, 0xe2, 0xff, 0xef, 0xff, 0xdd, 0xff, 0xf1, 0xff, 0xda, 0xff, 0xf4, 0xff, 0xd9, 0xff, 0xf6, 0xff, 0xdc, 0xff, 0xf7, 0xff, 0xe1, 0xff, 0xf7, 0xff, 0xe7, 0xff, 0xf5, 0xff, 0xec, 0xff, 0xf4, 0xff, 0xef, 0xff, 0xf4, 0xff, 0xf0, 0xff, 0xf7, 0xff, 0xef, 0xff, 0xfa, 0xff, 0xf0, 0xff, 0xfe, 0xff, 0xf2, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xfe, 0xff, 0x0e, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0d, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x01, 0x00, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xf7, 0xff, 0x05, 0x00, 0xf5, 0xff, 0x03, 0x00, 0xf5, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xf5, 0xff, 0xfa, 0xff, 0xf2, 0xff, 0xfb, 0xff, 0xf0, 0xff, 0xfb, 0xff, 0xf1, 0xff, 0xf9, 0xff, 0xf5, 0xff, 0xf6, 0xff, 0xf9, 0xff, 0xf4, 0xff, 0xfe, 0xff, 0xf3, 0xff, 0x02, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xf9, 0xff, 0x0e, 0x00, 0xf4, 0xff, 0x15, 0x00, 0xef, 0xff, 0x1c, 0x00, 0xeb, 0xff, 0x22, 0x00, 0xe8, 0xff, 0x25, 0x00, 0xe7, 0xff, 0x26, 0x00, 0xe9, 0xff, 0x26, 0x00, 0xeb, 0xff, 0x26, 0x00, 0xec, 0xff, 0x26, 0x00, 0xec, 0xff, 0x28, 0x00, 0xe8, 0xff, 0x2a, 0x00, 0xe3, 0xff, 0x2c, 0x00, 0xde, 0xff, 0x2e, 0x00, 0xda, 0xff, 0x2d, 0x00, 0xd8, 0xff, 0x2a, 0x00, 0xd8, 0xff, 0x25, 0x00, 0xda, 0xff, 0x20, 0x00, 0xdc, 0xff, 0x1a, 0x00, 0xde, 0xff, 0x14, 0x00, 0xde, 0xff, 0x10, 0x00, 0xdc, 0xff, 0x0b, 0x00, 0xd9, 0xff, 0x08, 0x00, 0xd6, 0xff, 0x04, 0x00, 0xd5, 0xff, 0x00, 0x00, 0xd7, 0xff, 0xfa, 0xff, 0xda, 0xff, 0xf4, 0xff, 0xe0, 0xff, 0xed, 0xff, 0xe5, 0xff, 0xe6, 0xff, 0xe9, 0xff, 0xe0, 0xff, 0xea, 0xff, 0xdc, 0xff, 0xe8, 0xff, 0xd9, 0xff, 0xe7, 0xff, 0xd9, 0xff, 0xe6, 0xff, 0xda, 0xff, 0xe8, 0xff, 0xda, 0xff, 0xed, 0xff, 0xd9, 0xff, 0xf3, 0xff, 0xd6, 0xff, 0xfa, 0xff, 0xd2, 0xff, 0x01, 0x00, 0xce, 0xff, 0x05, 0x00, 0xcb, 0xff, 0x06, 0x00, 0xcb, 0xff, 0x05, 0x00, 0xce, 0xff, 0x03, 0x00, 0xd2, 0xff, 0x03, 0x00, 0xd4, 0xff, 0x05, 0x00, 0xd4, 0xff, 0x09, 0x00, 0xd0, 0xff, 0x0f, 0x00, 0xcc, 0xff, 0x13, 0x00, 0xc7, 0xff, 0x16, 0x00, 0xc5, 0xff, 0x17, 0x00, 0xc7, 0xff, 0x17, 0x00, 0xcb, 0xff, 0x17, 0x00, 0xd1, 0xff, 0x18, 0x00, 0xd4, 0xff, 0x1b, 0x00, 0xd6, 0xff, 0x1e, 0x00, 0xd6, 0xff, 0x21, 0x00, 0xd6, 0xff, 0x21, 0x00, 0xd8, 0xff, 0x1e, 0x00, 0xde, 0xff, 0x1a, 0x00, 0xe7, 0xff, 0x17, 0x00, 0xf1, 0xff, 0x15, 0x00, 0xfb, 0xff, 0x16, 0x00, 0x02, 0x00, 0x18, 0x00, 0x06, 0x00, 0x19, 0x00, 0x08, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x16, 0x00, 0x0f, 0x00, 0x12, 0x00, 0x16, 0x00, 0x0e, 0x00, 0x20, 0x00, 0x0b, 0x00, 0x2b, 0x00, 0x0b, 0x00, 0x35, 0x00, 0x0c, 0x00, 0x3b, 0x00, 0x0d, 0x00, 0x3d, 0x00, 0x0c, 0x00, 0x3c, 0x00, 0x09, 0x00, 0x3a, 0x00, 0x05, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3b, 0x00, 0xfb, 0xff, 0x3f, 0x00, 0xf6, 0xff, 0x44, 0x00, 0xf3, 0xff, 0x49, 0x00, 0xf0, 0xff, 0x4c, 0x00, 0xee, 0xff, 0x4c, 0x00, 0xed, 0xff, 0x49, 0x00, 0xed, 0xff, 0x43, 0x00, 0xec, 0xff, 0x3c, 0x00, 0xea, 0xff, 0x36, 0x00, 0xe6, 0xff, 0x32, 0x00, 0xe0, 0xff, 0x30, 0x00, 0xd9, 0xff, 0x2f, 0x00, 0xd2, 0xff, 0x2e, 0x00, 0xcc, 0xff, 0x2c, 0x00, 0xca, 0xff, 0x28, 0x00, 0xcb, 0xff, 0x23, 0x00, 0xce, 0xff, 0x1c, 0x00, 0xd1, 0xff, 0x16, 0x00, 0xd1, 0xff, 0x10, 0x00, 0xce, 0xff, 0x0c, 0x00, 0xc9, 0xff, 0x09, 0x00, 0xc4, 0xff, 0x07, 0x00, 0xc1, 0xff, 0x05, 0x00, 0xc2, 0xff, 0x04, 0x00, 0xc7, 0xff, 0x02, 0x00, 0xce, 0xff, 0xfe, 0xff, 0xd6, 0xff, 0xfa, 0xff, 0xdb, 0xff, 0xf5, 0xff, 0xde, 0xff, 0xf0, 0xff, 0xdd, 0xff, 0xed, 0xff, 0xdc, 0xff, 0xea, 0xff, 0xdb, 0xff, 0xe8, 0xff, 0xdf, 0xff, 0xe5, 0xff, 0xe7, 0xff, 0xe1, 0xff, 0xf2, 0xff, 0xdc, 0xff, 0xfd, 0xff, 0xd7, 0xff, 0x07, 0x00, 0xd0, 0xff, 0x0f, 0x00, 0xc9, 0xff, 0x13, 0x00, 0xc3, 0xff, 0x14, 0x00, 0xbf, 0xff, 0x14, 0x00, 0xbd, 0xff, 0x14, 0x00, 0xbf, 0xff, 0x14, 0x00, 0xc2, 0xff, 0x17, 0x00, 0xc6, 0xff, 0x1d, 0x00, 0xc8, 0xff, 0x23, 0x00, 0xc9, 0xff, 0x2a, 0x00, 0xca, 0xff, 0x30, 0x00, 0xca, 0xff, 0x32, 0x00, 0xcc, 0xff, 0x31, 0x00, 0xd0, 0xff, 0x2e, 0x00, 0xd5, 0xff, 0x2b, 0x00, 0xde, 0xff, 0x2a, 0x00, 0xe7, 0xff, 0x2c, 0x00, 0xf1, 0xff, 0x30, 0x00, 0xf9, 0xff, 0x34, 0x00, 0xfd, 0xff, 0x38, 0x00, 0xff, 0xff, 0x39, 0x00, 0xff, 0xff, 0x37, 0x00, 0xff, 0xff, 0x31, 0x00, 0x01, 0x00, 0x2c, 0x00, 0x05, 0x00, 0x28, 0x00, 0x0a, 0x00, 0x27, 0x00, 0x10, 0x00, 0x29, 0x00, 0x14, 0x00, 0x2c, 0x00, 0x16, 0x00, 0x2e, 0x00, 0x16, 0x00, 0x2e, 0x00, 0x14, 0x00, 0x2b, 0x00, 0x13, 0x00, 0x28, 0x00, 0x14, 0x00, 0x26, 0x00, 0x17, 0x00, 0x25, 0x00, 0x1d, 0x00, 0x26, 0x00, 0x22, 0x00, 0x27, 0x00, 0x27, 0x00, 0x28, 0x00, 0x28, 0x00, 0x27, 0x00, 0x28, 0x00, 0x25, 0x00, 0x26, 0x00, 0x21, 0x00, 0x25, 0x00, 0x1e, 0x00, 0x25, 0x00, 0x1c, 0x00, 0x27, 0x00, 0x1b, 0x00, 0x2b, 0x00, 0x1a, 0x00, 0x2f, 0x00, 0x19, 0x00, 0x32, 0x00, 0x15, 0x00, 0x32, 0x00, 0x11, 0x00, 0x30, 0x00, 0x0c, 0x00, 0x2b, 0x00, 0x08, 0x00, 0x26, 0x00, 0x06, 0x00, 0x22, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x04, 0x00, 0x1b, 0x00, 0x03, 0x00, 0x18, 0x00, 0x02, 0x00, 0x16, 0x00, 0x00, 0x00, 0x13, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xf9, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf0, 0xff, 0xf8, 0xff, 0xe9, 0xff, 0xf8, 0xff, 0xe4, 0xff, 0xf8, 0xff, 0xdf, 0xff, 0xf8, 0xff, 0xda, 0xff, 0xfa, 0xff, 0xd7, 0xff, 0xfc, 0xff, 0xd3, 0xff, 0xfd, 0xff, 0xd0, 0xff, 0xfd, 0xff, 0xce, 0xff, 0xfd, 0xff, 0xcc, 0xff, 0xfb, 0xff, 0xcc, 0xff, 0xf9, 0xff, 0xcc, 0xff, 0xf8, 0xff, 0xce, 0xff, 0xf9, 0xff, 0xd1, 0xff, 0xfa, 0xff, 0xd4, 0xff, 0xfb, 0xff, 0xd6, 0xff, 0xfd, 0xff, 0xd6, 0xff, 0xff, 0xff, 0xd6, 0xff, 0x00, 0x00, 0xd6, 0xff, 0x01, 0x00, 0xd7, 0xff, 0x00, 0x00, 0xd9, 0xff, 0xff, 0xff, 0xde, 0xff, 0xfe, 0xff, 0xe3, 0xff, 0xfd, 0xff, 0xe8, 0xff, 0xfd, 0xff, 0xeb, 0xff, 0xfe, 0xff, 0xed, 0xff, 0x00, 0x00, 0xed, 0xff, 0x01, 0x00, 0xec, 0xff, 0x01, 0x00, 0xec, 0xff, 0xff, 0xff, 0xef, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0xfa, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x13, 0x00, 0x02, 0x00, 0x1b, 0x00, 0x01, 0x00, 0x21, 0x00, 0x03, 0x00, 0x24, 0x00, 0x05, 0x00, 0x26, 0x00, 0x07, 0x00, 0x25, 0x00, 0x07, 0x00, 0x24, 0x00, 0x06, 0x00, 0x23, 0x00, 0x03, 0x00, 0x26, 0x00, 0x00, 0x00, 0x2b, 0x00, 0xfd, 0xff, 0x33, 0x00, 0xfc, 0xff, 0x3a, 0x00, 0xfb, 0xff, 0x3f, 0x00, 0xfb, 0xff, 0x41, 0x00, 0xf9, 0xff, 0x40, 0x00, 0xf6, 0xff, 0x3c, 0x00, 0xf1, 0xff, 0x38, 0x00, 0xeb, 0xff, 0x34, 0x00, 0xe6, 0xff, 0x31, 0x00, 0xe2, 0xff, 0x31, 0x00, 0xe0, 0xff, 0x32, 0x00, 0xdf, 0xff, 0x34, 0x00, 0xdf, 0xff, 0x34, 0x00, 0xde, 0xff, 0x34, 0x00, 0xda, 0xff, 0x31, 0x00, 0xd6, 0xff, 0x2b, 0x00, 0xd1, 0xff, 0x25, 0x00, 0xcd, 0xff, 0x1f, 0x00, 0xcb, 0xff, 0x1a, 0x00, 0xcb, 0xff, 0x19, 0x00, 0xcc, 0xff, 0x19, 0x00, 0xce, 0xff, 0x1a, 0x00, 0xd0, 0xff, 0x1a, 0x00, 0xd3, 0xff, 0x18, 0x00, 0xd6, 0xff, 0x13, 0x00, 0xd9, 0xff, 0x0e, 0x00, 0xdb, 0xff, 0x07, 0x00, 0xdd, 0xff, 0x02, 0x00, 0xdf, 0xff, 0xfc, 0xff, 0xe2, 0xff, 0xf8, 0xff, 0xe4, 0xff, 0xf6, 0xff, 0xe8, 0xff, 0xf3, 0xff, 0xeb, 0xff, 0xf1, 0xff, 0xee, 0xff, 0xef, 0xff, 0xf1, 0xff, 0xeb, 0xff, 0xf4, 0xff, 0xe5, 0xff, 0xf6, 0xff, 0xdf, 0xff, 0xf9, 0xff, 0xd9, 0xff, 0xfa, 0xff, 0xd4, 0xff, 0xfc, 0xff, 0xd1, 0xff, 0xfe, 0xff, 0xd0, 0xff, 0xff, 0xff, 0xd0, 0xff, 0x01, 0x00, 0xd1, 0xff, 0x02, 0x00, 0xd2, 0xff, 0x02, 0x00, 0xd1, 0xff, 0x02, 0x00, 0xce, 0xff, 0x03, 0x00, 0xca, 0xff, 0x04, 0x00, 0xc6, 0xff, 0x05, 0x00, 0xc4, 0xff, 0x07, 0x00, 0xc3, 0xff, 0x08, 0x00, 0xc5, 0xff, 0x09, 0x00, 0xc8, 0xff, 0x0a, 0x00, 0xcc, 0xff, 0x0b, 0x00, 0xcf, 0xff, 0x0d, 0x00, 0xd0, 0xff, 0x10, 0x00, 0xcf, 0xff, 0x13, 0x00, 0xcd, 0xff, 0x15, 0x00, 0xcc, 0xff, 0x16, 0x00, 0xce, 0xff, 0x16, 0x00, 0xd2, 0xff, 0x15, 0x00, 0xd7, 0xff, 0x14, 0x00, 0xdd, 0xff, 0x15, 0x00, 0xe1, 0xff, 0x18, 0x00, 0xe4, 0xff, 0x1d, 0x00, 0xe4, 0xff, 0x22, 0x00, 0xe3, 0xff, 0x25, 0x00, 0xe2, 0xff, 0x25, 0x00, 0xe1, 0xff, 0x23, 0x00, 0xe3, 0xff, 0x1f, 0x00, 0xe7, 0xff, 0x1a, 0x00, 0xed, 0xff, 0x16, 0x00, 0xf2, 0xff, 0x13, 0x00, 0xf6, 0xff, 0x12, 0x00, 0xf7, 0xff, 0x12, 0x00, 0xf7, 0xff, 0x14, 0x00, 0xf7, 0xff, 0x16, 0x00, 0xf7, 0xff, 0x15, 0x00, 0xfa, 0xff, 0x12, 0x00, 0xfe, 0xff, 0x0d, 0x00, 0x02, 0x00, 0x08, 0x00, 0x06, 0x00, 0x04, 0x00, 0x09, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x0b, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x12, 0x00, 0x12, 0x00, 0x12, 0x00, 0x15, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x09, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x06, 0x00, 0x1c, 0x00, 0x0b, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x09, 0x00, 0x1d, 0x00, 0x02, 0x00, 0x1f, 0x00, 0xfb, 0xff, 0x20, 0x00, 0xf4, 0xff, 0x20, 0x00, 0xf1, 0xff, 0x1f, 0x00, 0xf0, 0xff, 0x1c, 0x00, 0xf1, 0xff, 0x19, 0x00, 0xf3, 0xff, 0x17, 0x00, 0xf4, 0xff, 0x15, 0x00, 0xf2, 0xff, 0x15, 0x00, 0xee, 0xff, 0x16, 0x00, 0xe9, 0xff, 0x17, 0x00, 0xe5, 0xff, 0x18, 0x00, 0xe4, 0xff, 0x16, 0x00, 0xe6, 0xff, 0x13, 0x00, 0xea, 0xff, 0x0f, 0x00, 0xed, 0xff, 0x0a, 0x00, 0xf0, 0xff, 0x06, 0x00, 0xf1, 0xff, 0x04, 0x00, 0xf1, 0xff, 0x04, 0x00, 0xf2, 0xff, 0x05, 0x00, 0xf3, 0xff, 0x05, 0x00, 0xf6, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x02, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x0d, 0x00, 0xf5, 0xff, 0x13, 0x00, 0xf4, 0xff, 0x17, 0x00, 0xf6, 0xff, 0x19, 0x00, 0xfb, 0xff, 0x19, 0x00, 0x00, 0x00, 0x18, 0x00, 0x05, 0x00, 0x16, 0x00, 0x08, 0x00, 0x16, 0x00, 0x08, 0x00, 0x17, 0x00, 0x06, 0x00, 0x18, 0x00, 0x03, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x18, 0x00, 0x04, 0x00, 0x16, 0x00, 0x0a, 0x00, 0x13, 0x00, 0x11, 0x00, 0x10, 0x00, 0x16, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x09, 0x00, 0x11, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x13, 0x00, 0x14, 0x00, 0x17, 0x00, 0x14, 0x00, 0x19, 0x00, 0x13, 0x00, 0x18, 0x00, 0x13, 0x00, 0x16, 0x00, 0x13, 0x00, 0x14, 0x00, 0x12, 0x00, 0x13, 0x00, 0x11, 0x00, 0x15, 0x00, 0x0f, 0x00, 0x1a, 0x00, 0x0c, 0x00, 0x1f, 0x00, 0x09, 0x00, 0x23, 0x00, 0x05, 0x00, 0x25, 0x00, 0x01, 0x00, 0x24, 0x00, 0xfd, 0xff, 0x22, 0x00, 0xf9, 0xff, 0x1f, 0x00, 0xf6, 0xff, 0x1d, 0x00, 0xf4, 0xff, 0x1c, 0x00, 0xf0, 0xff, 0x1e, 0x00, 0xec, 0xff, 0x1f, 0x00, 0xe7, 0xff, 0x20, 0x00, 0xe3, 0xff, 0x20, 0x00, 0xe1, 0xff, 0x1d, 0x00, 0xe1, 0xff, 0x18, 0x00, 0xe2, 0xff, 0x14, 0x00, 0xe5, 0xff, 0x0f, 0x00, 0xe8, 0xff, 0x0b, 0x00, 0xe8, 0xff, 0x08, 0x00, 0xe7, 0xff, 0x05, 0x00, 0xe5, 0xff, 0x03, 0x00, 0xe2, 0xff, 0x02, 0x00, 0xe0, 0xff, 0x00, 0x00, 0xe1, 0xff, 0xfc, 0xff, 0xe4, 0xff, 0xf7, 0xff, 0xe9, 0xff, 0xf1, 0xff, 0xee, 0xff, 0xeb, 0xff, 0xf2, 0xff, 0xe5, 0xff, 0xf3, 0xff, 0xe0, 0xff, 0xf2, 0xff, 0xdd, 0xff, 0xf1, 0xff, 0xdb, 0xff, 0xf0, 0xff, 0xd9, 0xff, 0xf1, 0xff, 0xd8, 0xff, 0xf4, 0xff, 0xd7, 0xff, 0xf7, 0xff, 0xd4, 0xff, 0xfb, 0xff, 0xd1, 0xff, 0xfd, 0xff, 0xcd, 0xff, 0xfe, 0xff, 0xc9, 0xff, 0xfe, 0xff, 0xc7, 0xff, 0xfd, 0xff, 0xc7, 0xff, 0xfc, 0xff, 0xc9, 0xff, 0xfc, 0xff, 0xcc, 0xff, 0xfd, 0xff, 0xce, 0xff, 0xfe, 0xff, 0xd0, 0xff, 0x00, 0x00, 0xd0, 0xff, 0x01, 0x00, 0xcf, 0xff, 0x01, 0x00, 0xce, 0xff, 0x01, 0x00, 0xcd, 0xff, 0x01, 0x00, 0xcc, 0xff, 0x02, 0x00, 0xcc, 0xff, 0x04, 0x00, 0xcd, 0xff, 0x06, 0x00, 0xcf, 0xff, 0x07, 0x00, 0xd1, 0xff, 0x09, 0x00, 0xd3, 0xff, 0x0b, 0x00, 0xd4, 0xff, 0x0d, 0x00, 0xd4, 0xff, 0x11, 0x00, 0xd4, 0xff, 0x14, 0x00, 0xd4, 0xff, 0x16, 0x00, 0xd7, 0xff, 0x17, 0x00, 0xdb, 0xff, 0x18, 0x00, 0xe0, 0xff, 0x1a, 0x00, 0xe5, 0xff, 0x1c, 0x00, 0xea, 0xff, 0x1f, 0x00, 0xef, 0xff, 0x22, 0x00, 0xf4, 0xff, 0x24, 0x00, 0xf8, 0xff, 0x24, 0x00, 0xfd, 0xff, 0x22, 0x00, 0x02, 0x00, 0x20, 0x00, 0x07, 0x00, 0x1d, 0x00, 0x0c, 0x00, 0x1a, 0x00, 0x11, 0x00, 0x1a, 0x00, 0x15, 0x00, 0x1b, 0x00, 0x17, 0x00, 0x1d, 0x00, 0x18, 0x00, 0x1f, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x20, 0x00, 0x18, 0x00, 0x23, 0x00, 0x14, 0x00, 0x24, 0x00, 0x10, 0x00, 0x23, 0x00, 0x0f, 0x00, 0x21, 0x00, 0x0e, 0x00, 0x1f, 0x00, 0x0e, 0x00, 0x1d, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x0c, 0x00, 0x1d, 0x00, 0x08, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x21, 0x00, 0xfe, 0xff, 0x22, 0x00, 0xfa, 0xff, 0x21, 0x00, 0xf7, 0xff, 0x1e, 0x00, 0xf4, 0xff, 0x1a, 0x00, 0xf2, 0xff, 0x16, 0x00, 0xef, 0xff, 0x13, 0x00, 0xed, 0xff, 0x12, 0x00, 0xe9, 0xff, 0x12, 0x00, 0xe5, 0xff, 0x13, 0x00, 0xe1, 0xff, 0x13, 0x00, 0xde, 0xff, 0x12, 0x00, 0xdb, 0xff, 0x0f, 0x00, 0xd9, 0xff, 0x0b, 0x00, 0xd8, 0xff, 0x06, 0x00, 0xd6, 0xff, 0x03, 0x00, 0xd5, 0xff, 0x01, 0x00, 0xd4, 0xff, 0x01, 0x00, 0xd3, 0xff, 0x01, 0x00, 0xd3, 0xff, 0x01, 0x00, 0xd3, 0xff, 0x00, 0x00, 0xd2, 0xff, 0xff, 0xff, 0xd2, 0xff, 0xfd, 0xff, 0xd3, 0xff, 0xfa, 0xff, 0xd4, 0xff, 0xf5, 0xff, 0xd6, 0xff, 0xef, 0xff, 0xd7, 0xff, 0xe9, 0xff, 0xd8, 0xff, 0xe4, 0xff, 0xd9, 0xff, 0xe1, 0xff, 0xdc, 0xff, 0xde, 0xff, 0xe0, 0xff, 0xdc, 0xff, 0xe5, 0xff, 0xda, 0xff, 0xea, 0xff, 0xd8, 0xff, 0xed, 0xff, 0xd6, 0xff, 0xef, 0xff, 0xd4, 0xff, 0xf0, 0xff, 0xd4, 0xff, 0xf0, 0xff, 0xd5, 0xff, 0xf2, 0xff, 0xd7, 0xff, 0xf5, 0xff, 0xda, 0xff, 0xfa, 0xff, 0xde, 0xff, 0x00, 0x00, 0xe1, 0xff, 0x06, 0x00, 0xe5, 0xff, 0x0a, 0x00, 0xe9, 0xff, 0x0b, 0x00, 0xee, 0xff, 0x0a, 0x00, 0xf3, 0xff, 0x09, 0x00, 0xf9, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x0c, 0x00, 0x01, 0x00, 0x11, 0x00, 0x02, 0x00, 0x17, 0x00, 0x02, 0x00, 0x1d, 0x00, 0x02, 0x00, 0x22, 0x00, 0x02, 0x00, 0x23, 0x00, 0x02, 0x00, 0x22, 0x00, 0x04, 0x00, 0x20, 0x00, 0x05, 0x00, 0x1f, 0x00, 0x06, 0x00, 0x20, 0x00, 0x05, 0x00, 0x23, 0x00, 0x03, 0x00, 0x26, 0x00, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x01, 0x00, 0x25, 0x00, 0x03, 0x00, 0x20, 0x00, 0x06, 0x00, 0x1a, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x0d, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x11, 0x00, 0x0f, 0x00, 0x12, 0x00, 0x0d, 0x00, 0x13, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x06, 0x00, 0x16, 0x00, 0x02, 0x00, 0x19, 0x00, 0xfe, 0xff, 0x1b, 0x00, 0xf9, 0xff, 0x1c, 0x00, 0xf5, 0xff, 0x1c, 0x00, 0xf1, 0xff, 0x1c, 0x00, 0xec, 0xff, 0x1d, 0x00, 0xe9, 0xff, 0x1d, 0x00, 0xe7, 0xff, 0x1d, 0x00, 0xe5, 0xff, 0x1e, 0x00, 0xe5, 0xff, 0x1f, 0x00, 0xe5, 0xff, 0x20, 0x00, 0xe5, 0xff, 0x20, 0x00, 0xe4, 0xff, 0x20, 0x00, 0xe1, 0xff, 0x1f, 0x00, 0xdd, 0xff, 0x1f, 0x00, 0xd9, 0xff, 0x20, 0x00, 0xd5, 0xff, 0x21, 0x00, 0xd4, 0xff, 0x22, 0x00, 0xd4, 0xff, 0x23, 0x00, 0xd5, 0xff, 0x23, 0x00, 0xd6, 0xff, 0x22, 0x00, 0xd7, 0xff, 0x21, 0x00, 0xd8, 0xff, 0x1f, 0x00, 0xd9, 0xff, 0x1d, 0x00, 0xd9, 0xff, 0x1a, 0x00, 0xd9, 0xff, 0x19, 0x00, 0xda, 0xff, 0x18, 0x00, 0xdd, 0xff, 0x17, 0x00, 0xe1, 0xff, 0x14, 0x00, 0xe6, 0xff, 0x10, 0x00, 0xec, 0xff, 0x0a, 0x00, 0xf1, 0xff, 0x05, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xfa, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x09, 0x00, 0xf9, 0xff, 0x10, 0x00, 0xf7, 0xff, 0x1a, 0x00, 0xf4, 0xff, 0x23, 0x00, 0xf0, 0xff, 0x2b, 0x00, 0xeb, 0xff, 0x30, 0x00, 0xe6, 0xff, 0x32, 0x00, 0xe1, 0xff, 0x33, 0x00, 0xdf, 0xff, 0x32, 0x00, 0xde, 0xff, 0x32, 0x00, 0xde, 0xff, 0x33, 0x00, 0xdd, 0xff, 0x36, 0x00, 0xdb, 0xff, 0x3b, 0x00, 0xd9, 0xff, 0x41, 0x00, 0xd6, 0xff, 0x44, 0x00, 0xd4, 0xff, 0x45, 0x00, 0xd3, 0xff, 0x43, 0x00, 0xd3, 0xff, 0x3e, 0x00, 0xd6, 0xff, 0x3a, 0x00, 0xda, 0xff, 0x37, 0x00, 0xdf, 0xff, 0x37, 0x00, 0xe4, 0xff, 0x38, 0x00, 0xe8, 0xff, 0x3a, 0x00, 0xec, 0xff, 0x3b, 0x00, 0xf1, 0xff, 0x3b, 0x00, 0xf6, 0xff, 0x39, 0x00, 0xfd, 0xff, 0x37, 0x00, 0x04, 0x00, 0x35, 0x00, 0x0b, 0x00, 0x36, 0x00, 0x11, 0x00, 0x37, 0x00, 0x17, 0x00, 0x38, 0x00, 0x1b, 0x00, 0x36, 0x00, 0x1f, 0x00, 0x33, 0x00, 0x22, 0x00, 0x2e, 0x00, 0x25, 0x00, 0x29, 0x00, 0x28, 0x00, 0x25, 0x00, 0x2b, 0x00, 0x23, 0x00, 0x2d, 0x00, 0x22, 0x00, 0x2d, 0x00, 0x21, 0x00, 0x2c, 0x00, 0x1e, 0x00, 0x29, 0x00, 0x1a, 0x00, 0x25, 0x00, 0x13, 0x00, 0x22, 0x00, 0x0b, 0x00, 0x20, 0x00, 0x03, 0x00, 0x1f, 0x00, 0xfd, 0xff, 0x1e, 0x00, 0xf9, 0xff, 0x1c, 0x00, 0xf7, 0xff, 0x1a, 0x00, 0xf4, 0xff, 0x17, 0x00, 0xf0, 0xff, 0x15, 0x00, 0xea, 0xff, 0x12, 0x00, 0xe5, 0xff, 0x11, 0x00, 0xe0, 0xff, 0x10, 0x00, 0xdd, 0xff, 0x0f, 0x00, 0xdb, 0xff, 0x0d, 0x00, 0xdb, 0xff, 0x0b, 0x00, 0xda, 0xff, 0x08, 0x00, 0xda, 0xff, 0x06, 0x00, 0xd9, 0xff, 0x04, 0x00, 0xd8, 0xff, 0x04, 0x00, 0xd6, 0xff, 0x04, 0x00, 0xd3, 0xff, 0x03, 0x00, 0xd1, 0xff, 0x02, 0x00, 0xce, 0xff, 0x00, 0x00, 0xcc, 0xff, 0xfd, 0xff, 0xcb, 0xff, 0xfb, 0xff, 0xca, 0xff, 0xfb, 0xff, 0xcc, 0xff, 0xfb, 0xff, 0xce, 0xff, 0xfc, 0xff, 0xd1, 0xff, 0xfb, 0xff, 0xd3, 0xff, 0xf9, 0xff, 0xd4, 0xff, 0xf6, 0xff, 0xd2, 0xff, 0xf2, 0xff, 0xcf, 0xff, 0xee, 0xff, 0xcd, 0xff, 0xeb, 0xff, 0xcb, 0xff, 0xea, 0xff, 0xcd, 0xff, 0xe9, 0xff, 0xd2, 0xff, 0xe8, 0xff, 0xd9, 0xff, 0xe7, 0xff, 0xe1, 0xff, 0xe5, 0xff, 0xe8, 0xff, 0xe3, 0xff, 0xed, 0xff, 0xe0, 0xff, 0xf0, 0xff, 0xde, 0xff, 0xf2, 0xff, 0xdb, 0xff, 0xf4, 0xff, 0xd8, 0xff, 0xf7, 0xff, 0xd7, 0xff, 0xfc, 0xff, 0xd8, 0xff, 0x01, 0x00, 0xda, 0xff, 0x08, 0x00, 0xdd, 0xff, 0x0d, 0x00, 0xe0, 0xff, 0x12, 0x00, 0xe1, 0xff, 0x15, 0x00, 0xe0, 0xff, 0x17, 0x00, 0xdd, 0xff, 0x1a, 0x00, 0xda, 0xff, 0x1c, 0x00, 0xd8, 0xff, 0x1d, 0x00, 0xd8, 0xff, 0x1e, 0x00, 0xdb, 0xff, 0x1f, 0x00, 0xe1, 0xff, 0x21, 0x00, 0xe7, 0xff, 0x23, 0x00, 0xed, 0xff, 0x24, 0x00, 0xf0, 0xff, 0x25, 0x00, 0xf0, 0xff, 0x24, 0x00, 0xef, 0xff, 0x21, 0x00, 0xed, 0xff, 0x1d, 0x00, 0xee, 0xff, 0x19, 0x00, 0xf1, 0xff, 0x16, 0x00, 0xf8, 0xff, 0x15, 0x00, 0x00, 0x00, 0x14, 0x00, 0x07, 0x00, 0x15, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x11, 0x00, 0x0f, 0x00, 0x12, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x07, 0x00, 0x16, 0x00, 0x04, 0x00, 0x19, 0x00, 0x03, 0x00, 0x1d, 0x00, 0x03, 0x00, 0x20, 0x00, 0x03, 0x00, 0x22, 0x00, 0x02, 0x00, 0x22, 0x00, 0x01, 0x00, 0x21, 0x00, 0x00, 0x00, 0x1f, 0x00, 0xfe, 0xff, 0x1c, 0x00, 0xfc, 0xff, 0x18, 0x00, 0xfa, 0xff, 0x15, 0x00, 0xf8, 0xff, 0x13, 0x00, 0xf6, 0xff, 0x12, 0x00, 0xf3, 0xff, 0x12, 0x00, 0xf1, 0xff, 0x12, 0x00, 0xee, 0xff, 0x10, 0x00, 0xed, 0xff, 0x0d, 0x00, 0xed, 0xff, 0x09, 0x00, 0xed, 0xff, 0x04, 0x00, 0xec, 0xff, 0x01, 0x00, 0xeb, 0xff, 0xff, 0xff, 0xea, 0xff, 0xff, 0xff, 0xe8, 0xff, 0xff, 0xff, 0xe7, 0xff, 0x01, 0x00, 0xe7, 0xff, 0x01, 0x00, 0xe7, 0xff, 0x01, 0x00, 0xe8, 0xff, 0x00, 0x00, 0xea, 0xff, 0xfe, 0xff, 0xeb, 0xff, 0xfc, 0xff, 0xeb, 0xff, 0xfc, 0xff, 0xea, 0xff, 0xfd, 0xff, 0xea, 0xff, 0x00, 0x00, 0xea, 0xff, 0x01, 0x00, 0xec, 0xff, 0x01, 0x00, 0xee, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xfb, 0xff, 0xf0, 0xff, 0xf8, 0xff, 0xef, 0xff, 0xf5, 0xff, 0xed, 0xff, 0xf3, 0xff, 0xec, 0xff, 0xf4, 0xff, 0xec, 0xff, 0xf5, 0xff, 0xee, 0xff, 0xf6, 0xff, 0xf0, 0xff, 0xf6, 0xff, 0xf2, 0xff, 0xf4, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xef, 0xff, 0xf0, 0xff, 0xef, 0xff, 0xef, 0xff, 0xf1, 0xff, 0xef, 0xff, 0xf4, 0xff, 0xf1, 0xff, 0xf9, 0xff, 0xf5, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfb, 0xff, 0x0e, 0x00, 0xfc, 0xff, 0x12, 0x00, 0xff, 0xff, 0x16, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x08, 0x00, 0x1e, 0x00, 0x0b, 0x00, 0x21, 0x00, 0x0e, 0x00, 0x22, 0x00, 0x0e, 0x00, 0x22, 0x00, 0x0e, 0x00, 0x22, 0x00, 0x0e, 0x00, 0x20, 0x00, 0x0e, 0x00, 0x20, 0x00, 0x10, 0x00, 0x20, 0x00, 0x12, 0x00, 0x21, 0x00, 0x15, 0x00, 0x22, 0x00, 0x16, 0x00, 0x23, 0x00, 0x17, 0x00, 0x23, 0x00, 0x16, 0x00, 0x22, 0x00, 0x14, 0x00, 0x1f, 0x00, 0x10, 0x00, 0x1d, 0x00, 0x0d, 0x00, 0x1a, 0x00, 0x0b, 0x00, 0x1a, 0x00, 0x0a, 0x00, 0x1b, 0x00, 0x0a, 0x00, 0x1d, 0x00, 0x09, 0x00, 0x20, 0x00, 0x08, 0x00, 0x22, 0x00, 0x05, 0x00, 0x23, 0x00, 0x01, 0x00, 0x22, 0x00, 0xfc, 0xff, 0x21, 0x00, 0xf6, 0xff, 0x1f, 0x00, 0xf0, 0xff, 0x1e, 0x00, 0xeb, 0xff, 0x1f, 0x00, 0xe8, 0xff, 0x21, 0x00, 0xe6, 0xff, 0x24, 0x00, 0xe5, 0xff, 0x28, 0x00, 0xe4, 0xff, 0x29, 0x00, 0xe3, 0xff, 0x27, 0x00, 0xe0, 0xff, 0x23, 0x00, 0xdd, 0xff, 0x1c, 0x00, 0xd9, 0xff, 0x15, 0x00, 0xd5, 0xff, 0x0e, 0x00, 0xd2, 0xff, 0x0a, 0x00, 0xd1, 0xff, 0x08, 0x00, 0xd1, 0xff, 0x06, 0x00, 0xd2, 0xff, 0x04, 0x00, 0xd3, 0xff, 0xff, 0xff, 0xd4, 0xff, 0xf9, 0xff, 0xd5, 0xff, 0xef, 0xff, 0xd6, 0xff, 0xe4, 0xff, 0xd7, 0xff, 0xda, 0xff, 0xd7, 0xff, 0xd1, 0xff, 0xd8, 0xff, 0xcb, 0xff, 0xda, 0xff, 0xc8, 0xff, 0xde, 0xff, 0xc8, 0xff, 0xe2, 0xff, 0xc9, 0xff, 0xe6, 0xff, 0xc9, 0xff, 0xea, 0xff, 0xc6, 0xff, 0xed, 0xff, 0xc2, 0xff, 0xee, 0xff, 0xbd, 0xff, 0xef, 0xff, 0xb9, 0xff, 0xf0, 0xff, 0xb7, 0xff, 0xf2, 0xff, 0xb8, 0xff, 0xf5, 0xff, 0xbc, 0xff, 0xf9, 0xff, 0xc3, 0xff, 0xfe, 0xff, 0xc9, 0xff, 0x03, 0x00, 0xcf, 0xff, 0x07, 0x00, 0xd2, 0xff, 0x0a, 0x00, 0xd4, 0xff, 0x0b, 0x00, 0xd5, 0xff, 0x0b, 0x00, 0xd7, 0xff, 0x0c, 0x00, 0xd9, 0xff, 0x0f, 0x00, 0xdd, 0xff, 0x13, 0x00, 0xe3, 0xff, 0x17, 0x00, 0xe8, 0xff, 0x1c, 0x00, 0xed, 0xff, 0x20, 0x00, 0xef, 0xff, 0x23, 0x00, 0xef, 0xff, 0x25, 0x00, 0xed, 0xff, 0x25, 0x00, 0xec, 0xff, 0x24, 0x00, 0xec, 0xff, 0x24, 0x00, 0xee, 0xff, 0x25, 0x00, 0xf2, 0xff, 0x27, 0x00, 0xf8, 0xff, 0x29, 0x00, 0xfd, 0xff, 0x2a, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00, 0x25, 0x00, 0xff, 0xff, 0x22, 0x00, 0xfe, 0xff, 0x20, 0x00, 0xff, 0xff, 0x1f, 0x00, 0x02, 0x00, 0x20, 0x00, 0x07, 0x00, 0x21, 0x00, 0x0c, 0x00, 0x21, 0x00, 0x10, 0x00, 0x20, 0x00, 0x14, 0x00, 0x1e, 0x00, 0x15, 0x00, 0x1c, 0x00, 0x16, 0x00, 0x1b, 0x00, 0x17, 0x00, 0x1c, 0x00, 0x18, 0x00, 0x1d, 0x00, 0x19, 0x00, 0x1e, 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x18, 0x00, 0x1d, 0x00, 0x15, 0x00, 0x1b, 0x00, 0x14, 0x00, 0x1a, 0x00, 0x13, 0x00, 0x19, 0x00, 0x13, 0x00, 0x18, 0x00, 0x13, 0x00, 0x18, 0x00, 0x12, 0x00, 0x17, 0x00, 0x0f, 0x00, 0x15, 0x00, 0x0b, 0x00, 0x12, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0xfb, 0xff, 0x0a, 0x00, 0xf7, 0xff, 0x09, 0x00, 0xf3, 0xff, 0x08, 0x00, 0xee, 0xff, 0x06, 0x00, 0xea, 0xff, 0x03, 0x00, 0xe7, 0xff, 0x00, 0x00, 0xe4, 0xff, 0xfc, 0xff, 0xe2, 0xff, 0xfa, 0xff, 0xe0, 0xff, 0xf9, 0xff, 0xdc, 0xff, 0xf8, 0xff, 0xd8, 0xff, 0xf8, 0xff, 0xd4, 0xff, 0xf6, 0xff, 0xd0, 0xff, 0xf3, 0xff, 0xcd, 0xff, 0xf0, 0xff, 0xcd, 0xff, 0xef, 0xff, 0xce, 0xff, 0xf1, 0xff, 0xd1, 0xff, 0xf4, 0xff, 0xd3, 0xff, 0xf8, 0xff, 0xd5, 0xff, 0xfa, 0xff, 0xd4, 0xff, 0xfa, 0xff, 0xd3, 0xff, 0xf9, 0xff, 0xd2, 0xff, 0xf7, 0xff, 0xd2, 0xff, 0xf6, 0xff, 0xd5, 0xff, 0xf7, 0xff, 0xda, 0xff, 0xfa, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xe6, 0xff, 0x05, 0x00, 0xea, 0xff, 0x08, 0x00, 0xed, 0xff, 0x09, 0x00, 0xed, 0xff, 0x07, 0x00, 0xed, 0xff, 0x05, 0x00, 0xed, 0xff, 0x02, 0x00, 0xef, 0xff, 0x02, 0x00, 0xf3, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x0b, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x0c, 0x00, 0xff, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x0d, 0x00, 0xfa, 0xff, 0x0e, 0x00, 0xfa, 0xff, 0x11, 0x00, 0xfd, 0xff, 0x13, 0x00, 0x02, 0x00, 0x14, 0x00, 0x09, 0x00, 0x14, 0x00, 0x10, 0x00, 0x14, 0x00, 0x17, 0x00, 0x13, 0x00, 0x1c, 0x00, 0x12, 0x00, 0x20, 0x00, 0x11, 0x00, 0x22, 0x00, 0x0f, 0x00, 0x24, 0x00, 0x0d, 0x00, 0x27, 0x00, 0x0b, 0x00, 0x2c, 0x00, 0x0b, 0x00, 0x32, 0x00, 0x0b, 0x00, 0x3a, 0x00, 0x0b, 0x00, 0x41, 0x00, 0x0a, 0x00, 0x47, 0x00, 0x08, 0x00, 0x4b, 0x00, 0x04, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x4d, 0x00, 0xfc, 0xff, 0x4d, 0x00, 0xfa, 0xff, 0x4c, 0x00, 0xf8, 0xff, 0x4b, 0x00, 0xf9, 0xff, 0x4a, 0x00, 0xf9, 0xff, 0x4a, 0x00, 0xf9, 0xff, 0x49, 0x00, 0xf7, 0xff, 0x47, 0x00, 0xf2, 0xff, 0x44, 0x00, 0xed, 0xff, 0x41, 0x00, 0xe9, 0xff, 0x3e, 0x00, 0xe6, 0xff, 0x3a, 0x00, 0xe5, 0xff, 0x35, 0x00, 0xe4, 0xff, 0x2f, 0x00, 0xe4, 0xff, 0x2a, 0x00, 0xe3, 0xff, 0x24, 0x00, 0xe1, 0xff, 0x20, 0x00, 0xde, 0xff, 0x1d, 0x00, 0xdb, 0xff, 0x1b, 0x00, 0xd9, 0xff, 0x19, 0x00, 0xd9, 0xff, 0x17, 0x00, 0xd9, 0xff, 0x13, 0x00, 0xdb, 0xff, 0x0d, 0x00, 0xdc, 0xff, 0x06, 0x00, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xfa, 0xff, 0xdd, 0xff, 0xf9, 0xff, 0xde, 0xff, 0xfb, 0xff, 0xdf, 0xff, 0xfe, 0xff, 0xe0, 0xff, 0x01, 0x00, 0xe1, 0xff, 0x02, 0x00, 0xe2, 0xff, 0x00, 0x00, 0xe4, 0xff, 0xfc, 0xff, 0xe6, 0xff, 0xf7, 0xff, 0xea, 0xff, 0xf4, 0xff, 0xed, 0xff, 0xf3, 0xff, 0xef, 0xff, 0xf6, 0xff, 0xf1, 0xff, 0xf9, 0xff, 0xf2, 0xff, 0xfc, 0xff, 0xf2, 0xff, 0xfc, 0xff, 0xf2, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf3, 0xff, 0xfb, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xee, 0xff, 0x02, 0x00, 0xee, 0xff, 0x03, 0x00, 0xf0, 0xff, 0x03, 0x00, 0xf3, 0xff, 0x04, 0x00, 0xf6, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x09, 0x00, 0xf9, 0xff, 0x0c, 0x00, 0xf7, 0xff, 0x0f, 0x00, 0xf5, 0xff, 0x11, 0x00, 0xf3, 0xff, 0x13, 0x00, 0xf3, 0xff, 0x15, 0x00, 0xf5, 0xff, 0x18, 0x00, 0xf7, 0xff, 0x1a, 0x00, 0xf9, 0xff, 0x1e, 0x00, 0xfc, 0xff, 0x22, 0x00, 0xfd, 0xff, 0x25, 0x00, 0xfd, 0xff, 0x26, 0x00, 0xfc, 0xff, 0x26, 0x00, 0xfa, 0xff, 0x26, 0x00, 0xf9, 0xff, 0x26, 0x00, 0xf9, 0xff, 0x27, 0x00, 0xfb, 0xff, 0x29, 0x00, 0xfe, 0xff, 0x2c, 0x00, 0x01, 0x00, 0x2d, 0x00, 0x04, 0x00, 0x2d, 0x00, 0x05, 0x00, 0x2c, 0x00, 0x07, 0x00, 0x29, 0x00, 0x08, 0x00, 0x25, 0x00, 0x09, 0x00, 0x22, 0x00, 0x09, 0x00, 0x20, 0x00, 0x0a, 0x00, 0x1d, 0x00, 0x0c, 0x00, 0x19, 0x00, 0x0d, 0x00, 0x16, 0x00, 0x0f, 0x00, 0x12, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x08, 0x00, 0x05, 0x00, 0x05, 0x00, 0x02, 0x00, 0x01, 0x00, 0xfe, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xf9, 0xff, 0xf7, 0xff, 0xf8, 0xff, 0xf4, 0xff, 0xf8, 0xff, 0xf1, 0xff, 0xf9, 0xff, 0xef, 0xff, 0xf9, 0xff, 0xed, 0xff, 0xf8, 0xff, 0xeb, 0xff, 0xf6, 0xff, 0xe9, 0xff, 0xf6, 0xff, 0xe7, 0xff, 0xf6, 0xff, 0xe5, 0xff, 0xf7, 0xff, 0xe2, 0xff, 0xf8, 0xff, 0xe0, 0xff, 0xf9, 0xff, 0xde, 0xff, 0xf9, 0xff, 0xdc, 0xff, 0xf7, 0xff, 0xda, 0xff, 0xf4, 0xff, 0xda, 0xff, 0xf3, 0xff, 0xd9, 0xff, 0xf2, 0xff, 0xd9, 0xff, 0xf3, 0xff, 0xd8, 0xff, 0xf5, 0xff, 0xd7, 0xff, 0xf8, 0xff, 0xd5, 0xff, 0xf9, 0xff, 0xd4, 0xff, 0xfa, 0xff, 0xd4, 0xff, 0xfa, 0xff, 0xd5, 0xff, 0xfa, 0xff, 0xd8, 0xff, 0xfa, 0xff, 0xdd, 0xff, 0xfa, 0xff, 0xe2, 0xff, 0xfa, 0xff, 0xe5, 0xff, 0xfb, 0xff, 0xe8, 0xff, 0xfd, 0xff, 0xe8, 0xff, 0xff, 0xff, 0xe7, 0xff, 0x02, 0x00, 0xe6, 0xff, 0x04, 0x00, 0xe7, 0xff, 0x05, 0x00, 0xeb, 0xff, 0x06, 0x00, 0xf0, 0xff, 0x06, 0x00, 0xf6, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x06, 0x00, 0xff, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfb, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xff, 0xff, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0xff, 0xff, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x00, 0x09, 0x00, 0x02, 0x00, 0x07, 0x00, 0x01, 0x00, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfa, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x0b, 0x00, 0xf5, 0xff, 0x0f, 0x00, 0xf7, 0xff, 0x11, 0x00, 0xfa, 0xff, 0x12, 0x00, 0xfe, 0xff, 0x11, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xff, 0xff, 0x0e, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xf8, 0xff, 0x10, 0x00, 0xf5, 0xff, 0x12, 0x00, 0xf4, 0xff, 0x12, 0x00, 0xf5, 0xff, 0x12, 0x00, 0xf6, 0xff, 0x11, 0x00, 0xf8, 0xff, 0x10, 0x00, 0xf8, 0xff, 0x10, 0x00, 0xf5, 0xff, 0x11, 0x00, 0xf1, 0xff, 0x12, 0x00, 0xed, 0xff, 0x12, 0x00, 0xe9, 0xff, 0x12, 0x00, 0xe7, 0xff, 0x11, 0x00, 0xe7, 0xff, 0x10, 0x00, 0xe8, 0xff, 0x0f, 0x00, 0xe9, 0xff, 0x0e, 0x00, 0xe9, 0xff, 0x0d, 0x00, 0xe8, 0xff, 0x0e, 0x00, 0xe6, 0xff, 0x0e, 0x00, 0xe5, 0xff, 0x0e, 0x00, 0xe5, 0xff, 0x0d, 0x00, 0xe5, 0xff, 0x0a, 0x00, 0xe6, 0xff, 0x07, 0x00, 0xe9, 0xff, 0x05, 0x00, 0xec, 0xff, 0x03, 0x00, 0xf0, 0xff, 0x03, 0x00, 0xf4, 0xff, 0x03, 0x00, 0xf7, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf7, 0xff, 0x0b, 0x00, 0xf6, 0xff, 0x0f, 0x00, 0xf5, 0xff, 0x10, 0x00, 0xf3, 0xff, 0x0f, 0x00, 0xf3, 0xff, 0x0d, 0x00, 0xf2, 0xff, 0x0c, 0x00, 0xf2, 0xff, 0x0d, 0x00, 0xf2, 0xff, 0x0f, 0x00, 0xf1, 0xff, 0x12, 0x00, 0xef, 0xff, 0x15, 0x00, 0xed, 0xff, 0x16, 0x00, 0xeb, 0xff, 0x16, 0x00, 0xeb, 0xff, 0x13, 0x00, 0xea, 0xff, 0x10, 0x00, 0xea, 0xff, 0x0d, 0x00, 0xeb, 0xff, 0x0a, 0x00, 0xed, 0xff, 0x07, 0x00, 0xef, 0xff, 0x05, 0x00, 0xf3, 0xff, 0x04, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x07, 0x00, 0xff, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0e, 0x00, 0xfb, 0xff, 0x12, 0x00, 0xfb, 0xff, 0x17, 0x00, 0xfc, 0xff, 0x1c, 0x00, 0xfd, 0xff, 0x20, 0x00, 0xff, 0xff, 0x22, 0x00, 0x00, 0x00, 0x24, 0x00, 0xfe, 0xff, 0x25, 0x00, 0xfc, 0xff, 0x26, 0x00, 0xf9, 0xff, 0x27, 0x00, 0xf7, 0xff, 0x29, 0x00, 0xf7, 0xff, 0x2b, 0x00, 0xf9, 0xff, 0x2e, 0x00, 0xfa, 0xff, 0x30, 0x00, 0xfb, 0xff, 0x31, 0x00, 0xf9, 0xff, 0x32, 0x00, 0xf6, 0xff, 0x32, 0x00, 0xf1, 0xff, 0x31, 0x00, 0xec, 0xff, 0x30, 0x00, 0xea, 0xff, 0x2e, 0x00, 0xeb, 0xff, 0x2c, 0x00, 0xec, 0xff, 0x2b, 0x00, 0xee, 0xff, 0x2a, 0x00, 0xef, 0xff, 0x28, 0x00, 0xed, 0xff, 0x25, 0x00, 0xe9, 0xff, 0x22, 0x00, 0xe5, 0xff, 0x1e, 0x00, 0xe2, 0xff, 0x1a, 0x00, 0xe0, 0xff, 0x15, 0x00, 0xe1, 0xff, 0x10, 0x00, 0xe3, 0xff, 0x0b, 0x00, 0xe4, 0xff, 0x06, 0x00, 0xe6, 0xff, 0x02, 0x00, 0xe5, 0xff, 0xfe, 0xff, 0xe4, 0xff, 0xfb, 0xff, 0xe2, 0xff, 0xf7, 0xff, 0xe1, 0xff, 0xf2, 0xff, 0xe2, 0xff, 0xec, 0xff, 0xe6, 0xff, 0xe6, 0xff, 0xed, 0xff, 0xe1, 0xff, 0xf4, 0xff, 0xde, 0xff, 0xfc, 0xff, 0xdc, 0xff, 0x02, 0x00, 0xdc, 0xff, 0x07, 0x00, 0xdc, 0xff, 0x0a, 0x00, 0xdb, 0xff, 0x0c, 0x00, 0xda, 0xff, 0x0e, 0x00, 0xd8, 0xff, 0x10, 0x00, 0xd5, 0xff, 0x14, 0x00, 0xd2, 0xff, 0x1a, 0x00, 0xd1, 0xff, 0x22, 0x00, 0xd0, 0xff, 0x29, 0x00, 0xd2, 0xff, 0x2f, 0x00, 0xd4, 0xff, 0x31, 0x00, 0xd5, 0xff, 0x30, 0x00, 0xd7, 0xff, 0x2d, 0x00, 0xd7, 0xff, 0x28, 0x00, 0xd7, 0xff, 0x24, 0x00, 0xd7, 0xff, 0x23, 0x00, 0xd7, 0xff, 0x25, 0x00, 0xd8, 0xff, 0x27, 0x00, 0xda, 0xff, 0x28, 0x00, 0xdd, 0xff, 0x26, 0x00, 0xe1, 0xff, 0x21, 0x00, 0xe3, 0xff, 0x1a, 0x00, 0xe4, 0xff, 0x13, 0x00, 0xe3, 0xff, 0x0d, 0x00, 0xe1, 0xff, 0x0a, 0x00, 0xdf, 0xff, 0x09, 0x00, 0xe0, 0xff, 0x0a, 0x00, 0xe2, 0xff, 0x0b, 0x00, 0xe7, 0xff, 0x0a, 0x00, 0xed, 0xff, 0x08, 0x00, 0xf2, 0xff, 0x03, 0x00, 0xf5, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xfb, 0xff, 0xf7, 0xff, 0xfa, 0xff, 0xf7, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x02, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x13, 0x00, 0x07, 0x00, 0x19, 0x00, 0x06, 0x00, 0x1c, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0xfc, 0xff, 0x20, 0x00, 0xfb, 0xff, 0x23, 0x00, 0xfa, 0xff, 0x26, 0x00, 0xfb, 0xff, 0x2a, 0x00, 0xfc, 0xff, 0x2d, 0x00, 0xfb, 0xff, 0x2e, 0x00, 0xf8, 0xff, 0x2f, 0x00, 0xf4, 0xff, 0x2e, 0x00, 0xef, 0xff, 0x2c, 0x00, 0xeb, 0xff, 0x2a, 0x00, 0xe8, 0xff, 0x29, 0x00, 0xe6, 0xff, 0x28, 0x00, 0xe5, 0xff, 0x27, 0x00, 0xe4, 0xff, 0x27, 0x00, 0xe3, 0xff, 0x26, 0x00, 0xe1, 0xff, 0x25, 0x00, 0xe0, 0xff, 0x23, 0x00, 0xe0, 0xff, 0x20, 0x00, 0xe0, 0xff, 0x1c, 0x00, 0xe0, 0xff, 0x18, 0x00, 0xe1, 0xff, 0x14, 0x00, 0xe2, 0xff, 0x11, 0x00, 0xe3, 0xff, 0x0f, 0x00, 0xe3, 0xff, 0x0d, 0x00, 0xe3, 0xff, 0x0a, 0x00, 0xe5, 0xff, 0x06, 0x00, 0xe8, 0xff, 0x00, 0x00, 0xee, 0xff, 0xf9, 0xff, 0xf5, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xed, 0xff, 0x01, 0x00, 0xe8, 0xff, 0x05, 0x00, 0xe6, 0xff, 0x08, 0x00, 0xe5, 0xff, 0x0b, 0x00, 0xe4, 0xff, 0x0f, 0x00, 0xe1, 0xff, 0x13, 0x00, 0xde, 0xff, 0x18, 0x00, 0xd9, 0xff, 0x1d, 0x00, 0xd3, 0xff, 0x22, 0x00, 0xcf, 0xff, 0x26, 0x00, 0xcc, 0xff, 0x28, 0x00, 0xca, 0xff, 0x28, 0x00, 0xc8, 0xff, 0x27, 0x00, 0xc6, 0xff, 0x27, 0x00, 0xc5, 0xff, 0x26, 0x00, 0xc3, 0xff, 0x25, 0x00, 0xc0, 0xff, 0x25, 0x00, 0xbe, 0xff, 0x25, 0x00, 0xbc, 0xff, 0x25, 0x00, 0xbc, 0xff, 0x26, 0x00, 0xbd, 0xff, 0x26, 0x00, 0xc0, 0xff, 0x25, 0x00, 0xc4, 0xff, 0x23, 0x00, 0xc9, 0xff, 0x20, 0x00, 0xce, 0xff, 0x1d, 0x00, 0xd3, 0xff, 0x1a, 0x00, 0xd8, 0xff, 0x19, 0x00, 0xdb, 0xff, 0x18, 0x00, 0xdd, 0xff, 0x18, 0x00, 0xdf, 0xff, 0x18, 0x00, 0xe3, 0xff, 0x17, 0x00, 0xe8, 0xff, 0x16, 0x00, 0xf0, 0xff, 0x14, 0x00, 0xf9, 0xff, 0x11, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x09, 0x00, 0x05, 0x00, 0x07, 0x00, 0x04, 0x00, 0x09, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x15, 0x00, 0xff, 0xff, 0x1c, 0x00, 0xfc, 0xff, 0x20, 0x00, 0xfa, 0xff, 0x21, 0x00, 0xf7, 0xff, 0x1f, 0x00, 0xf5, 0xff, 0x1c, 0x00, 0xf2, 0xff, 0x1b, 0x00, 0xef, 0xff, 0x1d, 0x00, 0xec, 0xff, 0x21, 0x00, 0xe9, 0xff, 0x27, 0x00, 0xe6, 0xff, 0x2c, 0x00, 0xe2, 0xff, 0x30, 0x00, 0xdd, 0xff, 0x30, 0x00, 0xd9, 0xff, 0x2f, 0x00, 0xd4, 0xff, 0x2d, 0x00, 0xd2, 0xff, 0x2c, 0x00, 0xd0, 0xff, 0x2d, 0x00, 0xd1, 0xff, 0x30, 0x00, 0xd2, 0xff, 0x33, 0x00, 0xd4, 0xff, 0x36, 0x00, 0xd5, 0xff, 0x38, 0x00, 0xd5, 0xff, 0x38, 0x00, 0xd5, 0xff, 0x36, 0x00, 0xd5, 0xff, 0x33, 0x00, 0xd6, 0xff, 0x31, 0x00, 0xd9, 0xff, 0x2f, 0x00, 0xdd, 0xff, 0x2e, 0x00, 0xe2, 0xff, 0x2e, 0x00, 0xe7, 0xff, 0x2c, 0x00, 0xec, 0xff, 0x2b, 0x00, 0xef, 0xff, 0x28, 0x00, 0xf3, 0xff, 0x25, 0x00, 0xf6, 0xff, 0x21, 0x00, 0xf8, 0xff, 0x1c, 0x00, 0xfa, 0xff, 0x17, 0x00, 0xfa, 0xff, 0x11, 0x00, 0xfb, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x05, 0x00, 0x01, 0x00, 0x03, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xf9, 0xff, 0x0a, 0x00, 0xf4, 0xff, 0x09, 0x00, 0xef, 0xff, 0x07, 0x00, 0xeb, 0xff, 0x07, 0x00, 0xea, 0xff, 0x07, 0x00, 0xea, 0xff, 0x0a, 0x00, 0xeb, 0xff, 0x0e, 0x00, 0xec, 0xff, 0x11, 0x00, 0xec, 0xff, 0x13, 0x00, 0xeb, 0xff, 0x13, 0x00, 0xea, 0xff, 0x13, 0x00, 0xe8, 0xff, 0x11, 0x00, 0xe8, 0xff, 0x11, 0x00, 0xea, 0xff, 0x12, 0x00, 0xed, 0xff, 0x15, 0x00, 0xf1, 0xff, 0x19, 0x00, 0xf4, 0xff, 0x1c, 0x00, 0xf7, 0xff, 0x1e, 0x00, 0xf8, 0xff, 0x1f, 0x00, 0xf9, 0xff, 0x1e, 0x00, 0xfa, 0xff, 0x1d, 0x00, 0xfb, 0xff, 0x1b, 0x00, 0xfd, 0xff, 0x18, 0x00, 0xff, 0xff, 0x16, 0x00, 0x01, 0x00, 0x14, 0x00, 0x02, 0x00, 0x12, 0x00, 0x03, 0x00, 0x11, 0x00, 0x04, 0x00, 0x10, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x08, 0x00, 0x06, 0x00, 0x03, 0x00, 0x06, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x08, 0x00, 0xf3, 0xff, 0x09, 0x00, 0xf1, 0xff, 0x0a, 0x00, 0xf0, 0xff, 0x0a, 0x00, 0xf0, 0xff, 0x0b, 0x00, 0xef, 0xff, 0x0b, 0x00, 0xed, 0xff, 0x0b, 0x00, 0xea, 0xff, 0x0b, 0x00, 0xe6, 0xff, 0x0b, 0x00, 0xe4, 0xff, 0x0d, 0x00, 0xe2, 0xff, 0x0f, 0x00, 0xe2, 0xff, 0x11, 0x00, 0xe3, 0xff, 0x12, 0x00, 0xe4, 0xff, 0x12, 0x00, 0xe3, 0xff, 0x10, 0x00, 0xe1, 0xff, 0x0e, 0x00, 0xde, 0xff, 0x0c, 0x00, 0xdd, 0xff, 0x0b, 0x00, 0xdb, 0xff, 0x0a, 0x00, 0xdb, 0xff, 0x0b, 0x00, 0xdc, 0xff, 0x0a, 0x00, 0xdd, 0xff, 0x08, 0x00, 0xde, 0xff, 0x04, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xfb, 0xff, 0xe1, 0xff, 0xf7, 0xff, 0xe2, 0xff, 0xf6, 0xff, 0xe4, 0xff, 0xf5, 0xff, 0xe6, 0xff, 0xf4, 0xff, 0xe8, 0xff, 0xf3, 0xff, 0xea, 0xff, 0xf0, 0xff, 0xeb, 0xff, 0xec, 0xff, 0xee, 0xff, 0xe6, 0xff, 0xf1, 0xff, 0xe1, 0xff, 0xf5, 0xff, 0xdd, 0xff, 0xfa, 0xff, 0xdb, 0xff, 0xfe, 0xff, 0xda, 0xff, 0x02, 0x00, 0xda, 0xff, 0x05, 0x00, 0xda, 0xff, 0x07, 0x00, 0xdb, 0xff, 0x0a, 0x00, 0xda, 0xff, 0x0d, 0x00, 0xda, 0xff, 0x11, 0x00, 0xd9, 0xff, 0x15, 0x00, 0xd9, 0xff, 0x19, 0x00, 0xda, 0xff, 0x1d, 0x00, 0xdb, 0xff, 0x1f, 0x00, 0xdc, 0xff, 0x21, 0x00, 0xde, 0xff, 0x22, 0x00, 0xe1, 0xff, 0x24, 0x00, 0xe3, 0xff, 0x27, 0x00, 0xe5, 0xff, 0x29, 0x00, 0xe7, 0xff, 0x2b, 0x00, 0xe8, 0xff, 0x2c, 0x00, 0xea, 0xff, 0x2d, 0x00, 0xeb, 0xff, 0x2d, 0x00, 0xec, 0xff, 0x2e, 0x00, 0xee, 0xff, 0x30, 0x00, 0xf0, 0xff, 0x32, 0x00, 0xf2, 0xff, 0x33, 0x00, 0xf4, 0xff, 0x34, 0x00, 0xf4, 0xff, 0x34, 0x00, 0xf5, 0xff, 0x32, 0x00, 0xf7, 0xff, 0x30, 0x00, 0xf9, 0xff, 0x2e, 0x00, 0xfc, 0xff, 0x2d, 0x00, 0xff, 0xff, 0x2d, 0x00, 0x03, 0x00, 0x2e, 0x00, 0x07, 0x00, 0x2e, 0x00, 0x0b, 0x00, 0x2d, 0x00, 0x0e, 0x00, 0x2b, 0x00, 0x10, 0x00, 0x28, 0x00, 0x13, 0x00, 0x25, 0x00, 0x16, 0x00, 0x21, 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x1b, 0x00, 0x22, 0x00, 0x19, 0x00, 0x26, 0x00, 0x16, 0x00, 0x29, 0x00, 0x14, 0x00, 0x2b, 0x00, 0x10, 0x00, 0x2d, 0x00, 0x0c, 0x00, 0x2e, 0x00, 0x07, 0x00, 0x2e, 0x00, 0x01, 0x00, 0x2e, 0x00, 0xfd, 0xff, 0x2e, 0x00, 0xf9, 0xff, 0x2d, 0x00, 0xf6, 0xff, 0x2c, 0x00, 0xf4, 0xff, 0x2b, 0x00, 0xf1, 0xff, 0x29, 0x00, 0xee, 0xff, 0x27, 0x00, 0xea, 0xff, 0x24, 0x00, 0xe7, 0xff, 0x21, 0x00, 0xe4, 0xff, 0x1e, 0x00, 0xe1, 0xff, 0x1b, 0x00, 0xde, 0xff, 0x17, 0x00, 0xdb, 0xff, 0x13, 0x00, 0xd7, 0xff, 0x0e, 0x00, 0xd5, 0xff, 0x08, 0x00, 0xd5, 0xff, 0x02, 0x00, 0xd6, 0xff, 0xfc, 0xff, 0xd7, 0xff, 0xf7, 0xff, 0xd9, 0xff, 0xf3, 0xff, 0xd9, 0xff, 0xf1, 0xff, 0xd8, 0xff, 0xef, 0xff, 0xd6, 0xff, 0xed, 0xff, 0xd3, 0xff, 0xea, 0xff, 0xd2, 0xff, 0xe6, 0xff, 0xd2, 0xff, 0xe1, 0xff, 0xd5, 0xff, 0xdc, 0xff, 0xd8, 0xff, 0xd6, 0xff, 0xdc, 0xff, 0xd0, 0xff, 0xdf, 0xff, 0xcc, 0xff, 0xe1, 0xff, 0xcb, 0xff, 0xe1, 0xff, 0xca, 0xff, 0xe1, 0xff, 0xca, 0xff, 0xe1, 0xff, 0xca, 0xff, 0xe4, 0xff, 0xc8, 0xff, 0xe8, 0xff, 0xc6, 0xff, 0xec, 0xff, 0xc5, 0xff, 0xf0, 0xff, 0xc4, 0xff, 0xf3, 0xff, 0xc6, 0xff, 0xf6, 0xff, 0xc9, 0xff, 0xf7, 0xff, 0xcd, 0xff, 0xfa, 0xff, 0xd3, 0xff, 0xfd, 0xff, 0xd8, 0xff, 0x00, 0x00, 0xde, 0xff, 0x04, 0x00, 0xe2, 0xff, 0x08, 0x00, 0xe4, 0xff, 0x0b, 0x00, 0xe5, 0xff, 0x0e, 0x00, 0xe6, 0xff, 0x10, 0x00, 0xe8, 0xff, 0x13, 0x00, 0xeb, 0xff, 0x16, 0x00, 0xf0, 0xff, 0x1b, 0x00, 0xf6, 0xff, 0x1e, 0x00, 0xfc, 0xff, 0x21, 0x00, 0x02, 0x00, 0x22, 0x00, 0x05, 0x00, 0x23, 0x00, 0x08, 0x00, 0x23, 0x00, 0x09, 0x00, 0x23, 0x00, 0x0a, 0x00, 0x24, 0x00, 0x0c, 0x00, 0x25, 0x00, 0x10, 0x00, 0x26, 0x00, 0x16, 0x00, 0x26, 0x00, 0x1d, 0x00, 0x25, 0x00, 0x24, 0x00, 0x21, 0x00, 0x2a, 0x00, 0x1d, 0x00, 0x2e, 0x00, 0x19, 0x00, 0x2f, 0x00, 0x16, 0x00, 0x2f, 0x00, 0x14, 0x00, 0x2f, 0x00, 0x13, 0x00, 0x2f, 0x00, 0x11, 0x00, 0x31, 0x00, 0x0f, 0x00, 0x34, 0x00, 0x0e, 0x00, 0x38, 0x00, 0x0b, 0x00, 0x3a, 0x00, 0x09, 0x00, 0x3b, 0x00, 0x06, 0x00, 0x3a, 0x00, 0x04, 0x00, 0x38, 0x00, 0x00, 0x00, 0x36, 0x00, 0xfe, 0xff, 0x33, 0x00, 0xfc, 0xff, 0x31, 0x00, 0xfb, 0xff, 0x30, 0x00, 0xfb, 0xff, 0x30, 0x00, 0xfb, 0xff, 0x2f, 0x00, 0xfa, 0xff, 0x2d, 0x00, 0xf6, 0xff, 0x2a, 0x00, 0xf1, 0xff, 0x27, 0x00, 0xec, 0xff, 0x24, 0x00, 0xe6, 0xff, 0x20, 0x00, 0xe1, 0xff, 0x1d, 0x00, 0xde, 0xff, 0x19, 0x00, 0xdd, 0xff, 0x15, 0x00, 0xdd, 0xff, 0x11, 0x00, 0xdd, 0xff, 0x0c, 0x00, 0xdb, 0xff, 0x08, 0x00, 0xd8, 0xff, 0x03, 0x00, 0xd4, 0xff, 0xfe, 0xff, 0xd2, 0xff, 0xfa, 0xff, 0xd1, 0xff, 0xf6, 0xff, 0xd2, 0xff, 0xf4, 0xff, 0xd5, 0xff, 0xf3, 0xff, 0xd8, 0xff, 0xf2, 0xff, 0xda, 0xff, 0xf0, 0xff, 0xdb, 0xff, 0xee, 0xff, 0xda, 0xff, 0xec, 0xff, 0xda, 0xff, 0xea, 0xff, 0xdc, 0xff, 0xea, 0xff, 0xdf, 0xff, 0xe9, 0xff, 0xe4, 0xff, 0xe9, 0xff, 0xea, 0xff, 0xe9, 0xff, 0xef, 0xff, 0xe9, 0xff, 0xf3, 0xff, 0xe8, 0xff, 0xf6, 0xff, 0xe6, 0xff, 0xfa, 0xff, 0xe4, 0xff, 0xfe, 0xff, 0xe3, 0xff, 0x03, 0x00, 0xe2, 0xff, 0x09, 0x00, 0xe2, 0xff, 0x0f, 0x00, 0xe3, 0xff, 0x15, 0x00, 0xe3, 0xff, 0x19, 0x00, 0xe4, 0xff, 0x1c, 0x00, 0xe3, 0xff, 0x20, 0x00, 0xe3, 0xff, 0x23, 0x00, 0xe4, 0xff, 0x27, 0x00, 0xe5, 0xff, 0x2b, 0x00, 0xe8, 0xff, 0x2e, 0x00, 0xeb, 0xff, 0x2f, 0x00, 0xef, 0xff, 0x2f, 0x00, 0xf2, 0xff, 0x2e, 0x00, 0xf3, 0xff, 0x2c, 0x00, 0xf4, 0xff, 0x2b, 0x00, 0xf5, 0xff, 0x2b, 0x00, 0xf6, 0xff, 0x2c, 0x00, 0xf8, 0xff, 0x2b, 0x00, 0xfb, 0xff, 0x2a, 0x00, 0x00, 0x00, 0x29, 0x00, 0x05, 0x00, 0x27, 0x00, 0x09, 0x00, 0x25, 0x00, 0x0d, 0x00, 0x24, 0x00, 0x0e, 0x00, 0x23, 0x00, 0x0f, 0x00, 0x23, 0x00, 0x0f, 0x00, 0x23, 0x00, 0x0f, 0x00, 0x21, 0x00, 0x11, 0x00, 0x1f, 0x00, 0x13, 0x00, 0x1c, 0x00, 0x15, 0x00, 0x19, 0x00, 0x18, 0x00, 0x17, 0x00, 0x1b, 0x00, 0x16, 0x00, 0x1d, 0x00, 0x14, 0x00, 0x1f, 0x00, 0x11, 0x00, 0x1f, 0x00, 0x0e, 0x00, 0x1f, 0x00, 0x09, 0x00, 0x1e, 0x00, 0x04, 0x00, 0x1d, 0x00, 0xff, 0xff, 0x1c, 0x00, 0xfa, 0xff, 0x1c, 0x00, 0xf7, 0xff, 0x1d, 0x00, 0xf6, 0xff, 0x1f, 0x00, 0xf4, 0xff, 0x21, 0x00, 0xf1, 0xff, 0x22, 0x00, 0xee, 0xff, 0x21, 0x00, 0xeb, 0xff, 0x20, 0x00, 0xe7, 0xff, 0x1d, 0x00, 0xe4, 0xff, 0x1a, 0x00, 0xe2, 0xff, 0x19, 0x00, 0xe0, 0xff, 0x18, 0x00, 0xde, 0xff, 0x18, 0x00, 0xdc, 0xff, 0x18, 0x00, 0xdb, 0xff, 0x18, 0x00, 0xda, 0xff, 0x17, 0x00, 0xda, 0xff, 0x15, 0x00, 0xd9, 0xff, 0x13, 0x00, 0xd8, 0xff, 0x0f, 0x00, 0xd6, 0xff, 0x0b, 0x00, 0xd3, 0xff, 0x07, 0x00, 0xd1, 0xff, 0x04, 0x00, 0xd0, 0xff, 0x02, 0x00, 0xd0, 0xff, 0x01, 0x00, 0xd2, 0xff, 0x00, 0x00, 0xd5, 0xff, 0x00, 0x00, 0xd8, 0xff, 0xfe, 0xff, 0xda, 0xff, 0xfc, 0xff, 0xdb, 0xff, 0xf8, 0xff, 0xdb, 0xff, 0xf3, 0xff, 0xdb, 0xff, 0xef, 0xff, 0xdd, 0xff, 0xec, 0xff, 0xe1, 0xff, 0xeb, 0xff, 0xe6, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0xeb, 0xff, 0xf0, 0xff, 0xec, 0xff, 0xf3, 0xff, 0xec, 0xff, 0xf5, 0xff, 0xea, 0xff, 0xf8, 0xff, 0xe8, 0xff, 0xfb, 0xff, 0xe5, 0xff, 0xff, 0xff, 0xe3, 0xff, 0x04, 0x00, 0xe2, 0xff, 0x0b, 0x00, 0xe2, 0xff, 0x10, 0x00, 0xe3, 0xff, 0x15, 0x00, 0xe4, 0xff, 0x18, 0x00, 0xe5, 0xff, 0x1a, 0x00, 0xe6, 0xff, 0x1d, 0x00, 0xe5, 0xff, 0x20, 0x00, 0xe4, 0xff, 0x23, 0x00, 0xe2, 0xff, 0x27, 0x00, 0xe1, 0xff, 0x2a, 0x00, 0xe0, 0xff, 0x2c, 0x00, 0xdf, 0xff, 0x2b, 0x00, 0xde, 0xff, 0x2a, 0x00, 0xde, 0xff, 0x29, 0x00, 0xdd, 0xff, 0x29, 0x00, 0xdd, 0xff, 0x29, 0x00, 0xdc, 0xff, 0x2a, 0x00, 0xdc, 0xff, 0x2b, 0x00, 0xdc, 0xff, 0x2a, 0x00, 0xdd, 0xff, 0x27, 0x00, 0xdd, 0xff, 0x23, 0x00, 0xdf, 0xff, 0x1e, 0x00, 0xe2, 0xff, 0x1a, 0x00, 0xe6, 0xff, 0x18, 0x00, 0xeb, 0xff, 0x17, 0x00, 0xf0, 0xff, 0x16, 0x00, 0xf5, 0xff, 0x15, 0x00, 0xf9, 0xff, 0x13, 0x00, 0xfd, 0xff, 0x10, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x09, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0xfe, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xfa, 0xff, 0x11, 0x00, 0xf9, 0xff, 0x12, 0x00, 0xf7, 0xff, 0x12, 0x00, 0xf5, 0xff, 0x10, 0x00, 0xf3, 0xff, 0x0d, 0x00, 0xef, 0xff, 0x0a, 0x00, 0xec, 0xff, 0x08, 0x00, 0xea, 0xff, 0x07, 0x00, 0xe7, 0xff, 0x07, 0x00, 0xe6, 0xff, 0x08, 0x00, 0xe5, 0xff, 0x08, 0x00, 0xe3, 0xff, 0x08, 0x00, 0xe1, 0xff, 0x05, 0x00, 0xdf, 0xff, 0x01, 0x00, 0xdb, 0xff, 0xfc, 0xff, 0xd7, 0xff, 0xf9, 0xff, 0xd4, 0xff, 0xf7, 0xff, 0xd2, 0xff, 0xf7, 0xff, 0xd1, 0xff, 0xf7, 0xff, 0xd1, 0xff, 0xf7, 0xff, 0xd1, 0xff, 0xf7, 0xff, 0xd1, 0xff, 0xf7, 0xff, 0xd1, 0xff, 0xf7, 0xff, 0xd1, 0xff, 0xf7, 0xff, 0xd1, 0xff, 0xf5, 0xff, 0xd3, 0xff, 0xf4, 0xff, 0xd7, 0xff, 0xf3, 0xff, 0xdc, 0xff, 0xf4, 0xff, 0xe2, 0xff, 0xf6, 0xff, 0xe8, 0xff, 0xf9, 0xff, 0xed, 0xff, 0xfc, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xf6, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x12, 0x00, 0xfc, 0xff, 0x17, 0x00, 0xfe, 0xff, 0x1b, 0x00, 0x01, 0x00, 0x1f, 0x00, 0x04, 0x00, 0x21, 0x00, 0x05, 0x00, 0x22, 0x00, 0x06, 0x00, 0x24, 0x00, 0x04, 0x00, 0x26, 0x00, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00, 0x2a, 0x00, 0xff, 0xff, 0x2a, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x04, 0x00, 0x29, 0x00, 0x08, 0x00, 0x27, 0x00, 0x0b, 0x00, 0x26, 0x00, 0x0d, 0x00, 0x23, 0x00, 0x0d, 0x00, 0x21, 0x00, 0x0c, 0x00, 0x1e, 0x00, 0x0c, 0x00, 0x1c, 0x00, 0x0c, 0x00, 0x1a, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x0f, 0x00, 0x18, 0x00, 0x13, 0x00, 0x15, 0x00, 0x17, 0x00, 0x13, 0x00, 0x19, 0x00, 0x10, 0x00, 0x1a, 0x00, 0x0f, 0x00, 0x1a, 0x00, 0x0e, 0x00, 0x19, 0x00, 0x0e, 0x00, 0x19, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x0c, 0x00, 0x1a, 0x00, 0x0b, 0x00, 0x1a, 0x00, 0x0a, 0x00, 0x1b, 0x00, 0x09, 0x00, 0x1a, 0x00, 0x09, 0x00, 0x18, 0x00, 0x09, 0x00, 0x15, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x06, 0x00, 0x08, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf6, 0xff, 0xfb, 0xff, 0xf4, 0xff, 0xf8, 0xff, 0xf2, 0xff, 0xf5, 0xff, 0xf0, 0xff, 0xf3, 0xff, 0xee, 0xff, 0xf4, 0xff, 0xeb, 0xff, 0xf6, 0xff, 0xe8, 0xff, 0xf9, 0xff, 0xe5, 0xff, 0xfb, 0xff, 0xe3, 0xff, 0xfb, 0xff, 0xe1, 0xff, 0xfa, 0xff, 0xe0, 0xff, 0xf9, 0xff, 0xdf, 0xff, 0xf8, 0xff, 0xdf, 0xff, 0xf9, 0xff, 0xdf, 0xff, 0xfa, 0xff, 0xdf, 0xff, 0xfd, 0xff, 0xde, 0xff, 0x01, 0x00, 0xde, 0xff, 0x03, 0x00, 0xdd, 0xff, 0x03, 0x00, 0xde, 0xff, 0x01, 0x00, 0xdf, 0xff, 0xfe, 0xff, 0xe1, 0xff, 0xfb, 0xff, 0xe3, 0xff, 0xf9, 0xff, 0xe5, 0xff, 0xfa, 0xff, 0xe7, 0xff, 0xfc, 0xff, 0xe9, 0xff, 0xfe, 0xff, 0xeb, 0xff, 0xff, 0xff, 0xed, 0xff, 0x00, 0x00, 0xf1, 0xff, 0xff, 0xff, 0xf4, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf6, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf7, 0xff, 0x06, 0x00, 0xf6, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x08, 0x00, 0xf9, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x0b, 0x00, 0xff, 0xff, 0x0a, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0a, 0x00, 0xff, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0x01, 0x00, 0x06, 0x00, 0x04, 0x00, 0x09, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x0b, 0x00, 0x0e, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x11, 0x00, 0x0c, 0x00, 0x13, 0x00, 0x0d, 0x00, 0x15, 0x00, 0x0b, 0x00, 0x16, 0x00, 0x07, 0x00, 0x16, 0x00, 0x02, 0x00, 0x15, 0x00, 0xfd, 0xff, 0x13, 0x00, 0xfa, 0xff, 0x11, 0x00, 0xfa, 0xff, 0x11, 0x00, 0xfb, 0xff, 0x11, 0x00, 0xfd, 0xff, 0x13, 0x00, 0xfd, 0xff, 0x15, 0x00, 0xfb, 0xff, 0x17, 0x00, 0xf9, 0xff, 0x18, 0x00, 0xf6, 0xff, 0x18, 0x00, 0xf5, 0xff, 0x16, 0x00, 0xf4, 0xff, 0x14, 0x00, 0xf6, 0xff, 0x11, 0x00, 0xf7, 0xff, 0x10, 0x00, 0xf9, 0xff, 0x11, 0x00, 0xfa, 0xff, 0x12, 0x00, 0xfa, 0xff, 0x13, 0x00, 0xfa, 0xff, 0x13, 0x00, 0xfb, 0xff, 0x12, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x0b, 0x00, 0x02, 0x00, 0x08, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x06, 0x00, 0x03, 0x00, 0x07, 0x00, 0x03, 0x00, 0x08, 0x00, 0x02, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0xfe, 0xff, 0x0c, 0x00, 0xfa, 0xff, 0x0c, 0x00, 0xf6, 0xff, 0x0c, 0x00, 0xf3, 0xff, 0x0c, 0x00, 0xf1, 0xff, 0x0c, 0x00, 0xf1, 0xff, 0x0d, 0x00, 0xf0, 0xff, 0x0e, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0xee, 0xff, 0x0e, 0x00, 0xea, 0xff, 0x0c, 0x00, 0xe5, 0xff, 0x09, 0x00, 0xe0, 0xff, 0x07, 0x00, 0xdb, 0xff, 0x07, 0x00, 0xd9, 0xff, 0x07, 0x00, 0xd8, 0xff, 0x09, 0x00, 0xda, 0xff, 0x0b, 0x00, 0xdb, 0xff, 0x0c, 0x00, 0xdb, 0xff, 0x0c, 0x00, 0xda, 0xff, 0x0c, 0x00, 0xd8, 0xff, 0x0c, 0x00, 0xd6, 0xff, 0x0c, 0x00, 0xd3, 0xff, 0x0e, 0x00, 0xd2, 0xff, 0x10, 0x00, 0xd3, 0xff, 0x13, 0x00, 0xd5, 0xff, 0x16, 0x00, 0xd8, 0xff, 0x19, 0x00, 0xdb, 0xff, 0x1c, 0x00, 0xdc, 0xff, 0x1e, 0x00, 0xdc, 0xff, 0x21, 0x00, 0xda, 0xff, 0x22, 0x00, 0xd9, 0xff, 0x23, 0x00, 0xda, 0xff, 0x22, 0x00, 0xdd, 0xff, 0x20, 0x00, 0xe1, 0xff, 0x1f, 0x00, 0xe6, 0xff, 0x1f, 0x00, 0xea, 0xff, 0x1f, 0x00, 0xed, 0xff, 0x1f, 0x00, 0xee, 0xff, 0x1e, 0x00, 0xf0, 0xff, 0x1c, 0x00, 0xf2, 0xff, 0x18, 0x00, 0xf6, 0xff, 0x13, 0x00, 0xfa, 0xff, 0x0e, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x14, 0x00, 0x08, 0x00, 0x17, 0x00, 0x08, 0x00, 0x19, 0x00, 0x06, 0x00, 0x1b, 0x00, 0x03, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x20, 0x00, 0xfd, 0xff, 0x24, 0x00, 0xfb, 0xff, 0x28, 0x00, 0xfa, 0xff, 0x2c, 0x00, 0xfa, 0xff, 0x2f, 0x00, 0xf9, 0xff, 0x30, 0x00, 0xf8, 0xff, 0x2f, 0x00, 0xf7, 0xff, 0x2d, 0x00, 0xf6, 0xff, 0x2c, 0x00, 0xf4, 0xff, 0x2a, 0x00, 0xf3, 0xff, 0x2a, 0x00, 0xf3, 0xff, 0x2b, 0x00, 0xf3, 0xff, 0x2c, 0x00, 0xf3, 0xff, 0x2d, 0x00, 0xf3, 0xff, 0x2c, 0x00, 0xf2, 0xff, 0x2b, 0x00, 0xf2, 0xff, 0x28, 0x00, 0xf2, 0xff, 0x25, 0x00, 0xf2, 0xff, 0x21, 0x00, 0xf1, 0xff, 0x1e, 0x00, 0xf1, 0xff, 0x1c, 0x00, 0xef, 0xff, 0x1b, 0x00, 0xed, 0xff, 0x1b, 0x00, 0xec, 0xff, 0x19, 0x00, 0xea, 0xff, 0x17, 0x00, 0xe9, 0xff, 0x12, 0x00, 0xe9, 0xff, 0x0e, 0x00, 0xe8, 0xff, 0x09, 0x00, 0xe7, 0xff, 0x06, 0x00, 0xe6, 0xff, 0x03, 0x00, 0xe4, 0xff, 0x02, 0x00, 0xe4, 0xff, 0x00, 0x00, 0xe4, 0xff, 0xfc, 0xff, 0xe4, 0xff, 0xf7, 0xff, 0xe6, 0xff, 0xf0, 0xff, 0xe7, 0xff, 0xe9, 0xff, 0xe9, 0xff, 0xe3, 0xff, 0xea, 0xff, 0xdf, 0xff, 0xea, 0xff, 0xde, 0xff, 0xea, 0xff, 0xdd, 0xff, 0xeb, 0xff, 0xdd, 0xff, 0xed, 0xff, 0xdb, 0xff, 0xf1, 0xff, 0xd8, 0xff, 0xf5, 0xff, 0xd4, 0xff, 0xf8, 0xff, 0xd0, 0xff, 0xf9, 0xff, 0xcd, 0xff, 0xfa, 0xff, 0xcb, 0xff, 0xf9, 0xff, 0xcb, 0xff, 0xf9, 0xff, 0xcc, 0xff, 0xf9, 0xff, 0xcd, 0xff, 0xfa, 0xff, 0xcf, 0xff, 0xfb, 0xff, 0xd0, 0xff, 0xfe, 0xff, 0xd1, 0xff, 0x00, 0x00, 0xd2, 0xff, 0x03, 0x00, 0xd3, 0xff, 0x05, 0x00, 0xd4, 0xff, 0x06, 0x00, 0xd6, 0xff, 0x08, 0x00, 0xd8, 0xff, 0x09, 0x00, 0xd9, 0xff, 0x0b, 0x00, 0xdb, 0xff, 0x0c, 0x00, 0xde, 0xff, 0x0d, 0x00, 0xe1, 0xff, 0x0f, 0x00, 0xe6, 0xff, 0x10, 0x00, 0xeb, 0xff, 0x11, 0x00, 0xf0, 0xff, 0x11, 0x00, 0xf3, 0xff, 0x11, 0x00, 0xf6, 0xff, 0x10, 0x00, 0xf8, 0xff, 0x0d, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x06, 0x00, 0x11, 0x00, 0x05, 0x00, 0x16, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x20, 0x00, 0xfc, 0xff, 0x23, 0x00, 0xf9, 0xff, 0x26, 0x00, 0xf6, 0xff, 0x2b, 0x00, 0xf5, 0xff, 0x30, 0x00, 0xf4, 0xff, 0x35, 0x00, 0xf4, 0xff, 0x37, 0x00, 0xf3, 0xff, 0x37, 0x00, 0xf2, 0xff, 0x35, 0x00, 0xf0, 0xff, 0x32, 0x00, 0xef, 0xff, 0x2e, 0x00, 0xed, 0xff, 0x2b, 0x00, 0xec, 0xff, 0x2a, 0x00, 0xed, 0xff, 0x2a, 0x00, 0xee, 0xff, 0x2a, 0x00, 0xf0, 0xff, 0x29, 0x00, 0xf1, 0xff, 0x28, 0x00, 0xf2, 0xff, 0x24, 0x00, 0xf4, 0xff, 0x1e, 0x00, 0xf7, 0xff, 0x16, 0x00, 0xfb, 0xff, 0x0d, 0x00, 0xff, 0xff, 0x07, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xf8, 0xff, 0x08, 0x00, 0xf2, 0xff, 0x0a, 0x00, 0xec, 0xff, 0x0b, 0x00, 0xe7, 0xff, 0x0b, 0x00, 0xe4, 0xff, 0x0a, 0x00, 0xe3, 0xff, 0x08, 0x00, 0xe3, 0xff, 0x07, 0x00, 0xe3, 0xff, 0x07, 0x00, 0xe1, 0xff, 0x07, 0x00, 0xde, 0xff, 0x08, 0x00, 0xd9, 0xff, 0x09, 0x00, 0xd4, 0xff, 0x09, 0x00, 0xd1, 0xff, 0x08, 0x00, 0xcf, 0xff, 0x08, 0x00, 0xd0, 0xff, 0x08, 0x00, 0xd0, 0xff, 0x09, 0x00, 0xd0, 0xff, 0x0c, 0x00, 0xd0, 0xff, 0x0f, 0x00, 0xce, 0xff, 0x12, 0x00, 0xcd, 0xff, 0x13, 0x00, 0xcd, 0xff, 0x14, 0x00, 0xcf, 0xff, 0x14, 0x00, 0xd2, 0xff, 0x13, 0x00, 0xd5, 0xff, 0x12, 0x00, 0xd7, 0xff, 0x11, 0x00, 0xda, 0xff, 0x10, 0x00, 0xdc, 0xff, 0x0f, 0x00, 0xdf, 0xff, 0x0c, 0x00, 0xe3, 0xff, 0x07, 0x00, 0xe9, 0xff, 0x03, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x09, 0x00, 0xf9, 0xff, 0x0d, 0x00, 0xf6, 0xff, 0x12, 0x00, 0xf3, 0xff, 0x17, 0x00, 0xf0, 0xff, 0x1d, 0x00, 0xed, 0xff, 0x23, 0x00, 0xeb, 0xff, 0x2a, 0x00, 0xeb, 0xff, 0x2f, 0x00, 0xeb, 0xff, 0x34, 0x00, 0xeb, 0xff, 0x38, 0x00, 0xea, 0xff, 0x3b, 0x00, 0xe8, 0xff, 0x3d, 0x00, 0xe7, 0xff, 0x3f, 0x00, 0xe7, 0xff, 0x40, 0x00, 0xe6, 0xff, 0x40, 0x00, 0xe6, 0xff, 0x40, 0x00, 0xe5, 0xff, 0x40, 0x00, 0xe3, 0xff, 0x40, 0x00, 0xe2, 0xff, 0x41, 0x00, 0xe1, 0xff, 0x41, 0x00, 0xe2, 0xff, 0x41, 0x00, 0xe4, 0xff, 0x40, 0x00, 0xe6, 0xff, 0x3d, 0x00, 0xe9, 0xff, 0x3a, 0x00, 0xea, 0xff, 0x36, 0x00, 0xeb, 0xff, 0x32, 0x00, 0xea, 0xff, 0x2d, 0x00, 0xea, 0xff, 0x2a, 0x00, 0xeb, 0xff, 0x26, 0x00, 0xed, 0xff, 0x23, 0x00, 0xf0, 0xff, 0x20, 0x00, 0xf2, 0xff, 0x1c, 0x00, 0xf3, 0xff, 0x18, 0x00, 0xf3, 0xff, 0x12, 0x00, 0xf2, 0xff, 0x0b, 0x00, 0xf1, 0xff, 0x04, 0x00, 0xf1, 0xff, 0xfe, 0xff, 0xf2, 0xff, 0xf8, 0xff, 0xf4, 0xff, 0xf3, 0xff, 0xf6, 0xff, 0xef, 0xff, 0xf8, 0xff, 0xeb, 0xff, 0xf9, 0xff, 0xe7, 0xff, 0xfb, 0xff, 0xe2, 0xff, 0xfc, 0xff, 0xdc, 0xff, 0xfd, 0xff, 0xd5, 0xff, 0xff, 0xff, 0xce, 0xff, 0x02, 0x00, 0xc8, 0xff, 0x06, 0x00, 0xc5, 0xff, 0x0a, 0x00, 0xc3, 0xff, 0x0d, 0x00, 0xc2, 0xff, 0x0f, 0x00, 0xc2, 0xff, 0x11, 0x00, 0xc0, 0xff, 0x12, 0x00, 0xbc, 0xff, 0x12, 0x00, 0xb7, 0xff, 0x13, 0x00, 0xb3, 0xff, 0x13, 0x00, 0xaf, 0xff, 0x12, 0x00, 0xae, 0xff, 0x10, 0x00, 0xb0, 0xff, 0x0e, 0x00, 0xb4, 0xff, 0x0c, 0x00, 0xb9, 0xff, 0x0a, 0x00, 0xbd, 0xff, 0x0a, 0x00, 0xc0, 0xff, 0x0b, 0x00, 0xc2, 0xff, 0x0b, 0x00, 0xc3, 0xff, 0x0b, 0x00, 0xc5, 0xff, 0x0b, 0x00, 0xc8, 0xff, 0x0b, 0x00, 0xcc, 0xff, 0x0b, 0x00, 0xd3, 0xff, 0x0d, 0x00, 0xda, 0xff, 0x0e, 0x00, 0xe1, 0xff, 0x0f, 0x00, 0xe8, 0xff, 0x10, 0x00, 0xee, 0xff, 0x10, 0x00, 0xf4, 0xff, 0x10, 0x00, 0xf9, 0xff, 0x10, 0x00, 0xff, 0xff, 0x10, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x13, 0x00, 0x0c, 0x00, 0x1a, 0x00, 0x09, 0x00, 0x21, 0x00, 0x07, 0x00, 0x28, 0x00, 0x04, 0x00, 0x2f, 0x00, 0x02, 0x00, 0x36, 0x00, 0x01, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x46, 0x00, 0x01, 0x00, 0x46, 0x00, 0x02, 0x00, 0x46, 0x00, 0x04, 0x00, 0x48, 0x00, 0x05, 0x00, 0x49, 0x00, 0x05, 0x00, 0x4a, 0x00, 0x06, 0x00, 0x4a, 0x00, 0x07, 0x00, 0x49, 0x00, 0x08, 0x00, 0x46, 0x00, 0x0b, 0x00, 0x40, 0x00, 0x0e, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x34, 0x00, 0x12, 0x00, 0x2f, 0x00, 0x13, 0x00, 0x2b, 0x00, 0x14, 0x00, 0x28, 0x00, 0x13, 0x00, 0x25, 0x00, 0x12, 0x00, 0x21, 0x00, 0x11, 0x00, 0x1d, 0x00, 0x11, 0x00, 0x18, 0x00, 0x13, 0x00, 0x12, 0x00, 0x16, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x07, 0x00, 0x19, 0x00, 0x02, 0x00, 0x19, 0x00, 0xfe, 0xff, 0x19, 0x00, 0xfa, 0xff, 0x19, 0x00, 0xf7, 0xff, 0x1a, 0x00, 0xf4, 0xff, 0x1b, 0x00, 0xf1, 0xff, 0x1d, 0x00, 0xed, 0xff, 0x1e, 0x00, 0xe9, 0xff, 0x1e, 0x00, 0xe5, 0xff, 0x1e, 0x00, 0xe0, 0xff, 0x1d, 0x00, 0xdc, 0xff, 0x1b, 0x00, 0xd7, 0xff, 0x19, 0x00, 0xd4, 0xff, 0x18, 0x00, 0xd1, 0xff, 0x17, 0x00, 0xcf, 0xff, 0x17, 0x00, 0xcc, 0xff, 0x16, 0x00, 0xca, 0xff, 0x15, 0x00, 0xc7, 0xff, 0x13, 0x00, 0xc5, 0xff, 0x11, 0x00, 0xc3, 0xff, 0x10, 0x00, 0xc2, 0xff, 0x0f, 0x00, 0xc1, 0xff, 0x0e, 0x00, 0xc0, 0xff, 0x0d, 0x00, 0xc0, 0xff, 0x0a, 0x00, 0xc1, 0xff, 0x06, 0x00, 0xc2, 0xff, 0x01, 0x00, 0xc3, 0xff, 0xfe, 0xff, 0xc5, 0xff, 0xfc, 0xff, 0xc7, 0xff, 0xfc, 0xff, 0xcb, 0xff, 0xfe, 0xff, 0xcf, 0xff, 0xff, 0xff, 0xd4, 0xff, 0xfd, 0xff, 0xda, 0xff, 0xfa, 0xff, 0xe1, 0xff, 0xf4, 0xff, 0xe9, 0xff, 0xef, 0xff, 0xf0, 0xff, 0xec, 0xff, 0xf7, 0xff, 0xeb, 0xff, 0xfd, 0xff, 0xed, 0xff, 0x04, 0x00, 0xf0, 0xff, 0x0a, 0x00, 0xf3, 0xff, 0x0f, 0x00, 0xf6, 0xff, 0x14, 0x00, 0xf7, 0xff, 0x19, 0x00, 0xf6, 0xff, 0x1f, 0x00, 0xf5, 0xff, 0x25, 0x00, 0xf5, 0xff, 0x2b, 0x00, 0xf5, 0xff, 0x31, 0x00, 0xf7, 0xff, 0x36, 0x00, 0xfa, 0xff, 0x3a, 0x00, 0xfc, 0xff, 0x3b, 0x00, 0xfe, 0xff, 0x3c, 0x00, 0xff, 0xff, 0x3d, 0x00, 0xfe, 0xff, 0x3f, 0x00, 0xfc, 0xff, 0x41, 0x00, 0xfa, 0xff, 0x44, 0x00, 0xf8, 0xff, 0x47, 0x00, 0xf6, 0xff, 0x4a, 0x00, 0xf5, 0xff, 0x4b, 0x00, 0xf6, 0xff, 0x4c, 0x00, 0xf6, 0xff, 0x4b, 0x00, 0xf5, 0xff, 0x4a, 0x00, 0xf3, 0xff, 0x4a, 0x00, 0xef, 0xff, 0x49, 0x00, 0xeb, 0xff, 0x48, 0x00, 0xe8, 0xff, 0x46, 0x00, 0xe6, 0xff, 0x43, 0x00, 0xe6, 0xff, 0x40, 0x00, 0xe7, 0xff, 0x3c, 0x00, 0xe9, 0xff, 0x38, 0x00, 0xea, 0xff, 0x34, 0x00, 0xeb, 0xff, 0x30, 0x00, 0xeb, 0xff, 0x2c, 0x00, 0xeb, 0xff, 0x27, 0x00, 0xec, 0xff, 0x22, 0x00, 0xee, 0xff, 0x1d, 0x00, 0xf0, 0xff, 0x19, 0x00, 0xf3, 0xff, 0x15, 0x00, 0xf4, 0xff, 0x12, 0x00, 0xf5, 0xff, 0x0e, 0x00, 0xf4, 0xff, 0x0b, 0x00, 0xf4, 0xff, 0x07, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf7, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xf7, 0xff, 0xfa, 0xff, 0xf2, 0xff, 0xf9, 0xff, 0xed, 0xff, 0xf7, 0xff, 0xea, 0xff, 0xf3, 0xff, 0xe7, 0xff, 0xef, 0xff, 0xe4, 0xff, 0xed, 0xff, 0xe1, 0xff, 0xeb, 0xff, 0xde, 0xff, 0xec, 0xff, 0xd9, 0xff, 0xed, 0xff, 0xd3, 0xff, 0xee, 0xff, 0xcd, 0xff, 0xed, 0xff, 0xc7, 0xff, 0xea, 0xff, 0xc4, 0xff, 0xe5, 0xff, 0xc2, 0xff, 0xe2, 0xff, 0xc3, 0xff, 0xe0, 0xff, 0xc6, 0xff, 0xdf, 0xff, 0xca, 0xff, 0xe1, 0xff, 0xcc, 0xff, 0xe3, 0xff, 0xcd, 0xff, 0xe5, 0xff, 0xcc, 0xff, 0xe5, 0xff, 0xcb, 0xff, 0xe4, 0xff, 0xcb, 0xff, 0xe3, 0xff, 0xcb, 0xff, 0xe1, 0xff, 0xce, 0xff, 0xe0, 0xff, 0xd2, 0xff, 0xe1, 0xff, 0xd7, 0xff, 0xe3, 0xff, 0xdc, 0xff, 0xe4, 0xff, 0xe1, 0xff, 0xe6, 0xff, 0xe4, 0xff, 0xe8, 0xff, 0xe6, 0xff, 0xe9, 0xff, 0xe8, 0xff, 0xea, 0xff, 0xea, 0xff, 0xeb, 0xff, 0xed, 0xff, 0xec, 0xff, 0xf0, 0xff, 0xed, 0xff, 0xf3, 0xff, 0xed, 0xff, 0xf8, 0xff, 0xed, 0xff, 0xfd, 0xff, 0xee, 0xff, 0x02, 0x00, 0xee, 0xff, 0x08, 0x00, 0xef, 0xff, 0x0d, 0x00, 0xf0, 0xff, 0x12, 0x00, 0xf1, 0xff, 0x15, 0x00, 0xf4, 0xff, 0x17, 0x00, 0xf6, 0xff, 0x1a, 0x00, 0xf8, 0xff, 0x1c, 0x00, 0xfb, 0xff, 0x1f, 0x00, 0xfe, 0xff, 0x22, 0x00, 0x01, 0x00, 0x25, 0x00, 0x03, 0x00, 0x27, 0x00, 0x06, 0x00, 0x28, 0x00, 0x09, 0x00, 0x29, 0x00, 0x0d, 0x00, 0x2a, 0x00, 0x11, 0x00, 0x29, 0x00, 0x17, 0x00, 0x2a, 0x00, 0x1d, 0x00, 0x2a, 0x00, 0x22, 0x00, 0x2b, 0x00, 0x26, 0x00, 0x2c, 0x00, 0x29, 0x00, 0x2c, 0x00, 0x2b, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x28, 0x00, 0x2d, 0x00, 0x26, 0x00, 0x2e, 0x00, 0x24, 0x00, 0x31, 0x00, 0x23, 0x00, 0x34, 0x00, 0x21, 0x00, 0x37, 0x00, 0x1f, 0x00, 0x38, 0x00, 0x1b, 0x00, 0x37, 0x00, 0x16, 0x00, 0x34, 0x00, 0x10, 0x00, 0x30, 0x00, 0x0a, 0x00, 0x2d, 0x00, 0x04, 0x00, 0x2c, 0x00, 0xfe, 0xff, 0x2c, 0x00, 0xf8, 0xff, 0x2c, 0x00, 0xf2, 0xff, 0x2b, 0x00, 0xeb, 0xff, 0x29, 0x00, 0xe4, 0xff, 0x25, 0x00, 0xdc, 0xff, 0x21, 0x00, 0xd4, 0xff, 0x1d, 0x00, 0xcd, 0xff, 0x1b, 0x00, 0xc8, 0xff, 0x19, 0x00, 0xc4, 0xff, 0x18, 0x00, 0xc1, 0xff, 0x17, 0x00, 0xbd, 0xff, 0x16, 0x00, 0xba, 0xff, 0x13, 0x00, 0xb6, 0xff, 0x10, 0x00, 0xb2, 0xff, 0x0e, 0x00, 0xb0, 0xff, 0x0c, 0x00, 0xae, 0xff, 0x0a, 0x00, 0xac, 0xff, 0x08, 0x00, 0xac, 0xff, 0x05, 0x00, 0xad, 0xff, 0x02, 0x00, 0xae, 0xff, 0xff, 0xff, 0xb0, 0xff, 0xfd, 0xff, 0xb2, 0xff, 0xfc, 0xff, 0xb5, 0xff, 0xfc, 0xff, 0xb8, 0xff, 0xfd, 0xff, 0xbc, 0xff, 0xfd, 0xff, 0xc0, 0xff, 0xfc, 0xff, 0xc5, 0xff, 0xfa, 0xff, 0xca, 0xff, 0xf7, 0xff, 0xcf, 0xff, 0xf3, 0xff, 0xd4, 0xff, 0xf1, 0xff, 0xd9, 0xff, 0xef, 0xff, 0xdf, 0xff, 0xee, 0xff, 0xe5, 0xff, 0xee, 0xff, 0xeb, 0xff, 0xef, 0xff, 0xf0, 0xff, 0xef, 0xff, 0xf5, 0xff, 0xed, 0xff, 0xfa, 0xff, 0xeb, 0xff, 0xfe, 0xff, 0xe9, 0xff, 0x01, 0x00, 0xe6, 0xff, 0x05, 0x00, 0xe6, 0xff, 0x09, 0x00, 0xe6, 0xff, 0x0d, 0x00, 0xe8, 0xff, 0x11, 0x00, 0xeb, 0xff, 0x14, 0x00, 0xed, 0xff, 0x17, 0x00, 0xef, 0xff, 0x1a, 0x00, 0xef, 0xff, 0x1d, 0x00, 0xf0, 0xff, 0x1f, 0x00, 0xf1, 0xff, 0x21, 0x00, 0xf3, 0xff, 0x24, 0x00, 0xf6, 0xff, 0x27, 0x00, 0xfa, 0xff, 0x2a, 0x00, 0xff, 0xff, 0x2e, 0x00, 0x04, 0x00, 0x32, 0x00, 0x09, 0x00, 0x35, 0x00, 0x0d, 0x00, 0x37, 0x00, 0x10, 0x00, 0x37, 0x00, 0x12, 0x00, 0x37, 0x00, 0x14, 0x00, 0x37, 0x00, 0x16, 0x00, 0x38, 0x00, 0x18, 0x00, 0x3b, 0x00, 0x1b, 0x00, 0x3e, 0x00, 0x1e, 0x00, 0x40, 0x00, 0x21, 0x00, 0x41, 0x00, 0x23, 0x00, 0x3e, 0x00, 0x24, 0x00, 0x3a, 0x00, 0x23, 0x00, 0x35, 0x00, 0x21, 0x00, 0x30, 0x00, 0x1e, 0x00, 0x2c, 0x00, 0x1d, 0x00, 0x29, 0x00, 0x1d, 0x00, 0x27, 0x00, 0x1d, 0x00, 0x24, 0x00, 0x1e, 0x00, 0x20, 0x00, 0x1f, 0x00, 0x19, 0x00, 0x1d, 0x00, 0x12, 0x00, 0x1a, 0x00, 0x0a, 0x00, 0x16, 0x00, 0x03, 0x00, 0x12, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0xf8, 0xff, 0x0c, 0x00, 0xf3, 0xff, 0x0b, 0x00, 0xef, 0xff, 0x0a, 0x00, 0xeb, 0xff, 0x08, 0x00, 0xe7, 0xff, 0x05, 0x00, 0xe3, 0xff, 0x02, 0x00, 0xe0, 0xff, 0xfd, 0xff, 0xdd, 0xff, 0xf9, 0xff, 0xda, 0xff, 0xf6, 0xff, 0xd8, 0xff, 0xf3, 0xff, 0xd4, 0xff, 0xf0, 0xff, 0xd1, 0xff, 0xed, 0xff, 0xcf, 0xff, 0xe9, 0xff, 0xcd, 0xff, 0xe5, 0xff, 0xcc, 0xff, 0xe1, 0xff, 0xcc, 0xff, 0xdd, 0xff, 0xcd, 0xff, 0xda, 0xff, 0xcd, 0xff, 0xd8, 0xff, 0xcd, 0xff, 0xd7, 0xff, 0xcc, 0xff, 0xd6, 0xff, 0xcc, 0xff, 0xd4, 0xff, 0xcc, 0xff, 0xd1, 0xff, 0xcd, 0xff, 0xce, 0xff, 0xd0, 0xff, 0xca, 0xff, 0xd4, 0xff, 0xc8, 0xff, 0xd7, 0xff, 0xc6, 0xff, 0xdb, 0xff, 0xc5, 0xff, 0xde, 0xff, 0xc4, 0xff, 0xe1, 0xff, 0xc3, 0xff, 0xe4, 0xff, 0xc2, 0xff, 0xe7, 0xff, 0xc2, 0xff, 0xeb, 0xff, 0xc2, 0xff, 0xef, 0xff, 0xc3, 0xff, 0xf4, 0xff, 0xc5, 0xff, 0xf9, 0xff, 0xc7, 0xff, 0xfe, 0xff, 0xc9, 0xff, 0x02, 0x00, 0xcc, 0xff, 0x07, 0x00, 0xce, 0xff, 0x0c, 0x00, 0xd1, 0xff, 0x11, 0x00, 0xd5, 0xff, 0x16, 0x00, 0xdb, 0xff, 0x1b, 0x00, 0xe0, 0xff, 0x1f, 0x00, 0xe5, 0xff, 0x23, 0x00, 0xea, 0xff, 0x27, 0x00, 0xed, 0xff, 0x2a, 0x00, 0xf0, 0xff, 0x2e, 0x00, 0xf3, 0xff, 0x31, 0x00, 0xf8, 0xff, 0x34, 0x00, 0xfd, 0xff, 0x37, 0x00, 0x03, 0x00, 0x39, 0x00, 0x09, 0x00, 0x3a, 0x00, 0x0d, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x3a, 0x00, 0x13, 0x00, 0x3a, 0x00, 0x16, 0x00, 0x39, 0x00, 0x1a, 0x00, 0x37, 0x00, 0x1f, 0x00, 0x34, 0x00, 0x24, 0x00, 0x30, 0x00, 0x2a, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2b, 0x00, 0x31, 0x00, 0x2b, 0x00, 0x34, 0x00, 0x2a, 0x00, 0x36, 0x00, 0x29, 0x00, 0x37, 0x00, 0x26, 0x00, 0x38, 0x00, 0x23, 0x00, 0x3a, 0x00, 0x20, 0x00, 0x3c, 0x00, 0x1d, 0x00, 0x3e, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x1c, 0x00, 0x41, 0x00, 0x1c, 0x00, 0x42, 0x00, 0x1c, 0x00, 0x42, 0x00, 0x1a, 0x00, 0x42, 0x00, 0x18, 0x00, 0x41, 0x00, 0x14, 0x00, 0x3f, 0x00, 0x0f, 0x00, 0x3c, 0x00, 0x0b, 0x00, 0x3a, 0x00, 0x06, 0x00, 0x38, 0x00, 0x02, 0x00, 0x38, 0x00, 0xff, 0xff, 0x38, 0x00, 0xfc, 0xff, 0x37, 0x00, 0xf8, 0xff, 0x35, 0x00, 0xf4, 0xff, 0x31, 0x00, 0xef, 0xff, 0x2d, 0x00, 0xea, 0xff, 0x28, 0x00, 0xe6, 0xff, 0x23, 0x00, 0xe3, 0xff, 0x1e, 0x00, 0xe1, 0xff, 0x1a, 0x00, 0xe0, 0xff, 0x16, 0x00, 0xdf, 0xff, 0x12, 0x00, 0xdf, 0xff, 0x0d, 0x00, 0xdf, 0xff, 0x06, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xf8, 0xff, 0xe0, 0xff, 0xf2, 0xff, 0xe0, 0xff, 0xee, 0xff, 0xe2, 0xff, 0xec, 0xff, 0xe4, 0xff, 0xeb, 0xff, 0xe8, 0xff, 0xe9, 0xff, 0xed, 0xff, 0xe7, 0xff, 0xf3, 0xff, 0xe4, 0xff, 0xf9, 0xff, 0xe0, 0xff, 0xfe, 0xff, 0xdd, 0xff, 0x02, 0x00, 0xdb, 0xff, 0x05, 0x00, 0xda, 0xff, 0x07, 0x00, 0xda, 0xff, 0x0a, 0x00, 0xda, 0xff, 0x0e, 0x00, 0xda, 0xff, 0x12, 0x00, 0xda, 0xff, 0x17, 0x00, 0xda, 0xff, 0x1c, 0x00, 0xd9, 0xff, 0x20, 0x00, 0xd9, 0xff, 0x23, 0x00, 0xd9, 0xff, 0x24, 0x00, 0xda, 0xff, 0x25, 0x00, 0xdc, 0xff, 0x24, 0x00, 0xdf, 0xff, 0x23, 0x00, 0xe2, 0xff, 0x24, 0x00, 0xe5, 0xff, 0x24, 0x00, 0xe8, 0xff, 0x25, 0x00, 0xe9, 0xff, 0x26, 0x00, 0xeb, 0xff, 0x25, 0x00, 0xed, 0xff, 0x24, 0x00, 0xf1, 0xff, 0x23, 0x00, 0xf5, 0xff, 0x22, 0x00, 0xfa, 0xff, 0x22, 0x00, 0x00, 0x00, 0x22, 0x00, 0x05, 0x00, 0x22, 0x00, 0x08, 0x00, 0x23, 0x00, 0x09, 0x00, 0x23, 0x00, 0x09, 0x00, 0x23, 0x00, 0x08, 0x00, 0x23, 0x00, 0x08, 0x00, 0x23, 0x00, 0x0b, 0x00, 0x22, 0x00, 0x0f, 0x00, 0x21, 0x00, 0x14, 0x00, 0x20, 0x00, 0x18, 0x00, 0x1f, 0x00, 0x1a, 0x00, 0x1d, 0x00, 0x19, 0x00, 0x1c, 0x00, 0x17, 0x00, 0x1a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x14, 0x00, 0x13, 0x00, 0x15, 0x00, 0x0f, 0x00, 0x17, 0x00, 0x09, 0x00, 0x1a, 0x00, 0x03, 0x00, 0x1d, 0x00, 0xfd, 0xff, 0x1d, 0x00, 0xf8, 0xff, 0x1b, 0x00, 0xf3, 0xff, 0x17, 0x00, 0xee, 0xff, 0x12, 0x00, 0xea, 0xff, 0x0d, 0x00, 0xe5, 0xff, 0x0a, 0x00, 0xe0, 0xff, 0x08, 0x00, 0xd9, 0xff, 0x07, 0x00, 0xd3, 0xff, 0x06, 0x00, 0xcd, 0xff, 0x03, 0x00, 0xca, 0xff, 0x00, 0x00, 0xc9, 0xff, 0xfb, 0xff, 0xc8, 0xff, 0xf6, 0xff, 0xc8, 0xff, 0xf2, 0xff, 0xc8, 0xff, 0xee, 0xff, 0xc7, 0xff, 0xea, 0xff, 0xc5, 0xff, 0xe8, 0xff, 0xc4, 0xff, 0xe6, 0xff, 0xc3, 0xff, 0xe5, 0xff, 0xc3, 0xff, 0xe4, 0xff, 0xc6, 0xff, 0xe3, 0xff, 0xca, 0xff, 0xe0, 0xff, 0xce, 0xff, 0xdd, 0xff, 0xd1, 0xff, 0xd9, 0xff, 0xd2, 0xff, 0xd6, 0xff, 0xd1, 0xff, 0xd3, 0xff, 0xcf, 0xff, 0xd1, 0xff, 0xce, 0xff, 0xd2, 0xff, 0xcf, 0xff, 0xd3, 0xff, 0xd2, 0xff, 0xd4, 0xff, 0xd6, 0xff, 0xd5, 0xff, 0xda, 0xff, 0xd4, 0xff, 0xdd, 0xff, 0xd3, 0xff, 0xdf, 0xff, 0xd2, 0xff, 0xe0, 0xff, 0xd1, 0xff, 0xe0, 0xff, 0xd2, 0xff, 0xe0, 0xff, 0xd3, 0xff, 0xe1, 0xff, 0xd5, 0xff, 0xe5, 0xff, 0xd8, 0xff, 0xea, 0xff, 0xdb, 0xff, 0xf0, 0xff, 0xdd, 0xff, 0xf5, 0xff, 0xdf, 0xff, 0xfa, 0xff, 0xe1, 0xff, 0xfe, 0xff, 0xe4, 0xff, 0x01, 0x00, 0xe7, 0xff, 0x03, 0x00, 0xeb, 0xff, 0x04, 0x00, 0xef, 0xff, 0x06, 0x00, 0xf2, 0xff, 0x09, 0x00, 0xf5, 0xff, 0x0d, 0x00, 0xf9, 0xff, 0x12, 0x00, 0xfc, 0xff, 0x17, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x21, 0x00, 0x08, 0x00, 0x24, 0x00, 0x0b, 0x00, 0x25, 0x00, 0x0e, 0x00, 0x25, 0x00, 0x11, 0x00, 0x24, 0x00, 0x14, 0x00, 0x24, 0x00, 0x18, 0x00, 0x24, 0x00, 0x1c, 0x00, 0x25, 0x00, 0x1e, 0x00, 0x27, 0x00, 0x20, 0x00, 0x28, 0x00, 0x20, 0x00, 0x27, 0x00, 0x1f, 0x00, 0x25, 0x00, 0x1f, 0x00, 0x21, 0x00, 0x20, 0x00, 0x1c, 0x00, 0x23, 0x00, 0x17, 0x00, 0x26, 0x00, 0x14, 0x00, 0x29, 0x00, 0x11, 0x00, 0x2b, 0x00, 0x0f, 0x00, 0x2b, 0x00, 0x0d, 0x00, 0x28, 0x00, 0x0b, 0x00, 0x25, 0x00, 0x07, 0x00, 0x22, 0x00, 0x03, 0x00, 0x21, 0x00, 0xff, 0xff, 0x23, 0x00, 0xfc, 0xff, 0x25, 0x00, 0xf9, 0xff, 0x27, 0x00, 0xf8, 0xff, 0x28, 0x00, 0xf7, 0xff, 0x25, 0x00, 0xf5, 0xff, 0x21, 0x00, 0xf4, 0xff, 0x1c, 0x00, 0xf2, 0xff, 0x18, 0x00, 0xf0, 0xff, 0x15, 0x00, 0xed, 0xff, 0x15, 0x00, 0xea, 0xff, 0x15, 0x00, 0xe7, 0xff, 0x14, 0x00, 0xe4, 0xff, 0x13, 0x00, 0xe1, 0xff, 0x0f, 0x00, 0xe0, 0xff, 0x0a, 0x00, 0xdf, 0xff, 0x04, 0x00, 0xde, 0xff, 0xff, 0xff, 0xdd, 0xff, 0xfc, 0xff, 0xdc, 0xff, 0xfa, 0xff, 0xda, 0xff, 0xf9, 0xff, 0xd8, 0xff, 0xf8, 0xff, 0xd6, 0xff, 0xf5, 0xff, 0xd5, 0xff, 0xf0, 0xff, 0xd5, 0xff, 0xeb, 0xff, 0xd6, 0xff, 0xe6, 0xff, 0xd9, 0xff, 0xe2, 0xff, 0xdb, 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xdd, 0xff, 0xde, 0xff, 0xdd, 0xff, 0xde, 0xff, 0xdd, 0xff, 0xde, 0xff, 0xdd, 0xff, 0xde, 0xff, 0xde, 0xff, 0xdf, 0xff, 0xde, 0xff, 0xe2, 0xff, 0xdd, 0xff, 0xe5, 0xff, 0xdc, 0xff, 0xe9, 0xff, 0xdc, 0xff, 0xec, 0xff, 0xdc, 0xff, 0xed, 0xff, 0xdf, 0xff, 0xee, 0xff, 0xe1, 0xff, 0xf0, 0xff, 0xe5, 0xff, 0xf3, 0xff, 0xe9, 0xff, 0xf7, 0xff, 0xec, 0xff, 0xfb, 0xff, 0xef, 0xff, 0x00, 0x00, 0xf1, 0xff, 0x04, 0x00, 0xf1, 0xff, 0x08, 0x00, 0xf2, 0xff, 0x0c, 0x00, 0xf3, 0xff, 0x0f, 0x00, 0xf6, 0xff, 0x13, 0x00, 0xf9, 0xff, 0x17, 0x00, 0xfe, 0xff, 0x1a, 0x00, 0x02, 0x00, 0x1e, 0x00, 0x06, 0x00, 0x22, 0x00, 0x09, 0x00, 0x25, 0x00, 0x0b, 0x00, 0x28, 0x00, 0x0c, 0x00, 0x2a, 0x00, 0x0d, 0x00, 0x2c, 0x00, 0x0f, 0x00, 0x2c, 0x00, 0x12, 0x00, 0x2c, 0x00, 0x17, 0x00, 0x2c, 0x00, 0x1c, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x2d, 0x00, 0x23, 0x00, 0x2e, 0x00, 0x24, 0x00, 0x2e, 0x00, 0x25, 0x00, 0x2d, 0x00, 0x25, 0x00, 0x2b, 0x00, 0x26, 0x00, 0x28, 0x00, 0x28, 0x00, 0x24, 0x00, 0x29, 0x00, 0x20, 0x00, 0x2b, 0x00, 0x1c, 0x00, 0x2c, 0x00, 0x1b, 0x00, 0x2c, 0x00, 0x1a, 0x00, 0x2b, 0x00, 0x19, 0x00, 0x29, 0x00, 0x17, 0x00, 0x27, 0x00, 0x13, 0x00, 0x24, 0x00, 0x0e, 0x00, 0x22, 0x00, 0x08, 0x00, 0x21, 0x00, 0x02, 0x00, 0x20, 0x00, 0xff, 0xff, 0x20, 0x00, 0xfd, 0xff, 0x1f, 0x00, 0xfc, 0xff, 0x1e, 0x00, 0xfb, 0xff, 0x1c, 0x00, 0xf9, 0xff, 0x19, 0x00, 0xf7, 0xff, 0x16, 0x00, 0xf4, 0xff, 0x13, 0x00, 0xf1, 0xff, 0x10, 0x00, 0xee, 0xff, 0x0e, 0x00, 0xec, 0xff, 0x0c, 0x00, 0xec, 0xff, 0x0b, 0x00, 0xec, 0xff, 0x09, 0x00, 0xed, 0xff, 0x05, 0x00, 0xee, 0xff, 0x01, 0x00, 0xee, 0xff, 0xfd, 0xff, 0xed, 0xff, 0xf9, 0xff, 0xed, 0xff, 0xf8, 0xff, 0xed, 0xff, 0xf7, 0xff, 0xed, 0xff, 0xf7, 0xff, 0xec, 0xff, 0xf6, 0xff, 0xec, 0xff, 0xf6, 0xff, 0xec, 0xff, 0xf4, 0xff, 0xed, 0xff, 0xf1, 0xff, 0xef, 0xff, 0xed, 0xff, 0xf2, 0xff, 0xea, 0xff, 0xf5, 0xff, 0xe8, 0xff, 0xf9, 0xff, 0xe7, 0xff, 0xfb, 0xff, 0xe8, 0xff, 0xfd, 0xff, 0xe9, 0xff, 0xfd, 0xff, 0xe9, 0xff, 0xfe, 0xff, 0xe8, 0xff, 0xff, 0xff, 0xe6, 0xff, 0x02, 0x00, 0xe4, 0xff, 0x06, 0x00, 0xe2, 0xff, 0x0c, 0x00, 0xe0, 0xff, 0x12, 0x00, 0xde, 0xff, 0x16, 0x00, 0xdd, 0xff, 0x1a, 0x00, 0xde, 0xff, 0x1d, 0x00, 0xdf, 0xff, 0x1f, 0x00, 0xe1, 0xff, 0x21, 0x00, 0xe3, 0xff, 0x23, 0x00, 0xe6, 0xff, 0x26, 0x00, 0xe8, 0xff, 0x29, 0x00, 0xeb, 0xff, 0x2d, 0x00, 0xef, 0xff, 0x31, 0x00, 0xf3, 0xff, 0x35, 0x00, 0xf8, 0xff, 0x38, 0x00, 0xfc, 0xff, 0x3a, 0x00, 0x01, 0x00, 0x3b, 0x00, 0x05, 0x00, 0x3b, 0x00, 0x09, 0x00, 0x39, 0x00, 0x0c, 0x00, 0x38, 0x00, 0x0f, 0x00, 0x36, 0x00, 0x12, 0x00, 0x35, 0x00, 0x14, 0x00, 0x35, 0x00, 0x16, 0x00, 0x34, 0x00, 0x17, 0x00, 0x32, 0x00, 0x17, 0x00, 0x2f, 0x00, 0x17, 0x00, 0x2a, 0x00, 0x18, 0x00, 0x24, 0x00, 0x18, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x17, 0x00, 0x17, 0x00, 0x13, 0x00, 0x16, 0x00, 0x11, 0x00, 0x16, 0x00, 0x0f, 0x00, 0x16, 0x00, 0x0c, 0x00, 0x16, 0x00, 0x07, 0x00, 0x17, 0x00, 0x00, 0x00, 0x17, 0x00, 0xfa, 0xff, 0x17, 0x00, 0xf4, 0xff, 0x16, 0x00, 0xf0, 0xff, 0x14, 0x00, 0xee, 0xff, 0x11, 0x00, 0xec, 0xff, 0x0e, 0x00, 0xeb, 0xff, 0x0b, 0x00, 0xea, 0xff, 0x08, 0x00, 0xe8, 0xff, 0x06, 0x00, 0xe5, 0xff, 0x04, 0x00, 0xe2, 0xff, 0x02, 0x00, 0xdf, 0xff, 0xfe, 0xff, 0xdc, 0xff, 0xfa, 0xff, 0xd9, 0xff, 0xf6, 0xff, 0xd8, 0xff, 0xf2, 0xff, 0xd7, 0xff, 0xef, 0xff, 0xd7, 0xff, 0xed, 0xff, 0xd8, 0xff, 0xeb, 0xff, 0xd9, 0xff, 0xe9, 0xff, 0xd9, 0xff, 0xe7, 0xff, 0xd9, 0xff, 0xe5, 0xff, 0xd8, 0xff, 0xe2, 0xff, 0xd6, 0xff, 0xe0, 0xff, 0xd3, 0xff, 0xde, 0xff, 0xd3, 0xff, 0xdc, 0xff, 0xd6, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xdb, 0xff, 0xe1, 0xff, 0xdc, 0xff, 0xe7, 0xff, 0xdb, 0xff, 0xeb, 0xff, 0xda, 0xff, 0xec, 0xff, 0xd9, 0xff, 0xeb, 0xff, 0xd8, 0xff, 0xea, 0xff, 0xd7, 0xff, 0xeb, 0xff, 0xd6, 0xff, 0xee, 0xff, 0xd6, 0xff, 0xf2, 0xff, 0xd6, 0xff, 0xf8, 0xff, 0xd7, 0xff, 0xfc, 0xff, 0xd8, 0xff, 0xfe, 0xff, 0xda, 0xff, 0xfc, 0xff, 0xdc, 0xff, 0xf9, 0xff, 0xdd, 0xff, 0xf5, 0xff, 0xdf, 0xff, 0xf3, 0xff, 0xe1, 0xff, 0xf3, 0xff, 0xe3, 0xff, 0xf5, 0xff, 0xe5, 0xff, 0xf8, 0xff, 0xe7, 0xff, 0xf9, 0xff, 0xe9, 0xff, 0xf9, 0xff, 0xeb, 0xff, 0xf7, 0xff, 0xee, 0xff, 0xf4, 0xff, 0xf0, 0xff, 0xf2, 0xff, 0xf3, 0xff, 0xf2, 0xff, 0xf5, 0xff, 0xf3, 0xff, 0xf6, 0xff, 0xf5, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x02, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf4, 0xff, 0x04, 0x00, 0xf2, 0xff, 0x05, 0x00, 0xf2, 0xff, 0x07, 0x00, 0xf3, 0xff, 0x09, 0x00, 0xf5, 0xff, 0x0b, 0x00, 0xf6, 0xff, 0x0d, 0x00, 0xf5, 0xff, 0x0e, 0x00, 0xf4, 0xff, 0x0f, 0x00, 0xf2, 0xff, 0x10, 0x00, 0xef, 0xff, 0x11, 0x00, 0xed, 0xff, 0x14, 0x00, 0xed, 0xff, 0x17, 0x00, 0xee, 0xff, 0x1a, 0x00, 0xf0, 0xff, 0x1d, 0x00, 0xf2, 0xff, 0x1e, 0x00, 0xf3, 0xff, 0x1d, 0x00, 0xf2, 0xff, 0x1c, 0x00, 0xee, 0xff, 0x1b, 0x00, 0xe9, 0xff, 0x19, 0x00, 0xe5, 0xff, 0x19, 0x00, 0xe2, 0xff, 0x1a, 0x00, 0xe2, 0xff, 0x1b, 0x00, 0xe3, 0xff, 0x1c, 0x00, 0xe5, 0xff, 0x1c, 0x00, 0xe7, 0xff, 0x1b, 0x00, 0xe6, 0xff, 0x1a, 0x00, 0xe5, 0xff, 0x19, 0x00, 0xe2, 0xff, 0x18, 0x00, 0xe1, 0xff, 0x17, 0x00, 0xe2, 0xff, 0x16, 0x00, 0xe5, 0xff, 0x15, 0x00, 0xe9, 0xff, 0x15, 0x00, 0xee, 0xff, 0x14, 0x00, 0xf3, 0xff, 0x14, 0x00, 0xf7, 0xff, 0x13, 0x00, 0xfa, 0xff, 0x12, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x08, 0x00, 0x07, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x10, 0x00, 0x01, 0x00, 0x14, 0x00, 0x01, 0x00, 0x16, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0xfd, 0xff, 0x1a, 0x00, 0xf8, 0xff, 0x1b, 0x00, 0xf2, 0xff, 0x1d, 0x00, 0xed, 0xff, 0x1f, 0x00, 0xea, 0xff, 0x22, 0x00, 0xea, 0xff, 0x26, 0x00, 0xeb, 0xff, 0x29, 0x00, 0xee, 0xff, 0x2b, 0x00, 0xef, 0xff, 0x2c, 0x00, 0xee, 0xff, 0x2b, 0x00, 0xec, 0xff, 0x29, 0x00, 0xe9, 0xff, 0x28, 0x00, 0xe6, 0xff, 0x28, 0x00, 0xe5, 0xff, 0x29, 0x00, 0xe5, 0xff, 0x2b, 0x00, 0xe6, 0xff, 0x2d, 0x00, 0xe8, 0xff, 0x2e, 0x00, 0xea, 0xff, 0x2d, 0x00, 0xeb, 0xff, 0x2b, 0x00, 0xed, 0xff, 0x28, 0x00, 0xee, 0xff, 0x26, 0x00, 0xf0, 0xff, 0x26, 0x00, 0xf2, 0xff, 0x27, 0x00, 0xf5, 0xff, 0x29, 0x00, 0xf7, 0xff, 0x2b, 0x00, 0xf9, 0xff, 0x2c, 0x00, 0xfc, 0xff, 0x2b, 0x00, 0x00, 0x00, 0x29, 0x00, 0x04, 0x00, 0x25, 0x00, 0x07, 0x00, 0x22, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x0d, 0x00, 0x1f, 0x00, 0x0e, 0x00, 0x1f, 0x00, 0x0f, 0x00, 0x20, 0x00, 0x11, 0x00, 0x1e, 0x00, 0x12, 0x00, 0x1b, 0x00, 0x13, 0x00, 0x15, 0x00, 0x14, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x08, 0x00, 0x14, 0x00, 0x03, 0x00, 0x14, 0x00, 0xff, 0xff, 0x14, 0x00, 0xfc, 0xff, 0x14, 0x00, 0xfb, 0xff, 0x16, 0x00, 0xf9, 0xff, 0x18, 0x00, 0xf7, 0xff, 0x1a, 0x00, 0xf4, 0xff, 0x1b, 0x00, 0xf1, 0xff, 0x1b, 0x00, 0xef, 0xff, 0x19, 0x00, 0xec, 0xff, 0x18, 0x00, 0xeb, 0xff, 0x17, 0x00, 0xea, 0xff, 0x17, 0x00, 0xe9, 0xff, 0x19, 0x00, 0xe9, 0xff, 0x1c, 0x00, 0xea, 0xff, 0x1f, 0x00, 0xeb, 0xff, 0x21, 0x00, 0xec, 0xff, 0x21, 0x00, 0xeb, 0xff, 0x20, 0x00, 0xea, 0xff, 0x1e, 0x00, 0xe9, 0xff, 0x1d, 0x00, 0xe8, 0xff, 0x1d, 0x00, 0xe8, 0xff, 0x1d, 0x00, 0xe8, 0xff, 0x1e, 0x00, 0xea, 0xff, 0x1e, 0x00, 0xeb, 0xff, 0x1e, 0x00, 0xed, 0xff, 0x1c, 0x00, 0xee, 0xff, 0x1a, 0x00, 0xed, 0xff, 0x17, 0x00, 0xec, 0xff, 0x13, 0x00, 0xeb, 0xff, 0x10, 0x00, 0xeb, 0xff, 0x0d, 0x00, 0xec, 0xff, 0x0b, 0x00, 0xee, 0xff, 0x0a, 0x00, 0xf0, 0xff, 0x09, 0x00, 0xf3, 0xff, 0x09, 0x00, 0xf4, 0xff, 0x08, 0x00, 0xf4, 0xff, 0x05, 0x00, 0xf3, 0xff, 0x01, 0x00, 0xf3, 0xff, 0xfb, 0xff, 0xf2, 0xff, 0xf5, 0xff, 0xf3, 0xff, 0xf0, 0xff, 0xf5, 0xff, 0xef, 0xff, 0xf8, 0xff, 0xf0, 0xff, 0xfb, 0xff, 0xf2, 0xff, 0xfd, 0xff, 0xf5, 0xff, 0xff, 0xff, 0xf5, 0xff, 0x01, 0x00, 0xf2, 0xff, 0x04, 0x00, 0xee, 0xff, 0x06, 0x00, 0xe9, 0xff, 0x09, 0x00, 0xe5, 0xff, 0x0a, 0x00, 0xe5, 0xff, 0x0b, 0x00, 0xe6, 0xff, 0x0c, 0x00, 0xe9, 0xff, 0x0d, 0x00, 0xec, 0xff, 0x0e, 0x00, 0xed, 0xff, 0x10, 0x00, 0xec, 0xff, 0x11, 0x00, 0xe9, 0xff, 0x12, 0x00, 0xe6, 0xff, 0x12, 0x00, 0xe4, 0xff, 0x11, 0x00, 0xe4, 0xff, 0x0f, 0x00, 0xe5, 0xff, 0x0d, 0x00, 0xe8, 0xff, 0x0a, 0x00, 0xeb, 0xff, 0x08, 0x00, 0xed, 0xff, 0x06, 0x00, 0xee, 0xff, 0x04, 0x00, 0xee, 0xff, 0x03, 0x00, 0xed, 0xff, 0x01, 0x00, 0xec, 0xff, 0xfe, 0xff, 0xec, 0xff, 0xfc, 0xff, 0xed, 0xff, 0xf9, 0xff, 0xf0, 0xff, 0xf7, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf9, 0xff, 0xf2, 0xff, 0xfd, 0xff, 0xf1, 0xff, 0x01, 0x00, 0xef, 0xff, 0x03, 0x00, 0xed, 0xff, 0x03, 0x00, 0xeb, 0xff, 0x02, 0x00, 0xea, 0xff, 0x02, 0x00, 0xe9, 0xff, 0x03, 0x00, 0xe9, 0xff, 0x06, 0x00, 0xe9, 0xff, 0x0a, 0x00, 0xe9, 0xff, 0x0e, 0x00, 0xe9, 0xff, 0x11, 0x00, 0xe9, 0xff, 0x12, 0x00, 0xe9, 0xff, 0x0f, 0x00, 0xea, 0xff, 0x0b, 0x00, 0xea, 0xff, 0x07, 0x00, 0xeb, 0xff, 0x03, 0x00, 0xec, 0xff, 0x02, 0x00, 0xec, 0xff, 0x03, 0x00, 0xed, 0xff, 0x04, 0x00, 0xee, 0xff, 0x05, 0x00, 0xf0, 0xff, 0x04, 0x00, 0xf2, 0xff, 0x02, 0x00, 0xf3, 0xff, 0xfe, 0xff, 0xf5, 0xff, 0xfb, 0xff, 0xf5, 0xff, 0xf8, 0xff, 0xf5, 0xff, 0xf8, 0xff, 0xf5, 0xff, 0xfb, 0xff, 0xf5, 0xff, 0xfe, 0xff, 0xf5, 0xff, 0x01, 0x00, 0xf7, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x10, 0x00, 0xff, 0xff, 0x13, 0x00, 0x00, 0x00, 0x16, 0x00, 0x02, 0x00, 0x16, 0x00, 0x04, 0x00, 0x15, 0x00, 0x05, 0x00, 0x12, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x0c, 0x00, 0x11, 0x00, 0x0c, 0x00, 0x13, 0x00, 0x0c, 0x00, 0x15, 0x00, 0x09, 0x00, 0x16, 0x00, 0x05, 0x00, 0x17, 0x00, 0x01, 0x00, 0x18, 0x00, 0xfc, 0xff, 0x1a, 0x00, 0xf9, 0xff, 0x1c, 0x00, 0xf7, 0xff, 0x1d, 0x00, 0xf7, 0xff, 0x1d, 0x00, 0xf8, 0xff, 0x1c, 0x00, 0xfa, 0xff, 0x1b, 0x00, 0xfb, 0xff, 0x1a, 0x00, 0xfa, 0xff, 0x1a, 0x00, 0xf9, 0xff, 0x1b, 0x00, 0xf7, 0xff, 0x1b, 0x00, 0xf7, 0xff, 0x1b, 0x00, 0xf8, 0xff, 0x1a, 0x00, 0xfb, 0xff, 0x17, 0x00, 0xff, 0xff, 0x14, 0x00, 0x02, 0x00, 0x12, 0x00, 0x04, 0x00, 0x11, 0x00, 0x05, 0x00, 0x13, 0x00, 0x04, 0x00, 0x15, 0x00, 0x04, 0x00, 0x17, 0x00, 0x03, 0x00, 0x16, 0x00, 0x03, 0x00, 0x13, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x07, 0x00, 0x06, 0x00, 0x07, 0x00, 0x06, 0x00, 0x07, 0x00, 0x05, 0x00, 0x07, 0x00, 0x02, 0x00, 0x06, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xf5, 0xff, 0x06, 0x00, 0xf1, 0xff, 0x09, 0x00, 0xef, 0xff, 0x0c, 0x00, 0xee, 0xff, 0x0f, 0x00, 0xed, 0xff, 0x10, 0x00, 0xeb, 0xff, 0x10, 0x00, 0xe9, 0xff, 0x0d, 0x00, 0xe6, 0xff, 0x0a, 0x00, 0xe4, 0xff, 0x08, 0x00, 0xe2, 0xff, 0x07, 0x00, 0xe0, 0xff, 0x08, 0x00, 0xdf, 0xff, 0x0b, 0x00, 0xdf, 0xff, 0x0e, 0x00, 0xdf, 0xff, 0x10, 0x00, 0xe1, 0xff, 0x10, 0x00, 0xe3, 0xff, 0x0d, 0x00, 0xe5, 0xff, 0x08, 0x00, 0xe7, 0xff, 0x04, 0x00, 0xe8, 0xff, 0x01, 0x00, 0xe8, 0xff, 0x00, 0x00, 0xe9, 0xff, 0x02, 0x00, 0xeb, 0xff, 0x04, 0x00, 0xef, 0xff, 0x05, 0x00, 0xf3, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xfd, 0xff, 0xfc, 0xff, 0x01, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf1, 0xff, 0x04, 0x00, 0xee, 0xff, 0x03, 0x00, 0xed, 0xff, 0x03, 0x00, 0xed, 0xff, 0x04, 0x00, 0xed, 0xff, 0x06, 0x00, 0xed, 0xff, 0x08, 0x00, 0xeb, 0xff, 0x0b, 0x00, 0xe8, 0xff, 0x0c, 0x00, 0xe5, 0xff, 0x0d, 0x00, 0xe1, 0xff, 0x0d, 0x00, 0xde, 0xff, 0x0c, 0x00, 0xdc, 0xff, 0x0b, 0x00, 0xdc, 0xff, 0x0b, 0x00, 0xde, 0xff, 0x0b, 0x00, 0xe0, 0xff, 0x0b, 0x00, 0xe1, 0xff, 0x0c, 0x00, 0xe1, 0xff, 0x0d, 0x00, 0xe0, 0xff, 0x0e, 0x00, 0xde, 0xff, 0x0f, 0x00, 0xdc, 0xff, 0x10, 0x00, 0xdb, 0xff, 0x11, 0x00, 0xda, 0xff, 0x12, 0x00, 0xda, 0xff, 0x13, 0x00, 0xdb, 0xff, 0x14, 0x00, 0xdc, 0xff, 0x15, 0x00, 0xdd, 0xff, 0x16, 0x00, 0xdc, 0xff, 0x16, 0x00, 0xdb, 0xff, 0x17, 0x00, 0xd9, 0xff, 0x16, 0x00, 0xd8, 0xff, 0x15, 0x00, 0xd9, 0xff, 0x14, 0x00, 0xda, 0xff, 0x13, 0x00, 0xdc, 0xff, 0x13, 0x00, 0xdf, 0xff, 0x13, 0x00, 0xe0, 0xff, 0x14, 0x00, 0xe0, 0xff, 0x13, 0x00, 0xe0, 0xff, 0x11, 0x00, 0xdf, 0xff, 0x0e, 0x00, 0xde, 0xff, 0x0b, 0x00, 0xdf, 0xff, 0x08, 0x00, 0xe2, 0xff, 0x05, 0x00, 0xe5, 0xff, 0x03, 0x00, 0xe8, 0xff, 0x01, 0x00, 0xeb, 0xff, 0xff, 0xff, 0xec, 0xff, 0xfc, 0xff, 0xec, 0xff, 0xfa, 0xff, 0xec, 0xff, 0xf7, 0xff, 0xec, 0xff, 0xf4, 0xff, 0xee, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xf0, 0xff, 0xf6, 0xff, 0xef, 0xff, 0xfb, 0xff, 0xed, 0xff, 0xff, 0xff, 0xeb, 0xff, 0x03, 0x00, 0xe8, 0xff, 0x05, 0x00, 0xe6, 0xff, 0x06, 0x00, 0xe4, 0xff, 0x07, 0x00, 0xe2, 0xff, 0x08, 0x00, 0xe2, 0xff, 0x0a, 0x00, 0xe1, 0xff, 0x0d, 0x00, 0xe2, 0xff, 0x10, 0x00, 0xe2, 0xff, 0x13, 0x00, 0xe3, 0xff, 0x15, 0x00, 0xe3, 0xff, 0x16, 0x00, 0xe4, 0xff, 0x15, 0x00, 0xe5, 0xff, 0x13, 0x00, 0xe7, 0xff, 0x11, 0x00, 0xe7, 0xff, 0x10, 0x00, 0xe8, 0xff, 0x0f, 0x00, 0xe8, 0xff, 0x0f, 0x00, 0xe8, 0xff, 0x10, 0x00, 0xea, 0xff, 0x11, 0x00, 0xed, 0xff, 0x12, 0x00, 0xf0, 0xff, 0x11, 0x00, 0xf4, 0xff, 0x10, 0x00, 0xf6, 0xff, 0x0e, 0x00, 0xf8, 0xff, 0x0d, 0x00, 0xf8, 0xff, 0x0d, 0x00, 0xf8, 0xff, 0x0e, 0x00, 0xf7, 0xff, 0x10, 0x00, 0xf8, 0xff, 0x12, 0x00, 0xfa, 0xff, 0x13, 0x00, 0xfd, 0xff, 0x14, 0x00, 0x01, 0x00, 0x14, 0x00, 0x05, 0x00, 0x14, 0x00, 0x09, 0x00, 0x13, 0x00, 0x0c, 0x00, 0x12, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x11, 0x00, 0x14, 0x00, 0x14, 0x00, 0x15, 0x00, 0x17, 0x00, 0x15, 0x00, 0x1a, 0x00, 0x15, 0x00, 0x1d, 0x00, 0x14, 0x00, 0x20, 0x00, 0x13, 0x00, 0x24, 0x00, 0x12, 0x00, 0x27, 0x00, 0x10, 0x00, 0x2a, 0x00, 0x0f, 0x00, 0x2b, 0x00, 0x0f, 0x00, 0x2a, 0x00, 0x0f, 0x00, 0x29, 0x00, 0x10, 0x00, 0x28, 0x00, 0x10, 0x00, 0x27, 0x00, 0x10, 0x00, 0x27, 0x00, 0x0e, 0x00, 0x26, 0x00, 0x0c, 0x00, 0x26, 0x00, 0x0a, 0x00, 0x24, 0x00, 0x0a, 0x00, 0x21, 0x00, 0x0a, 0x00, 0x1d, 0x00, 0x0b, 0x00, 0x19, 0x00, 0x0c, 0x00, 0x15, 0x00, 0x0d, 0x00, 0x12, 0x00, 0x0e, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x0d, 0x00, 0xff, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x12, 0x00, 0xfb, 0xff, 0x14, 0x00, 0xf9, 0xff, 0x16, 0x00, 0xf8, 0xff, 0x18, 0x00, 0xf6, 0xff, 0x18, 0x00, 0xf3, 0xff, 0x18, 0x00, 0xf1, 0xff, 0x18, 0x00, 0xf0, 0xff, 0x18, 0x00, 0xf0, 0xff, 0x19, 0x00, 0xf1, 0xff, 0x1b, 0x00, 0xf1, 0xff, 0x1d, 0x00, 0xf1, 0xff, 0x1f, 0x00, 0xf0, 0xff, 0x21, 0x00, 0xee, 0xff, 0x21, 0x00, 0xec, 0xff, 0x1f, 0x00, 0xeb, 0xff, 0x1d, 0x00, 0xeb, 0xff, 0x1c, 0x00, 0xec, 0xff, 0x1b, 0x00, 0xed, 0xff, 0x1b, 0x00, 0xed, 0xff, 0x1b, 0x00, 0xee, 0xff, 0x1b, 0x00, 0xee, 0xff, 0x1b, 0x00, 0xed, 0xff, 0x1b, 0x00, 0xec, 0xff, 0x19, 0x00, 0xeb, 0xff, 0x16, 0x00, 0xea, 0xff, 0x14, 0x00, 0xea, 0xff, 0x12, 0x00, 0xea, 0xff, 0x12, 0x00, 0xea, 0xff, 0x12, 0x00, 0xec, 0xff, 0x12, 0x00, 0xee, 0xff, 0x12, 0x00, 0xf1, 0xff, 0x12, 0x00, 0xf4, 0xff, 0x11, 0x00, 0xf7, 0xff, 0x0f, 0x00, 0xf9, 0xff, 0x0e, 0x00, 0xfb, 0xff, 0x0e, 0x00, 0xfd, 0xff, 0x0d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x09, 0x00, 0x1a, 0x00, 0x07, 0x00, 0x1c, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x02, 0x00, 0x1f, 0x00, 0xff, 0xff, 0x21, 0x00, 0xfd, 0xff, 0x22, 0x00, 0xfb, 0xff, 0x24, 0x00, 0xf9, 0xff, 0x25, 0x00, 0xf8, 0xff, 0x25, 0x00, 0xf7, 0xff, 0x25, 0x00, 0xf6, 0xff, 0x25, 0x00, 0xf4, 0xff, 0x24, 0x00, 0xf2, 0xff, 0x23, 0x00, 0xf0, 0xff, 0x20, 0x00, 0xef, 0xff, 0x1e, 0x00, 0xee, 0xff, 0x1b, 0x00, 0xed, 0xff, 0x19, 0x00, 0xec, 0xff, 0x18, 0x00, 0xeb, 0xff, 0x17, 0x00, 0xeb, 0xff, 0x16, 0x00, 0xea, 0xff, 0x15, 0x00, 0xeb, 0xff, 0x13, 0x00, 0xeb, 0xff, 0x0f, 0x00, 0xec, 0xff, 0x0b, 0x00, 0xed, 0xff, 0x06, 0x00, 0xec, 0xff, 0x02, 0x00, 0xeb, 0xff, 0xfe, 0xff, 0xe9, 0xff, 0xfb, 0xff, 0xe9, 0xff, 0xf6, 0xff, 0xe9, 0xff, 0xf1, 0xff, 0xea, 0xff, 0xec, 0xff, 0xec, 0xff, 0xe6, 0xff, 0xed, 0xff, 0xe2, 0xff, 0xed, 0xff, 0xdf, 0xff, 0xec, 0xff, 0xdc, 0xff, 0xeb, 0xff, 0xda, 0xff, 0xea, 0xff, 0xd8, 0xff, 0xeb, 0xff, 0xd4, 0xff, 0xed, 0xff, 0xd0, 0xff, 0xef, 0xff, 0xcc, 0xff, 0xf3, 0xff, 0xc9, 0xff, 0xf6, 0xff, 0xc7, 0xff, 0xf7, 0xff, 0xc7, 0xff, 0xf7, 0xff, 0xc7, 0xff, 0xf5, 0xff, 0xc7, 0xff, 0xf3, 0xff, 0xc8, 0xff, 0xf2, 0xff, 0xc8, 0xff, 0xf2, 0xff, 0xc8, 0xff, 0xf4, 0xff, 0xc9, 0xff, 0xf7, 0xff, 0xcb, 0xff, 0xf9, 0xff, 0xcd, 0xff, 0xfb, 0xff, 0xcf, 0xff, 0xfb, 0xff, 0xd1, 0xff, 0xfa, 0xff, 0xd2, 0xff, 0xf8, 0xff, 0xd3, 0xff, 0xf6, 0xff, 0xd4, 0xff, 0xf4, 0xff, 0xd6, 0xff, 0xf4, 0xff, 0xd9, 0xff, 0xf4, 0xff, 0xdc, 0xff, 0xf4, 0xff, 0xe0, 0xff, 0xf4, 0xff, 0xe3, 0xff, 0xf4, 0xff, 0xe6, 0xff, 0xf3, 0xff, 0xe9, 0xff, 0xf1, 0xff, 0xeb, 0xff, 0xef, 0xff, 0xee, 0xff, 0xed, 0xff, 0xf2, 0xff, 0xea, 0xff, 0xf5, 0xff, 0xe8, 0xff, 0xf9, 0xff, 0xe7, 0xff, 0xfe, 0xff, 0xe6, 0xff, 0x02, 0x00, 0xe5, 0xff, 0x07, 0x00, 0xe5, 0xff, 0x0b, 0x00, 0xe4, 0xff, 0x0f, 0x00, 0xe3, 0xff, 0x13, 0x00, 0xe1, 0xff, 0x16, 0x00, 0xdf, 0xff, 0x1a, 0x00, 0xdd, 0xff, 0x1f, 0x00, 0xdb, 0xff, 0x23, 0x00, 0xdb, 0xff, 0x28, 0x00, 0xdd, 0xff, 0x2c, 0x00, 0xdf, 0xff, 0x31, 0x00, 0xe1, 0xff, 0x35, 0x00, 0xe2, 0xff, 0x39, 0x00, 0xe1, 0xff, 0x3b, 0x00, 0xe0, 0xff, 0x3c, 0x00, 0xdf, 0xff, 0x3d, 0x00, 0xdf, 0xff, 0x3d, 0x00, 0xe0, 0xff, 0x3e, 0x00, 0xe2, 0xff, 0x3e, 0x00, 0xe5, 0xff, 0x3c, 0x00, 0xe9, 0xff, 0x39, 0x00, 0xec, 0xff, 0x35, 0x00, 0xef, 0xff, 0x31, 0x00, 0xf0, 0xff, 0x2c, 0x00, 0xf1, 0xff, 0x27, 0x00, 0xf2, 0xff, 0x23, 0x00, 0xf3, 0xff, 0x1e, 0x00, 0xf5, 0xff, 0x1a, 0x00, 0xf7, 0xff, 0x15, 0x00, 0xf9, 0xff, 0x0f, 0x00, 0xfb, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xf7, 0xff, 0x04, 0x00, 0xf4, 0xff, 0x05, 0x00, 0xf2, 0xff, 0x05, 0x00, 0xef, 0xff, 0x05, 0x00, 0xec, 0xff, 0x06, 0x00, 0xea, 0xff, 0x07, 0x00, 0xe8, 0xff, 0x08, 0x00, 0xe7, 0xff, 0x09, 0x00, 0xe6, 0xff, 0x09, 0x00, 0xe6, 0xff, 0x09, 0x00, 0xe5, 0xff, 0x09, 0x00, 0xe4, 0xff, 0x0a, 0x00, 0xe2, 0xff, 0x0c, 0x00, 0xe1, 0xff, 0x0f, 0x00, 0xe0, 0xff, 0x12, 0x00, 0xe0, 0xff, 0x14, 0x00, 0xe0, 0xff, 0x16, 0x00, 0xdf, 0xff, 0x17, 0x00, 0xde, 0xff, 0x17, 0x00, 0xdc, 0xff, 0x18, 0x00, 0xda, 0xff, 0x19, 0x00, 0xd9, 0xff, 0x1c, 0x00, 0xd9, 0xff, 0x1f, 0x00, 0xd9, 0xff, 0x22, 0x00, 0xdb, 0xff, 0x24, 0x00, 0xdd, 0xff, 0x24, 0x00, 0xdf, 0xff, 0x23, 0x00, 0xdf, 0xff, 0x22, 0x00, 0xdf, 0xff, 0x20, 0x00, 0xdf, 0xff, 0x20, 0x00, 0xdf, 0xff, 0x21, 0x00, 0xe1, 0xff, 0x22, 0x00, 0xe4, 0xff, 0x23, 0x00, 0xe8, 0xff, 0x23, 0x00, 0xed, 0xff, 0x22, 0x00, 0xf1, 0xff, 0x1e, 0x00, 0xf3, 0xff, 0x1a, 0x00, 0xf5, 0xff, 0x17, 0x00, 0xf7, 0xff, 0x15, 0x00, 0xfa, 0xff, 0x15, 0x00, 0xfe, 0xff, 0x16, 0x00, 0x04, 0x00, 0x19, 0x00, 0x0a, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x19, 0x00, 0x16, 0x00, 0x17, 0x00, 0x1a, 0x00, 0x14, 0x00, 0x1c, 0x00, 0x10, 0x00, 0x1f, 0x00, 0x0e, 0x00, 0x21, 0x00, 0x0c, 0x00, 0x25, 0x00, 0x0d, 0x00, 0x29, 0x00, 0x0d, 0x00, 0x2d, 0x00, 0x0f, 0x00, 0x32, 0x00, 0x10, 0x00, 0x35, 0x00, 0x0f, 0x00, 0x37, 0x00, 0x0e, 0x00, 0x38, 0x00, 0x0b, 0x00, 0x39, 0x00, 0x08, 0x00, 0x39, 0x00, 0x04, 0x00, 0x39, 0x00, 0x02, 0x00, 0x38, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, 0x02, 0x00, 0x32, 0x00, 0x03, 0x00, 0x2e, 0x00, 0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x22, 0x00, 0xfd, 0xff, 0x1d, 0x00, 0xf9, 0xff, 0x19, 0x00, 0xf6, 0xff, 0x15, 0x00, 0xf6, 0xff, 0x12, 0x00, 0xf6, 0xff, 0x0f, 0x00, 0xf8, 0xff, 0x0c, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf6, 0xff, 0xf7, 0xff, 0xf5, 0xff, 0xf8, 0xff, 0xf5, 0xff, 0xfa, 0xff, 0xf5, 0xff, 0xfc, 0xff, 0xf5, 0xff, 0xff, 0xff, 0xf5, 0xff, 0x02, 0x00, 0xf3, 0xff, 0x03, 0x00, 0xf1, 0xff, 0x03, 0x00, 0xef, 0xff, 0x02, 0x00, 0xee, 0xff, 0x00, 0x00, 0xed, 0xff, 0xfd, 0xff, 0xed, 0xff, 0xfc, 0xff, 0xed, 0xff, 0xfc, 0xff, 0xed, 0xff, 0xfe, 0xff, 0xec, 0xff, 0x00, 0x00, 0xec, 0xff, 0x03, 0x00, 0xeb, 0xff, 0x04, 0x00, 0xea, 0xff, 0x03, 0x00, 0xea, 0xff, 0x01, 0x00, 0xea, 0xff, 0x00, 0x00, 0xeb, 0xff, 0xff, 0xff, 0xec, 0xff, 0xff, 0xff, 0xee, 0xff, 0x01, 0x00, 0xef, 0xff, 0x04, 0x00, 0xef, 0xff, 0x06, 0x00, 0xf0, 0xff, 0x07, 0x00, 0xf1, 0xff, 0x07, 0x00, 0xf3, 0xff, 0x05, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x03, 0x00, 0x05, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x09, 0x00, 0x02, 0x00, 0x0b, 0x00, 0xff, 0xff, 0x0d, 0x00, 0xfa, 0xff, 0x0f, 0x00, 0xf7, 0xff, 0x11, 0x00, 0xf5, 0xff, 0x12, 0x00, 0xf4, 0xff, 0x15, 0x00, 0xf5, 0xff, 0x18, 0x00, 0xf6, 0xff, 0x1c, 0x00, 0xf7, 0xff, 0x1f, 0x00, 0xf8, 0xff, 0x21, 0x00, 0xf8, 0xff, 0x21, 0x00, 0xf8, 0xff, 0x1f, 0x00, 0xf7, 0xff, 0x1d, 0x00, 0xf5, 0xff, 0x1b, 0x00, 0xf4, 0xff, 0x1a, 0x00, 0xf2, 0xff, 0x19, 0x00, 0xf2, 0xff, 0x1a, 0x00, 0xf2, 0xff, 0x1b, 0x00, 0xf2, 0xff, 0x1b, 0x00, 0xf1, 0xff, 0x19, 0x00, 0xf0, 0xff, 0x16, 0x00, 0xef, 0xff, 0x13, 0x00, 0xef, 0xff, 0x11, 0x00, 0xef, 0xff, 0x10, 0x00, 0xf0, 0xff, 0x10, 0x00, 0xf1, 0xff, 0x0f, 0x00, 0xf3, 0xff, 0x0e, 0x00, 0xf4, 0xff, 0x0c, 0x00, 0xf6, 0xff, 0x09, 0x00, 0xf7, 0xff, 0x07, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x08, 0x00, 0xf6, 0xff, 0x08, 0x00, 0xf3, 0xff, 0x07, 0x00, 0xf0, 0xff, 0x05, 0x00, 0xed, 0xff, 0x04, 0x00, 0xeb, 0xff, 0x04, 0x00, 0xe8, 0xff, 0x04, 0x00, 0xe5, 0xff, 0x05, 0x00, 0xe1, 0xff, 0x06, 0x00, 0xde, 0xff, 0x07, 0x00, 0xdc, 0xff, 0x08, 0x00, 0xda, 0xff, 0x08, 0x00, 0xd9, 0xff, 0x07, 0x00, 0xd9, 0xff, 0x06, 0x00, 0xd8, 0xff, 0x04, 0x00, 0xd7, 0xff, 0x03, 0x00, 0xd6, 0xff, 0x03, 0x00, 0xd6, 0xff, 0x04, 0x00, 0xd6, 0xff, 0x05, 0x00, 0xd8, 0xff, 0x06, 0x00, 0xda, 0xff, 0x07, 0x00, 0xdd, 0xff, 0x08, 0x00, 0xe0, 0xff, 0x07, 0x00, 0xe4, 0xff, 0x05, 0x00, 0xe7, 0xff, 0x02, 0x00, 0xe9, 0xff, 0x00, 0x00, 0xec, 0xff, 0xff, 0xff, 0xee, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x01, 0x00, 0xf2, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xfb, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xff, 0xff, 0x07, 0x00, 0x01, 0x00, 0x08, 0x00, 0x03, 0x00, 0x09, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x14, 0x00, 0xfd, 0xff, 0x17, 0x00, 0xfb, 0xff, 0x18, 0x00, 0xf9, 0xff, 0x17, 0x00, 0xf8, 0xff, 0x17, 0x00, 0xf8, 0xff, 0x17, 0x00, 0xf9, 0xff, 0x18, 0x00, 0xfb, 0xff, 0x1b, 0x00, 0xfb, 0xff, 0x1f, 0x00, 0xfb, 0xff, 0x22, 0x00, 0xf9, 0xff, 0x24, 0x00, 0xf6, 0xff, 0x24, 0x00, 0xf4, 0xff, 0x23, 0x00, 0xf4, 0xff, 0x21, 0x00, 0xf4, 0xff, 0x1f, 0x00, 0xf6, 0xff, 0x1e, 0x00, 0xf8, 0xff, 0x1d, 0x00, 0xfb, 0xff, 0x1d, 0x00, 0xfd, 0xff, 0x1c, 0x00, 0xfe, 0xff, 0x1b, 0x00, 0xfd, 0xff, 0x18, 0x00, 0xfc, 0xff, 0x15, 0x00, 0xfc, 0xff, 0x12, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x0c, 0x00, 0x02, 0x00, 0x09, 0x00, 0x04, 0x00, 0x06, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf6, 0xff, 0x05, 0x00, 0xf4, 0xff, 0x06, 0x00, 0xf2, 0xff, 0x06, 0x00, 0xf2, 0xff, 0x05, 0x00, 0xf3, 0xff, 0x02, 0x00, 0xf4, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xfe, 0xff, 0xf4, 0xff, 0xfd, 0xff, 0xf2, 0xff, 0xfd, 0xff, 0xf0, 0xff, 0xfd, 0xff, 0xed, 0xff, 0xfc, 0xff, 0xec, 0xff, 0xfc, 0xff, 0xec, 0xff, 0xfa, 0xff, 0xed, 0xff, 0xf7, 0xff, 0xee, 0xff, 0xf4, 0xff, 0xef, 0xff, 0xf1, 0xff, 0xef, 0xff, 0xee, 0xff, 0xed, 0xff, 0xed, 0xff, 0xeb, 0xff, 0xec, 0xff, 0xe8, 0xff, 0xec, 0xff, 0xe6, 0xff, 0xec, 0xff, 0xe6, 0xff, 0xec, 0xff, 0xe7, 0xff, 0xec, 0xff, 0xe9, 0xff, 0xea, 0xff, 0xec, 0xff, 0xe8, 0xff, 0xed, 0xff, 0xe6, 0xff, 0xee, 0xff, 0xe5, 0xff, 0xee, 0xff, 0xe5, 0xff, 0xef, 0xff, 0xe7, 0xff, 0xf0, 0xff, 0xe8, 0xff, 0xf2, 0xff, 0xe9, 0xff, 0xf4, 0xff, 0xea, 0xff, 0xf8, 0xff, 0xe9, 0xff, 0xfc, 0xff, 0xe8, 0xff, 0x00, 0x00, 0xe6, 0xff, 0x03, 0x00, 0xe5, 0xff, 0x05, 0x00, 0xe4, 0xff, 0x05, 0x00, 0xe5, 0xff, 0x05, 0x00, 0xe7, 0xff, 0x04, 0x00, 0xea, 0xff, 0x04, 0x00, 0xec, 0xff, 0x04, 0x00, 0xee, 0xff, 0x04, 0x00, 0xef, 0xff, 0x05, 0x00, 0xf0, 0xff, 0x05, 0x00, 0xf2, 0xff, 0x04, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xf8, 0xff, 0x09, 0x00, 0xf8, 0xff, 0x0d, 0x00, 0xf9, 0xff, 0x10, 0x00, 0xfa, 0xff, 0x14, 0x00, 0xfb, 0xff, 0x17, 0x00, 0xfa, 0xff, 0x1b, 0x00, 0xf8, 0xff, 0x20, 0x00, 0xf6, 0xff, 0x25, 0x00, 0xf5, 0xff, 0x29, 0x00, 0xf6, 0xff, 0x2b, 0x00, 0xf8, 0xff, 0x2d, 0x00, 0xfa, 0xff, 0x2e, 0x00, 0xfc, 0xff, 0x2e, 0x00, 0xfc, 0xff, 0x2f, 0x00, 0xfc, 0xff, 0x31, 0x00, 0xf9, 0xff, 0x33, 0x00, 0xf7, 0xff, 0x36, 0x00, 0xf4, 0xff, 0x38, 0x00, 0xf3, 0xff, 0x39, 0x00, 0xf3, 0xff, 0x39, 0x00, 0xf4, 0xff, 0x37, 0x00, 0xf4, 0xff, 0x33, 0x00, 0xf5, 0xff, 0x30, 0x00, 0xf4, 0xff, 0x2d, 0x00, 0xf2, 0xff, 0x2b, 0x00, 0xf0, 0xff, 0x2b, 0x00, 0xef, 0xff, 0x2b, 0x00, 0xee, 0xff, 0x2c, 0x00, 0xee, 0xff, 0x2b, 0x00, 0xef, 0xff, 0x29, 0x00, 0xf0, 0xff, 0x25, 0x00, 0xf1, 0xff, 0x22, 0x00, 0xf3, 0xff, 0x1e, 0x00, 0xf3, 0xff, 0x1c, 0x00, 0xf4, 0xff, 0x1b, 0x00, 0xf5, 0xff, 0x1b, 0x00, 0xf5, 0xff, 0x1c, 0x00, 0xf6, 0xff, 0x1c, 0x00, 0xf7, 0xff, 0x1b, 0x00, 0xf9, 0xff, 0x18, 0x00, 0xfc, 0xff, 0x14, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x09, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x02, 0x00, 0x0a, 0x00, 0xfe, 0xff, 0x0e, 0x00, 0xfb, 0xff, 0x11, 0x00, 0xf8, 0xff, 0x12, 0x00, 0xf7, 0xff, 0x11, 0x00, 0xf6, 0xff, 0x0e, 0x00, 0xf5, 0xff, 0x0a, 0x00, 0xf5, 0xff, 0x07, 0x00, 0xf4, 0xff, 0x06, 0x00, 0xf3, 0xff, 0x07, 0x00, 0xf1, 0xff, 0x0a, 0x00, 0xef, 0xff, 0x0d, 0x00, 0xed, 0xff, 0x0f, 0x00, 0xeb, 0xff, 0x10, 0x00, 0xeb, 0xff, 0x0f, 0x00, 0xea, 0xff, 0x0d, 0x00, 0xea, 0xff, 0x0c, 0x00, 0xea, 0xff, 0x0c, 0x00, 0xeb, 0xff, 0x0d, 0x00, 0xeb, 0xff, 0x10, 0x00, 0xed, 0xff, 0x14, 0x00, 0xee, 0xff, 0x18, 0x00, 0xf0, 0xff, 0x1a, 0x00, 0xf1, 0xff, 0x1c, 0x00, 0xf2, 0xff, 0x1b, 0x00, 0xf4, 0xff, 0x18, 0x00, 0xf6, 0xff, 0x15, 0x00, 0xf8, 0xff, 0x14, 0x00, 0xf9, 0xff, 0x14, 0x00, 0xf9, 0xff, 0x15, 0x00, 0xf9, 0xff, 0x17, 0x00, 0xf9, 0xff, 0x18, 0x00, 0xf9, 0xff, 0x18, 0x00, 0xfa, 0xff, 0x16, 0x00, 0xfc, 0xff, 0x12, 0x00, 0xfe, 0xff, 0x0d, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0xff, 0xff, 0x09, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfb, 0xff, 0x0e, 0x00, 0xfb, 0xff, 0x0d, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfe, 0xff, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xf7, 0xff, 0x05, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf6, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xf7, 0xff, 0xf1, 0xff, 0xf5, 0xff, 0xef, 0xff, 0xf5, 0xff, 0xec, 0xff, 0xf4, 0xff, 0xe9, 0xff, 0xf4, 0xff, 0xe6, 0xff, 0xf3, 0xff, 0xe3, 0xff, 0xf0, 0xff, 0xe1, 0xff, 0xee, 0xff, 0xe0, 0xff, 0xeb, 0xff, 0xdf, 0xff, 0xe9, 0xff, 0xdf, 0xff, 0xe8, 0xff, 0xde, 0xff, 0xe7, 0xff, 0xdd, 0xff, 0xe7, 0xff, 0xdb, 0xff, 0xe7, 0xff, 0xd7, 0xff, 0xe7, 0xff, 0xd3, 0xff, 0xe7, 0xff, 0xd0, 0xff, 0xe6, 0xff, 0xce, 0xff, 0xe5, 0xff, 0xce, 0xff, 0xe4, 0xff, 0xd0, 0xff, 0xe3, 0xff, 0xd2, 0xff, 0xe4, 0xff, 0xd2, 0xff, 0xe5, 0xff, 0xd0, 0xff, 0xe8, 0xff, 0xcd, 0xff, 0xeb, 0xff, 0xcb, 0xff, 0xee, 0xff, 0xca, 0xff, 0xf0, 0xff, 0xcc, 0xff, 0xf1, 0xff, 0xd1, 0xff, 0xf2, 0xff, 0xd7, 0xff, 0xf3, 0xff, 0xdc, 0xff, 0xf5, 0xff, 0xdf, 0xff, 0xf8, 0xff, 0xe0, 0xff, 0xfc, 0xff, 0xe0, 0xff, 0x01, 0x00, 0xe2, 0xff, 0x05, 0x00, 0xe5, 0xff, 0x08, 0x00, 0xe9, 0xff, 0x0a, 0x00, 0xef, 0xff, 0x0a, 0x00, 0xf4, 0xff, 0x09, 0x00, 0xf8, 0xff, 0x09, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xff, 0xff, 0x0d, 0x00, 0x02, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x11, 0x00, 0x0a, 0x00, 0x12, 0x00, 0x0e, 0x00, 0x11, 0x00, 0x12, 0x00, 0x0f, 0x00, 0x15, 0x00, 0x0c, 0x00, 0x17, 0x00, 0x0a, 0x00, 0x18, 0x00, 0x09, 0x00, 0x18, 0x00, 0x0a, 0x00, 0x19, 0x00, 0x0c, 0x00, 0x1a, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x0f, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x1f, 0x00, 0x0c, 0x00, 0x21, 0x00, 0x09, 0x00, 0x21, 0x00, 0x07, 0x00, 0x21, 0x00, 0x05, 0x00, 0x20, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x07, 0x00, 0x1c, 0x00, 0x09, 0x00, 0x19, 0x00, 0x0c, 0x00, 0x17, 0x00, 0x0e, 0x00, 0x15, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x07, 0x00, 0x15, 0x00, 0x04, 0x00, 0x15, 0x00, 0x01, 0x00, 0x14, 0x00, 0x01, 0x00, 0x12, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x09, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x09, 0x00, 0xf8, 0xff, 0x0a, 0x00, 0xf9, 0xff, 0x09, 0x00, 0xf9, 0xff, 0x07, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf4, 0xff, 0x02, 0x00, 0xef, 0xff, 0x02, 0x00, 0xec, 0xff, 0x04, 0x00, 0xea, 0xff, 0x07, 0x00, 0xeb, 0xff, 0x0a, 0x00, 0xed, 0xff, 0x0d, 0x00, 0xf1, 0xff, 0x0d, 0x00, 0xf4, 0xff, 0x0c, 0x00, 0xf5, 0xff, 0x0a, 0x00, 0xf5, 0xff, 0x08, 0x00, 0xf3, 0xff, 0x06, 0x00, 0xf2, 0xff, 0x06, 0x00, 0xf2, 0xff, 0x07, 0x00, 0xf3, 0xff, 0x08, 0x00, 0xf5, 0xff, 0x09, 0x00, 0xf8, 0xff, 0x09, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x02, 0x00, 0x09, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x11, 0x00, 0x06, 0x00, 0x13, 0x00, 0x05, 0x00, 0x15, 0x00, 0x06, 0x00, 0x16, 0x00, 0x07, 0x00, 0x17, 0x00, 0x09, 0x00, 0x19, 0x00, 0x0c, 0x00, 0x1c, 0x00, 0x10, 0x00, 0x20, 0x00, 0x12, 0x00, 0x25, 0x00, 0x14, 0x00, 0x2a, 0x00, 0x14, 0x00, 0x2d, 0x00, 0x13, 0x00, 0x30, 0x00, 0x12, 0x00, 0x31, 0x00, 0x11, 0x00, 0x31, 0x00, 0x10, 0x00, 0x31, 0x00, 0x11, 0x00, 0x32, 0x00, 0x12, 0x00, 0x35, 0x00, 0x12, 0x00, 0x38, 0x00, 0x11, 0x00, 0x3a, 0x00, 0x0f, 0x00, 0x3c, 0x00, 0x0c, 0x00, 0x3c, 0x00, 0x09, 0x00, 0x3b, 0x00, 0x07, 0x00, 0x39, 0x00, 0x05, 0x00, 0x36, 0x00, 0x03, 0x00, 0x33, 0x00, 0x02, 0x00, 0x2f, 0x00, 0x02, 0x00, 0x2c, 0x00, 0x01, 0x00, 0x28, 0x00, 0xff, 0xff, 0x25, 0x00, 0xfc, 0xff, 0x21, 0x00, 0xfa, 0xff, 0x1d, 0x00, 0xf8, 0xff, 0x19, 0x00, 0xf7, 0xff, 0x15, 0x00, 0xf7, 0xff, 0x12, 0x00, 0xf8, 0xff, 0x0e, 0x00, 0xf8, 0xff, 0x0a, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xf5, 0xff, 0xf9, 0xff, 0xf2, 0xff, 0xf9, 0xff, 0xef, 0xff, 0xfa, 0xff, 0xec, 0xff, 0xfa, 0xff, 0xeb, 0xff, 0xfa, 0xff, 0xe9, 0xff, 0xf9, 0xff, 0xe7, 0xff, 0xf8, 0xff, 0xe5, 0xff, 0xf5, 0xff, 0xe2, 0xff, 0xf3, 0xff, 0xe0, 0xff, 0xf1, 0xff, 0xde, 0xff, 0xf0, 0xff, 0xdc, 0xff, 0xf0, 0xff, 0xda, 0xff, 0xf0, 0xff, 0xd9, 0xff, 0xf1, 0xff, 0xd8, 0xff, 0xf1, 0xff, 0xd7, 0xff, 0xf1, 0xff, 0xd6, 0xff, 0xf0, 0xff, 0xd5, 0xff, 0xef, 0xff, 0xd4, 0xff, 0xee, 0xff, 0xd4, 0xff, 0xed, 0xff, 0xd3, 0xff, 0xee, 0xff, 0xd3, 0xff, 0xf0, 0xff, 0xd4, 0xff, 0xf3, 0xff, 0xd6, 0xff, 0xf5, 0xff, 0xd9, 0xff, 0xf6, 0xff, 0xdc, 0xff, 0xf6, 0xff, 0xdf, 0xff, 0xf5, 0xff, 0xe1, 0xff, 0xf4, 0xff, 0xe2, 0xff, 0xf2, 0xff, 0xe3, 0xff, 0xf0, 0xff, 0xe6, 0xff, 0xf0, 0xff, 0xe9, 0xff, 0xf0, 0xff, 0xed, 0xff, 0xf2, 0xff, 0xf3, 0xff, 0xf4, 0xff, 0xf8, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0x02, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf3, 0xff, 0x05, 0x00, 0xf1, 0xff, 0x06, 0x00, 0xf1, 0xff, 0x07, 0x00, 0xf2, 0xff, 0x0a, 0x00, 0xf3, 0xff, 0x0e, 0x00, 0xf6, 0xff, 0x11, 0x00, 0xf9, 0xff, 0x15, 0x00, 0xfc, 0xff, 0x16, 0x00, 0xfe, 0xff, 0x16, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x10, 0x00, 0xff, 0xff, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x15, 0x00, 0x05, 0x00, 0x18, 0x00, 0x06, 0x00, 0x18, 0x00, 0x07, 0x00, 0x17, 0x00, 0x07, 0x00, 0x15, 0x00, 0x05, 0x00, 0x12, 0x00, 0x03, 0x00, 0x10, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0xff, 0xff, 0x12, 0x00, 0xff, 0xff, 0x14, 0x00, 0xff, 0xff, 0x16, 0x00, 0xfe, 0xff, 0x17, 0x00, 0xfc, 0xff, 0x17, 0x00, 0xfa, 0xff, 0x16, 0x00, 0xf7, 0xff, 0x13, 0x00, 0xf4, 0xff, 0x10, 0x00, 0xf2, 0xff, 0x0e, 0x00, 0xf1, 0xff, 0x0c, 0x00, 0xf2, 0xff, 0x0c, 0x00, 0xf2, 0xff, 0x0b, 0x00, 0xf3, 0xff, 0x0a, 0x00, 0xf4, 0xff, 0x08, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf5, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xf9, 0xff, 0xf8, 0xff, 0xf4, 0xff, 0xfa, 0xff, 0xf0, 0xff, 0xfc, 0xff, 0xee, 0xff, 0xfe, 0xff, 0xed, 0xff, 0x00, 0x00, 0xec, 0xff, 0x03, 0x00, 0xea, 0xff, 0x05, 0x00, 0xe7, 0xff, 0x08, 0x00, 0xe4, 0xff, 0x0a, 0x00, 0xe1, 0xff, 0x0c, 0x00, 0xde, 0xff, 0x0d, 0x00, 0xde, 0xff, 0x0e, 0x00, 0xdf, 0xff, 0x0f, 0x00, 0xe1, 0xff, 0x11, 0x00, 0xe3, 0xff, 0x13, 0x00, 0xe4, 0xff, 0x15, 0x00, 0xe4, 0xff, 0x16, 0x00, 0xe4, 0xff, 0x15, 0x00, 0xe3, 0xff, 0x13, 0x00, 0xe4, 0xff, 0x11, 0x00, 0xe6, 0xff, 0x10, 0x00, 0xe8, 0xff, 0x0f, 0x00, 0xec, 0xff, 0x0f, 0x00, 0xef, 0xff, 0x10, 0x00, 0xf2, 0xff, 0x10, 0x00, 0xf4, 0xff, 0x0f, 0x00, 0xf5, 0xff, 0x0d, 0x00, 0xf5, 0xff, 0x09, 0x00, 0xf7, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x07, 0x00, 0x01, 0x00, 0x09, 0x00, 0xff, 0xff, 0x0b, 0x00, 0xfe, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0d, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x11, 0x00, 0xfc, 0xff, 0x14, 0x00, 0xfd, 0xff, 0x17, 0x00, 0xfd, 0xff, 0x19, 0x00, 0xfd, 0xff, 0x1b, 0x00, 0xfd, 0xff, 0x1b, 0x00, 0xfd, 0xff, 0x1b, 0x00, 0xfd, 0xff, 0x1b, 0x00, 0xfd, 0xff, 0x1c, 0x00, 0xfd, 0xff, 0x1e, 0x00, 0xfd, 0xff, 0x20, 0x00, 0xfc, 0xff, 0x22, 0x00, 0xfc, 0xff, 0x23, 0x00, 0xfb, 0xff, 0x22, 0x00, 0xfb, 0xff, 0x20, 0x00, 0xfa, 0xff, 0x1d, 0x00, 0xfa, 0xff, 0x19, 0x00, 0xfa, 0xff, 0x15, 0x00, 0xfa, 0xff, 0x13, 0x00, 0xfb, 0xff, 0x11, 0x00, 0xfd, 0xff, 0x10, 0x00, 0xfe, 0xff, 0x0e, 0x00, 0xff, 0xff, 0x0b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf6, 0xff, 0x02, 0x00, 0xf5, 0xff, 0x05, 0x00, 0xf4, 0xff, 0x07, 0x00, 0xf2, 0xff, 0x08, 0x00, 0xf0, 0xff, 0x08, 0x00, 0xed, 0xff, 0x08, 0x00, 0xeb, 0xff, 0x07, 0x00, 0xea, 0xff, 0x06, 0x00, 0xe9, 0xff, 0x07, 0x00, 0xe9, 0xff, 0x07, 0x00, 0xea, 0xff, 0x08, 0x00, 0xea, 0xff, 0x08, 0x00, 0xea, 0xff, 0x08, 0x00, 0xe9, 0xff, 0x07, 0x00, 0xe8, 0xff, 0x06, 0x00, 0xe6, 0xff, 0x05, 0x00, 0xe5, 0xff, 0x03, 0x00, 0xe4, 0xff, 0x01, 0x00, 0xe5, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xfd, 0xff, 0xe8, 0xff, 0xfc, 0xff, 0xea, 0xff, 0xfb, 0xff, 0xeb, 0xff, 0xfa, 0xff, 0xeb, 0xff, 0xfa, 0xff, 0xeb, 0xff, 0xf9, 0xff, 0xeb, 0xff, 0xf8, 0xff, 0xeb, 0xff, 0xf7, 0xff, 0xec, 0xff, 0xf5, 0xff, 0xee, 0xff, 0xf3, 0xff, 0xf0, 0xff, 0xf3, 0xff, 0xf2, 0xff, 0xf4, 0xff, 0xf3, 0xff, 0xf6, 0xff, 0xf4, 0xff, 0xf8, 0xff, 0xf5, 0xff, 0xf9, 0xff, 0xf5, 0xff, 0xf8, 0xff, 0xf6, 0xff, 0xf7, 0xff, 0xf8, 0xff, 0xf5, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xf4, 0xff, 0x01, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x08, 0x00, 0xf7, 0xff, 0x0b, 0x00, 0xf5, 0xff, 0x0d, 0x00, 0xf2, 0xff, 0x10, 0x00, 0xf1, 0xff, 0x13, 0x00, 0xf0, 0xff, 0x15, 0x00, 0xf0, 0xff, 0x18, 0x00, 0xf1, 0xff, 0x1a, 0x00, 0xf2, 0xff, 0x1b, 0x00, 0xf2, 0xff, 0x1b, 0x00, 0xf3, 0xff, 0x1a, 0x00, 0xf3, 0xff, 0x1a, 0x00, 0xf3, 0xff, 0x19, 0x00, 0xf3, 0xff, 0x18, 0x00, 0xf4, 0xff, 0x18, 0x00, 0xf5, 0xff, 0x18, 0x00, 0xf6, 0xff, 0x17, 0x00, 0xf8, 0xff, 0x17, 0x00, 0xfa, 0xff, 0x15, 0x00, 0xfc, 0xff, 0x13, 0x00, 0xfe, 0xff, 0x10, 0x00, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x09, 0x00, 0x06, 0x00, 0x08, 0x00, 0x07, 0x00, 0x05, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x07, 0x00, 0xfa, 0xff, 0x09, 0x00, 0xfb, 0xff, 0x0a, 0x00, 0xfa, 0xff, 0x0c, 0x00, 0xf7, 0xff, 0x0c, 0x00, 0xf4, 0xff, 0x0c, 0x00, 0xf0, 0xff, 0x0c, 0x00, 0xee, 0xff, 0x0c, 0x00, 0xec, 0xff, 0x0c, 0x00, 0xec, 0xff, 0x0d, 0x00, 0xee, 0xff, 0x0f, 0x00, 0xef, 0xff, 0x10, 0x00, 0xf0, 0xff, 0x11, 0x00, 0xef, 0xff, 0x11, 0x00, 0xee, 0xff, 0x11, 0x00, 0xec, 0xff, 0x10, 0x00, 0xeb, 0xff, 0x10, 0x00, 0xec, 0xff, 0x11, 0x00, 0xee, 0xff, 0x11, 0x00, 0xf0, 0xff, 0x11, 0x00, 0xf3, 0xff, 0x11, 0x00, 0xf5, 0xff, 0x10, 0x00, 0xf6, 0xff, 0x0f, 0x00, 0xf7, 0xff, 0x0e, 0x00, 0xf8, 0xff, 0x0d, 0x00, 0xfa, 0xff, 0x0c, 0x00, 0xfb, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfe, 0xff, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x09, 0x00, 0x03, 0x00, 0x07, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x0b, 0x00, 0xfa, 0xff, 0x0b, 0x00, 0xf7, 0xff, 0x0c, 0x00, 0xf6, 0xff, 0x0d, 0x00, 0xf5, 0xff, 0x0e, 0x00, 0xf5, 0xff, 0x10, 0x00, 0xf5, 0xff, 0x11, 0x00, 0xf4, 0xff, 0x12, 0x00, 0xf3, 0xff, 0x13, 0x00, 0xf2, 0xff, 0x14, 0x00, 0xf1, 0xff, 0x14, 0x00, 0xef, 0xff, 0x14, 0x00, 0xee, 0xff, 0x14, 0x00, 0xed, 0xff, 0x15, 0x00, 0xee, 0xff, 0x15, 0x00, 0xef, 0xff, 0x15, 0x00, 0xf0, 0xff, 0x14, 0x00, 0xf1, 0xff, 0x13, 0x00, 0xf1, 0xff, 0x11, 0x00, 0xf2, 0xff, 0x0f, 0x00, 0xf2, 0xff, 0x0c, 0x00, 0xf3, 0xff, 0x09, 0x00, 0xf3, 0xff, 0x06, 0x00, 0xf4, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x00, 0x00, 0xf7, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf4, 0xff, 0xff, 0xff, 0xef, 0xff, 0x02, 0x00, 0xeb, 0xff, 0x03, 0x00, 0xe6, 0xff, 0x04, 0x00, 0xe2, 0xff, 0x04, 0x00, 0xdf, 0xff, 0x04, 0x00, 0xdc, 0xff, 0x05, 0x00, 0xda, 0xff, 0x06, 0x00, 0xd9, 0xff, 0x07, 0x00, 0xd8, 0xff, 0x0a, 0x00, 0xd7, 0xff, 0x0c, 0x00, 0xd6, 0xff, 0x0d, 0x00, 0xd5, 0xff, 0x0e, 0x00, 0xd5, 0xff, 0x0f, 0x00, 0xd6, 0xff, 0x0f, 0x00, 0xd7, 0xff, 0x0f, 0x00, 0xd9, 0xff, 0x10, 0x00, 0xdc, 0xff, 0x10, 0x00, 0xde, 0xff, 0x11, 0x00, 0xe1, 0xff, 0x12, 0x00, 0xe3, 0xff, 0x13, 0x00, 0xe4, 0xff, 0x14, 0x00, 0xe5, 0xff, 0x15, 0x00, 0xe7, 0xff, 0x15, 0x00, 0xe9, 0xff, 0x15, 0x00, 0xeb, 0xff, 0x15, 0x00, 0xee, 0xff, 0x14, 0x00, 0xf1, 0xff, 0x13, 0x00, 0xf3, 0xff, 0x12, 0x00, 0xf5, 0xff, 0x12, 0x00, 0xf6, 0xff, 0x13, 0x00, 0xf8, 0xff, 0x14, 0x00, 0xf9, 0xff, 0x14, 0x00, 0xfa, 0xff, 0x13, 0x00, 0xfb, 0xff, 0x11, 0x00, 0xfc, 0xff, 0x0e, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfe, 0xff, 0x0a, 0x00, 0xff, 0xff, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x03, 0x00, 0x06, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf7, 0xff, 0x07, 0x00, 0xf6, 0xff, 0x09, 0x00, 0xf5, 0xff, 0x0b, 0x00, 0xf5, 0xff, 0x0e, 0x00, 0xf3, 0xff, 0x10, 0x00, 0xf2, 0xff, 0x12, 0x00, 0xf1, 0xff, 0x14, 0x00, 0xf0, 0xff, 0x15, 0x00, 0xef, 0xff, 0x16, 0x00, 0xee, 0xff, 0x16, 0x00, 0xee, 0xff, 0x17, 0x00, 0xed, 0xff, 0x18, 0x00, 0xec, 0xff, 0x19, 0x00, 0xea, 0xff, 0x1a, 0x00, 0xe9, 0xff, 0x19, 0x00, 0xe9, 0xff, 0x18, 0x00, 0xea, 0xff, 0x16, 0x00, 0xeb, 0xff, 0x14, 0x00, 0xed, 0xff, 0x11, 0x00, 0xee, 0xff, 0x0f, 0x00, 0xef, 0xff, 0x0e, 0x00, 0xf0, 0xff, 0x0c, 0x00, 0xf0, 0xff, 0x0a, 0x00, 0xf0, 0xff, 0x09, 0x00, 0xf1, 0xff, 0x07, 0x00, 0xf3, 0xff, 0x05, 0x00, 0xf5, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xfb, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfa, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf7, 0xff, 0x03, 0x00, 0xf7, 0xff, 0x05, 0x00, 0xf8, 0xff, 0x08, 0x00, 0xf8, 0xff, 0x0b, 0x00, 0xf9, 0xff, 0x0e, 0x00, 0xf9, 0xff, 0x10, 0x00, 0xf9, 0xff, 0x12, 0x00, 0xfa, 0xff, 0x12, 0x00, 0xfb, 0xff, 0x12, 0x00, 0xfc, 0xff, 0x12, 0x00, 0xfe, 0xff, 0x12, 0x00, 0xff, 0xff, 0x14, 0x00, 0x00, 0x00, 0x16, 0x00, 0x01, 0x00, 0x19, 0x00, 0x03, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x06, 0x00, 0x1c, 0x00, 0x07, 0x00, 0x1a, 0x00, 0x08, 0x00, 0x17, 0x00, 0x09, 0x00, 0x14, 0x00, 0x0a, 0x00, 0x13, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x0a, 0x00, 0x12, 0x00, 0x09, 0x00, 0x0f, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x08, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x0b, 0x00, 0xff, 0xff, 0x0c, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xfd, 0xff, 0x12, 0x00, 0xfc, 0xff, 0x14, 0x00, 0xfa, 0xff, 0x15, 0x00, 0xf9, 0xff, 0x15, 0x00, 0xf9, 0xff, 0x14, 0x00, 0xf9, 0xff, 0x13, 0x00, 0xf9, 0xff, 0x14, 0x00, 0xf9, 0xff, 0x15, 0x00, 0xf9, 0xff, 0x17, 0x00, 0xf9, 0xff, 0x1a, 0x00, 0xf9, 0xff, 0x1b, 0x00, 0xf9, 0xff, 0x1c, 0x00, 0xf9, 0xff, 0x1c, 0x00, 0xf9, 0xff, 0x1c, 0x00, 0xfa, 0xff, 0x1a, 0x00, 0xfb, 0xff, 0x1a, 0x00, 0xfc, 0xff, 0x1a, 0x00, 0xfd, 0xff, 0x1a, 0x00, 0xfd, 0xff, 0x1b, 0x00, 0xfc, 0xff, 0x1b, 0x00, 0xfb, 0xff, 0x1a, 0x00, 0xf9, 0xff, 0x19, 0x00, 0xf7, 0xff, 0x17, 0x00, 0xf5, 0xff, 0x15, 0x00, 0xf4, 0xff, 0x13, 0x00, 0xf3, 0xff, 0x12, 0x00, 0xf3, 0xff, 0x10, 0x00, 0xf3, 0xff, 0x0e, 0x00, 0xf3, 0xff, 0x0d, 0x00, 0xf3, 0xff, 0x0b, 0x00, 0xf2, 0xff, 0x09, 0x00, 0xf1, 0xff, 0x07, 0x00, 0xf0, 0xff, 0x05, 0x00, 0xf0, 0xff, 0x03, 0x00, 0xef, 0xff, 0x02, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xf1, 0xff, 0x00, 0x00, 0xf2, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xfe, 0xff, 0xf3, 0xff, 0xfe, 0xff, 0xf4, 0xff, 0xfd, 0xff, 0xf4, 0xff, 0xfc, 0xff, 0xf5, 0xff, 0xfb, 0xff, 0xf6, 0xff, 0xfb, 0xff, 0xf7, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf5, 0xff, 0xff, 0xff, 0xf4, 0xff, 0x00, 0x00, 0xf3, 0xff, 0x00, 0x00, 0xf3, 0xff, 0x00, 0x00, 0xf3, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf2, 0xff, 0xfc, 0xff, 0xf0, 0xff, 0xfc, 0xff, 0xef, 0xff, 0xfd, 0xff, 0xed, 0xff, 0xfd, 0xff, 0xed, 0xff, 0xfc, 0xff, 0xec, 0xff, 0xf9, 0xff, 0xec, 0xff, 0xf6, 0xff, 0xed, 0xff, 0xf4, 0xff, 0xed, 0xff, 0xf3, 0xff, 0xed, 0xff, 0xf3, 0xff, 0xed, 0xff, 0xf4, 0xff, 0xed, 0xff, 0xf5, 0xff, 0xec, 0xff, 0xf6, 0xff, 0xeb, 0xff, 0xf6, 0xff, 0xeb, 0xff, 0xf4, 0xff, 0xec, 0xff, 0xf2, 0xff, 0xed, 0xff, 0xf0, 0xff, 0xee, 0xff, 0xf0, 0xff, 0xef, 0xff, 0xf0, 0xff, 0xef, 0xff, 0xf3, 0xff, 0xee, 0xff, 0xf5, 0xff, 0xed, 0xff, 0xf7, 0xff, 0xeb, 0xff, 0xf8, 0xff, 0xea, 0xff, 0xf7, 0xff, 0xea, 0xff, 0xf5, 0xff, 0xeb, 0xff, 0xf3, 0xff, 0xec, 0xff, 0xf1, 0xff, 0xed, 0xff, 0xf1, 0xff, 0xee, 0xff, 0xf2, 0xff, 0xef, 0xff, 0xf4, 0xff, 0xee, 0xff, 0xf7, 0xff, 0xec, 0xff, 0xf8, 0xff, 0xeb, 0xff, 0xf9, 0xff, 0xea, 0xff, 0xf8, 0xff, 0xea, 0xff, 0xf7, 0xff, 0xec, 0xff, 0xf7, 0xff, 0xee, 0xff, 0xf7, 0xff, 0xf1, 0xff, 0xf8, 0xff, 0xf4, 0xff, 0xf9, 0xff, 0xf7, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0x11, 0x00, 0x10, 0x00, 0x12, 0x00, 0x13, 0x00, 0x12, 0x00, 0x16, 0x00, 0x11, 0x00, 0x18, 0x00, 0x0f, 0x00, 0x1a, 0x00, 0x0c, 0x00, 0x1b, 0x00, 0x09, 0x00, 0x1b, 0x00, 0x07, 0x00, 0x1a, 0x00, 0x06, 0x00, 0x19, 0x00, 0x07, 0x00, 0x18, 0x00, 0x07, 0x00, 0x17, 0x00, 0x07, 0x00, 0x17, 0x00, 0x06, 0x00, 0x17, 0x00, 0x04, 0x00, 0x17, 0x00, 0x01, 0x00, 0x17, 0x00, 0xfe, 0xff, 0x17, 0x00, 0xfd, 0xff, 0x16, 0x00, 0xfd, 0xff, 0x15, 0x00, 0xfd, 0xff, 0x14, 0x00, 0xfe, 0xff, 0x12, 0x00, 0xff, 0xff, 0x11, 0x00, 0xff, 0xff, 0x0f, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0xfb, 0xff, 0x0f, 0x00, 0xfb, 0xff, 0x10, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0e, 0x00, 0xfd, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf5, 0xff, 0xfb, 0xff, 0xf4, 0xff, 0xfb, 0xff, 0xf5, 0xff, 0xfb, 0xff, 0xf7, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf5, 0xff, 0xfc, 0xff, 0xf4, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfd, 0xff, 0xf4, 0xff, 0xfd, 0xff, 0xf6, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x05, 0x00, 0x03, 0x00, 0x07, 0x00, 0x05, 0x00, 0x08, 0x00, 0x07, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x0d, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x07, 0x00, 0x10, 0x00, 0x07, 0x00, 0x12, 0x00, 0x07, 0x00, 0x14, 0x00, 0x07, 0x00, 0x15, 0x00, 0x07, 0x00, 0x16, 0x00, 0x05, 0x00, 0x16, 0x00, 0x03, 0x00, 0x16, 0x00, 0x01, 0x00, 0x16, 0x00, 0xff, 0xff, 0x16, 0x00, 0xfe, 0xff, 0x16, 0x00, 0xfe, 0xff, 0x16, 0x00, 0xff, 0xff, 0x16, 0x00, 0xff, 0xff, 0x15, 0x00, 0xff, 0xff, 0x13, 0x00, 0xfd, 0xff, 0x10, 0x00, 0xfb, 0xff, 0x0c, 0x00, 0xf9, 0xff, 0x09, 0x00, 0xf7, 0xff, 0x06, 0x00, 0xf7, 0xff, 0x03, 0x00, 0xf7, 0xff, 0x02, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0xfe, 0xff, 0xf5, 0xff, 0xfc, 0xff, 0xf4, 0xff, 0xf9, 0xff, 0xf2, 0xff, 0xf6, 0xff, 0xf1, 0xff, 0xf4, 0xff, 0xf0, 0xff, 0xf3, 0xff, 0xf1, 0xff, 0xf2, 0xff, 0xf3, 0xff, 0xf1, 0xff, 0xf4, 0xff, 0xf0, 0xff, 0xf4, 0xff, 0xef, 0xff, 0xf3, 0xff, 0xed, 0xff, 0xf2, 0xff, 0xeb, 0xff, 0xf1, 0xff, 0xe9, 0xff, 0xf2, 0xff, 0xe8, 0xff, 0xf4, 0xff, 0xe8, 0xff, 0xf7, 0xff, 0xe8, 0xff, 0xfa, 0xff, 0xe8, 0xff, 0xfc, 0xff, 0xe8, 0xff, 0xfc, 0xff, 0xe8, 0xff, 0xfc, 0xff, 0xe7, 0xff, 0xfc, 0xff, 0xe7, 0xff, 0xfc, 0xff, 0xe8, 0xff, 0xfe, 0xff, 0xe8, 0xff, 0x01, 0x00, 0xea, 0xff, 0x03, 0x00, 0xec, 0xff, 0x05, 0x00, 0xef, 0xff, 0x06, 0x00, 0xf1, 0xff, 0x05, 0x00, 0xf3, 0xff, 0x05, 0x00, 0xf5, 0xff, 0x05, 0x00, 0xf6, 0xff, 0x05, 0x00, 0xf6, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x09, 0x00, 0xf9, 0xff, 0x0b, 0x00, 0xfa, 0xff, 0x0d, 0x00, 0xfc, 0xff, 0x0d, 0x00, 0xfe, 0xff, 0x0c, 0x00, 0xff, 0xff, 0x0b, 0x00, 0xff, 0xff, 0x0b, 0x00, 0xfe, 0xff, 0x0d, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0xfd, 0xff, 0x12, 0x00, 0xfd, 0xff, 0x14, 0x00, 0xfe, 0xff, 0x15, 0x00, 0x00, 0x00, 0x15, 0x00, 0x01, 0x00, 0x15, 0x00, 0x02, 0x00, 0x15, 0x00, 0x03, 0x00, 0x15, 0x00, 0x03, 0x00, 0x15, 0x00, 0x04, 0x00, 0x15, 0x00, 0x06, 0x00, 0x16, 0x00, 0x08, 0x00, 0x17, 0x00, 0x0a, 0x00, 0x18, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x10, 0x00, 0x17, 0x00, 0x10, 0x00, 0x16, 0x00, 0x10, 0x00, 0x14, 0x00, 0x0f, 0x00, 0x12, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x05, 0x00, 0x10, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x0e, 0x00, 0xff, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xf7, 0xff, 0x05, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf4, 0xff, 0x03, 0x00, 0xf3, 0xff, 0x01, 0x00, 0xf2, 0xff, 0xfe, 0xff, 0xf2, 0xff, 0xfc, 0xff, 0xf2, 0xff, 0xf9, 0xff, 0xf2, 0xff, 0xf6, 0xff, 0xf1, 0xff, 0xf4, 0xff, 0xf1, 0xff, 0xf3, 0xff, 0xf0, 0xff, 0xf2, 0xff, 0xf0, 0xff, 0xf2, 0xff, 0xf1, 0xff, 0xf3, 0xff, 0xf1, 0xff, 0xf4, 0xff, 0xf2, 0xff, 0xf4, 0xff, 0xf3, 0xff, 0xf4, 0xff, 0xf4, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x11, 0x00, 0xfc, 0xff, 0x13, 0x00, 0xfd, 0xff, 0x13, 0x00, 0xfe, 0xff, 0x12, 0x00, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x10, 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x11, 0x00, 0x02, 0x00, 0x12, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x15, 0x00, 0x03, 0x00, 0x15, 0x00, 0x05, 0x00, 0x13, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x0b, 0x00, 0xfe, 0xff, 0x0c, 0x00, 0xfa, 0xff, 0x0d, 0x00, 0xf8, 0xff, 0x0d, 0x00, 0xf5, 0xff, 0x0c, 0x00, 0xf4, 0xff, 0x0b, 0x00, 0xf2, 0xff, 0x09, 0x00, 0xf1, 0xff, 0x08, 0x00, 0xef, 0xff, 0x06, 0x00, 0xed, 0xff, 0x05, 0x00, 0xeb, 0xff, 0x05, 0x00, 0xe8, 0xff, 0x04, 0x00, 0xe6, 0xff, 0x04, 0x00, 0xe5, 0xff, 0x02, 0x00, 0xe4, 0xff, 0x00, 0x00, 0xe5, 0xff, 0xfe, 0xff, 0xe6, 0xff, 0xfc, 0xff, 0xe6, 0xff, 0xfb, 0xff, 0xe6, 0xff, 0xfa, 0xff, 0xe5, 0xff, 0xf9, 0xff, 0xe5, 0xff, 0xf8, 0xff, 0xe4, 0xff, 0xf7, 0xff, 0xe4, 0xff, 0xf6, 0xff, 0xe4, 0xff, 0xf5, 0xff, 0xe5, 0xff, 0xf3, 0xff, 0xe6, 0xff, 0xf2, 0xff, 0xe7, 0xff, 0xf0, 0xff, 0xe8, 0xff, 0xef, 0xff, 0xe9, 0xff, 0xed, 0xff, 0xea, 0xff, 0xec, 0xff, 0xea, 0xff, 0xea, 0xff, 0xeb, 0xff, 0xe9, 0xff, 0xec, 0xff, 0xe8, 0xff, 0xed, 0xff, 0xe7, 0xff, 0xef, 0xff, 0xe6, 0xff, 0xf1, 0xff, 0xe6, 0xff, 0xf3, 0xff, 0xe6, 0xff, 0xf5, 0xff, 0xe7, 0xff, 0xf7, 0xff, 0xe8, 0xff, 0xf8, 0xff, 0xe9, 0xff, 0xf9, 0xff, 0xeb, 0xff, 0xf9, 0xff, 0xec, 0xff, 0xfa, 0xff, 0xee, 0xff, 0xfb, 0xff, 0xf0, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xfa, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x08, 0x00, 0x04, 0x00, 0x09, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x11, 0x00, 0x0c, 0x00, 0x12, 0x00, 0x0d, 0x00, 0x12, 0x00, 0x0f, 0x00, 0x12, 0x00, 0x11, 0x00, 0x11, 0x00, 0x14, 0x00, 0x11, 0x00, 0x16, 0x00, 0x10, 0x00, 0x18, 0x00, 0x11, 0x00, 0x18, 0x00, 0x11, 0x00, 0x18, 0x00, 0x10, 0x00, 0x18, 0x00, 0x10, 0x00, 0x19, 0x00, 0x0f, 0x00, 0x19, 0x00, 0x0e, 0x00, 0x1a, 0x00, 0x0e, 0x00, 0x1a, 0x00, 0x0f, 0x00, 0x1b, 0x00, 0x0f, 0x00, 0x1a, 0x00, 0x0f, 0x00, 0x19, 0x00, 0x0f, 0x00, 0x17, 0x00, 0x0f, 0x00, 0x15, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x10, 0x00, 0x11, 0x00, 0x11, 0x00, 0x0f, 0x00, 0x12, 0x00, 0x0d, 0x00, 0x13, 0x00, 0x0d, 0x00, 0x13, 0x00, 0x0d, 0x00, 0x12, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xff, 0xff, 0x0d, 0x00, 0xff, 0xff, 0x0c, 0x00, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf6, 0xff, 0xfd, 0xff, 0xf5, 0xff, 0xfe, 0xff, 0xf4, 0xff, 0xfe, 0xff, 0xf3, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0xfd, 0xff, 0xf4, 0xff, 0xfd, 0xff, 0xf4, 0xff, 0xff, 0xff, 0xf6, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0xfe, 0xff, 0x12, 0x00, 0xfc, 0xff, 0x12, 0x00, 0xfa, 0xff, 0x12, 0x00, 0xf9, 0xff, 0x11, 0x00, 0xf9, 0xff, 0x10, 0x00, 0xf9, 0xff, 0x10, 0x00, 0xf9, 0xff, 0x11, 0x00, 0xf8, 0xff, 0x11, 0x00, 0xf7, 0xff, 0x11, 0x00, 0xf6, 0xff, 0x0f, 0x00, 0xf5, 0xff, 0x0c, 0x00, 0xf6, 0xff, 0x09, 0x00, 0xf7, 0xff, 0x07, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xff, 0xff, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf7, 0xff, 0x01, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf4, 0xff, 0x00, 0x00, 0xf2, 0xff, 0xfd, 0xff, 0xf1, 0xff, 0xfb, 0xff, 0xee, 0xff, 0xfa, 0xff, 0xec, 0xff, 0xf9, 0xff, 0xea, 0xff, 0xfa, 0xff, 0xe8, 0xff, 0xfc, 0xff, 0xe7, 0xff, 0xfc, 0xff, 0xe7, 0xff, 0xfc, 0xff, 0xe7, 0xff, 0xfb, 0xff, 0xe8, 0xff, 0xfb, 0xff, 0xe7, 0xff, 0xfa, 0xff, 0xe7, 0xff, 0xfb, 0xff, 0xe6, 0xff, 0xfc, 0xff, 0xe6, 0xff, 0xfd, 0xff, 0xe7, 0xff, 0xfe, 0xff, 0xe9, 0xff, 0xff, 0xff, 0xeb, 0xff, 0xff, 0xff, 0xed, 0xff, 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xf1, 0xff, 0x00, 0x00, 0xf2, 0xff, 0x01, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x08, 0x00, 0xf9, 0xff, 0x08, 0x00, 0xf9, 0xff, 0x09, 0x00, 0xf9, 0xff, 0x09, 0x00, 0xf8, 0xff, 0x09, 0x00, 0xf8, 0xff, 0x09, 0x00, 0xf8, 0xff, 0x0a, 0x00, 0xf9, 0xff, 0x0b, 0x00, 0xfa, 0xff, 0x0c, 0x00, 0xfa, 0xff, 0x0e, 0x00, 0xfa, 0xff, 0x0f, 0x00, 0xfa, 0xff, 0x10, 0x00, 0xf9, 0xff, 0x10, 0x00, 0xf9, 0xff, 0x0f, 0x00, 0xf9, 0xff, 0x0d, 0x00, 0xf9, 0xff, 0x0b, 0x00, 0xfb, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xff, 0xff, 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0xff, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfa, 0xff, 0x0b, 0x00, 0xf7, 0xff, 0x0d, 0x00, 0xf4, 0xff, 0x10, 0x00, 0xf2, 0xff, 0x11, 0x00, 0xf1, 0xff, 0x13, 0x00, 0xf1, 0xff, 0x13, 0x00, 0xf1, 0xff, 0x12, 0x00, 0xf2, 0xff, 0x11, 0x00, 0xf3, 0xff, 0x10, 0x00, 0xf3, 0xff, 0x0f, 0x00, 0xf3, 0xff, 0x0f, 0x00, 0xf3, 0xff, 0x0f, 0x00, 0xf2, 0xff, 0x0f, 0x00, 0xf1, 0xff, 0x0f, 0x00, 0xf0, 0xff, 0x0e, 0x00, 0xf0, 0xff, 0x0c, 0x00, 0xf0, 0xff, 0x0a, 0x00, 0xf1, 0xff, 0x08, 0x00, 0xf3, 0xff, 0x06, 0x00, 0xf5, 0xff, 0x05, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf4, 0xff, 0x03, 0x00, 0xf3, 0xff, 0x02, 0x00, 0xf2, 0xff, 0x00, 0x00, 0xf2, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfa, 0xff, 0xf5, 0xff, 0xf8, 0xff, 0xf7, 0xff, 0xf6, 0xff, 0xf9, 0xff, 0xf5, 0xff, 0xfa, 0xff, 0xf5, 0xff, 0xfa, 0xff, 0xf5, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xfa, 0xff, 0xf3, 0xff, 0xfb, 0xff, 0xf2, 0xff, 0xfc, 0xff, 0xf0, 0xff, 0xfd, 0xff, 0xef, 0xff, 0xfe, 0xff, 0xef, 0xff, 0x00, 0x00, 0xef, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x01, 0x00, 0xf2, 0xff, 0x01, 0x00, 0xf3, 0xff, 0x02, 0x00, 0xf5, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf4, 0xff, 0x04, 0x00, 0xf3, 0xff, 0x04, 0x00, 0xf3, 0xff, 0x05, 0x00, 0xf3, 0xff, 0x07, 0x00, 0xf4, 0xff, 0x08, 0x00, 0xf4, 0xff, 0x09, 0x00, 0xf6, 0xff, 0x0a, 0x00, 0xf7, 0xff, 0x0c, 0x00, 0xf9, 0xff, 0x0d, 0x00, 0xfa, 0xff, 0x0e, 0x00, 0xfb, 0xff, 0x0f, 0x00, 0xfb, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x10, 0x00, 0xfd, 0xff, 0x10, 0x00, 0xff, 0xff, 0x11, 0x00, 0x02, 0x00, 0x12, 0x00, 0x05, 0x00, 0x12, 0x00, 0x08, 0x00, 0x12, 0x00, 0x0a, 0x00, 0x12, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x09, 0x00, 0x12, 0x00, 0x07, 0x00, 0x15, 0x00, 0x06, 0x00, 0x19, 0x00, 0x05, 0x00, 0x1b, 0x00, 0x04, 0x00, 0x1d, 0x00, 0x03, 0x00, 0x1d, 0x00, 0x01, 0x00, 0x1c, 0x00, 0xfe, 0xff, 0x1b, 0x00, 0xfb, 0xff, 0x1a, 0x00, 0xf7, 0xff, 0x1a, 0x00, 0xf5, 0xff, 0x1b, 0x00, 0xf3, 0xff, 0x1d, 0x00, 0xf2, 0xff, 0x1f, 0x00, 0xf2, 0xff, 0x1f, 0x00, 0xf1, 0xff, 0x1e, 0x00, 0xf1, 0xff, 0x1c, 0x00, 0xf1, 0xff, 0x19, 0x00, 0xf0, 0xff, 0x16, 0x00, 0xef, 0xff, 0x13, 0x00, 0xed, 0xff, 0x10, 0x00, 0xec, 0xff, 0x0e, 0x00, 0xeb, 0xff, 0x0c, 0x00, 0xea, 0xff, 0x0a, 0x00, 0xeb, 0xff, 0x07, 0x00, 0xed, 0xff, 0x04, 0x00, 0xf0, 0xff, 0x01, 0x00, 0xf3, 0xff, 0xfe, 0xff, 0xf5, 0xff, 0xfb, 0xff, 0xf7, 0xff, 0xfa, 0xff, 0xf7, 0xff, 0xf8, 0xff, 0xf6, 0xff, 0xf7, 0xff, 0xf6, 0xff, 0xf7, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xf8, 0xff, 0xf5, 0xff, 0xfc, 0xff, 0xf4, 0xff, 0xff, 0xff, 0xf3, 0xff, 0x03, 0x00, 0xf4, 0xff, 0x05, 0x00, 0xf4, 0xff, 0x06, 0x00, 0xf5, 0xff, 0x06, 0x00, 0xf6, 0xff, 0x06, 0x00, 0xf6, 0xff, 0x07, 0x00, 0xf5, 0xff, 0x08, 0x00, 0xf4, 0xff, 0x0b, 0x00, 0xf4, 0xff, 0x0e, 0x00, 0xf4, 0xff, 0x11, 0x00, 0xf6, 0xff, 0x12, 0x00, 0xf8, 0xff, 0x13, 0x00, 0xf9, 0xff, 0x14, 0x00, 0xfa, 0xff, 0x14, 0x00, 0xfa, 0xff, 0x15, 0x00, 0xf9, 0xff, 0x15, 0x00, 0xf8, 0xff, 0x15, 0x00, 0xf7, 0xff, 0x14, 0x00, 0xf8, 0xff, 0x14, 0x00, 0xf9, 0xff, 0x14, 0x00, 0xfb, 0xff, 0x14, 0x00, 0xfd, 0xff, 0x14, 0x00, 0xfe, 0xff, 0x14, 0x00, 0xff, 0xff, 0x13, 0x00, 0xff, 0xff, 0x12, 0x00, 0xff, 0xff, 0x10, 0x00, 0xff, 0xff, 0x0e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x09, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x0b, 0x00, 0x0e, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x11, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x0a, 0x00, 0x16, 0x00, 0x09, 0x00, 0x16, 0x00, 0x08, 0x00, 0x16, 0x00, 0x06, 0x00, 0x15, 0x00, 0x05, 0x00, 0x12, 0x00, 0x03, 0x00, 0x10, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xfe, 0xff, 0x0e, 0x00, 0xfd, 0xff, 0x0e, 0x00, 0xfd, 0xff, 0x0e, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf6, 0xff, 0x01, 0x00, 0xf4, 0xff, 0xff, 0xff, 0xf2, 0xff, 0xfe, 0xff, 0xf2, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0xfa, 0xff, 0xf3, 0xff, 0xf7, 0xff, 0xf2, 0xff, 0xf3, 0xff, 0xf1, 0xff, 0xef, 0xff, 0xf0, 0xff, 0xec, 0xff, 0xef, 0xff, 0xe9, 0xff, 0xef, 0xff, 0xe7, 0xff, 0xf0, 0xff, 0xe6, 0xff, 0xf2, 0xff, 0xe5, 0xff, 0xf5, 0xff, 0xe4, 0xff, 0xf6, 0xff, 0xe3, 0xff, 0xf7, 0xff, 0xe1, 0xff, 0xf7, 0xff, 0xdf, 0xff, 0xf8, 0xff, 0xdd, 0xff, 0xf8, 0xff, 0xdc, 0xff, 0xf9, 0xff, 0xdc, 0xff, 0xfa, 0xff, 0xdd, 0xff, 0xfc, 0xff, 0xde, 0xff, 0xfe, 0xff, 0xde, 0xff, 0x00, 0x00, 0xdf, 0xff, 0x02, 0x00, 0xdf, 0xff, 0x03, 0x00, 0xdf, 0xff, 0x04, 0x00, 0xe0, 0xff, 0x05, 0x00, 0xe1, 0xff, 0x06, 0x00, 0xe2, 0xff, 0x06, 0x00, 0xe4, 0xff, 0x07, 0x00, 0xe6, 0xff, 0x07, 0x00, 0xe8, 0xff, 0x07, 0x00, 0xea, 0xff, 0x08, 0x00, 0xec, 0xff, 0x08, 0x00, 0xee, 0xff, 0x09, 0x00, 0xf0, 0xff, 0x0a, 0x00, 0xf3, 0xff, 0x0a, 0x00, 0xf6, 0xff, 0x0a, 0x00, 0xf9, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x08, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x10, 0x00, 0x04, 0x00, 0x13, 0x00, 0x05, 0x00, 0x15, 0x00, 0x05, 0x00, 0x16, 0x00, 0x05, 0x00, 0x16, 0x00, 0x03, 0x00, 0x16, 0x00, 0x01, 0x00, 0x17, 0x00, 0xff, 0xff, 0x19, 0x00, 0xfc, 0xff, 0x1b, 0x00, 0xfb, 0xff, 0x1d, 0x00, 0xfa, 0xff, 0x1f, 0x00, 0xfa, 0xff, 0x20, 0x00, 0xf9, 0xff, 0x20, 0x00, 0xf9, 0xff, 0x1f, 0x00, 0xf8, 0xff, 0x1e, 0x00, 0xf7, 0xff, 0x1d, 0x00, 0xf5, 0xff, 0x1c, 0x00, 0xf3, 0xff, 0x1b, 0x00, 0xf2, 0xff, 0x1a, 0x00, 0xf1, 0xff, 0x18, 0x00, 0xf1, 0xff, 0x17, 0x00, 0xf2, 0xff, 0x14, 0x00, 0xf2, 0xff, 0x12, 0x00, 0xf3, 0xff, 0x0f, 0x00, 0xf3, 0xff, 0x0d, 0x00, 0xf3, 0xff, 0x0a, 0x00, 0xf4, 0xff, 0x07, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf5, 0xff, 0x00, 0x00, 0xf5, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xfe, 0xff, 0xf5, 0xff, 0xfd, 0xff, 0xf5, 0xff, 0xfc, 0xff, 0xf6, 0xff, 0xfa, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf4, 0xff, 0xf6, 0xff, 0xf1, 0xff, 0xf6, 0xff, 0xf0, 0xff, 0xf5, 0xff, 0xef, 0xff, 0xf5, 0xff, 0xef, 0xff, 0xf5, 0xff, 0xf0, 0xff, 0xf6, 0xff, 0xef, 0xff, 0xf7, 0xff, 0xee, 0xff, 0xf8, 0xff, 0xeb, 0xff, 0xfa, 0xff, 0xe8, 0xff, 0xfc, 0xff, 0xe5, 0xff, 0xfd, 0xff, 0xe3, 0xff, 0xfe, 0xff, 0xe2, 0xff, 0xff, 0xff, 0xe2, 0xff, 0xff, 0xff, 0xe3, 0xff, 0x01, 0x00, 0xe5, 0xff, 0x03, 0x00, 0xe6, 0xff, 0x05, 0x00, 0xe6, 0xff, 0x08, 0x00, 0xe6, 0xff, 0x0a, 0x00, 0xe5, 0xff, 0x0b, 0x00, 0xe5, 0xff, 0x0d, 0x00, 0xe5, 0xff, 0x0d, 0x00, 0xe7, 0xff, 0x0e, 0x00, 0xea, 0xff, 0x0e, 0x00, 0xed, 0xff, 0x0f, 0x00, 0xf0, 0xff, 0x10, 0x00, 0xf3, 0xff, 0x12, 0x00, 0xf5, 0xff, 0x13, 0x00, 0xf7, 0xff, 0x14, 0x00, 0xf9, 0xff, 0x14, 0x00, 0xfa, 0xff, 0x13, 0x00, 0xfd, 0xff, 0x13, 0x00, 0x00, 0x00, 0x12, 0x00, 0x03, 0x00, 0x13, 0x00, 0x06, 0x00, 0x14, 0x00, 0x08, 0x00, 0x15, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x0d, 0x00, 0x13, 0x00, 0x0e, 0x00, 0x12, 0x00, 0x10, 0x00, 0x10, 0x00, 0x12, 0x00, 0x0f, 0x00, 0x14, 0x00, 0x0f, 0x00, 0x16, 0x00, 0x0f, 0x00, 0x18, 0x00, 0x0e, 0x00, 0x19, 0x00, 0x0d, 0x00, 0x1a, 0x00, 0x0b, 0x00, 0x1b, 0x00, 0x09, 0x00, 0x1d, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x02, 0x00, 0x20, 0x00, 0xff, 0xff, 0x20, 0x00, 0xfc, 0xff, 0x21, 0x00, 0xfb, 0xff, 0x22, 0x00, 0xfa, 0xff, 0x22, 0x00, 0xf9, 0xff, 0x23, 0x00, 0xf7, 0xff, 0x23, 0x00, 0xf5, 0xff, 0x24, 0x00, 0xf2, 0xff, 0x23, 0x00, 0xf0, 0xff, 0x22, 0x00, 0xed, 0xff, 0x20, 0x00, 0xeb, 0xff, 0x1e, 0x00, 0xea, 0xff, 0x1b, 0x00, 0xe9, 0xff, 0x18, 0x00, 0xe9, 0xff, 0x15, 0x00, 0xe9, 0xff, 0x12, 0x00, 0xea, 0xff, 0x0f, 0x00, 0xe9, 0xff, 0x0c, 0x00, 0xe8, 0xff, 0x08, 0x00, 0xe6, 0xff, 0x05, 0x00, 0xe4, 0xff, 0x02, 0x00, 0xe3, 0xff, 0xff, 0xff, 0xe2, 0xff, 0xfc, 0xff, 0xe4, 0xff, 0xf9, 0xff, 0xe6, 0xff, 0xf5, 0xff, 0xe8, 0xff, 0xf1, 0xff, 0xea, 0xff, 0xed, 0xff, 0xeb, 0xff, 0xe9, 0xff, 0xeb, 0xff, 0xe7, 0xff, 0xea, 0xff, 0xe5, 0xff, 0xea, 0xff, 0xe4, 0xff, 0xeb, 0xff, 0xe3, 0xff, 0xed, 0xff, 0xe1, 0xff, 0xf1, 0xff, 0xdf, 0xff, 0xf4, 0xff, 0xdd, 0xff, 0xf7, 0xff, 0xdb, 0xff, 0xf8, 0xff, 0xda, 0xff, 0xf8, 0xff, 0xda, 0xff, 0xf7, 0xff, 0xda, 0xff, 0xf7, 0xff, 0xdb, 0xff, 0xf7, 0xff, 0xdb, 0xff, 0xf9, 0xff, 0xdc, 0xff, 0xfb, 0xff, 0xdc, 0xff, 0xfe, 0xff, 0xdc, 0xff, 0x01, 0x00, 0xdc, 0xff, 0x03, 0x00, 0xdd, 0xff, 0x05, 0x00, 0xde, 0xff, 0x06, 0x00, 0xe0, 0xff, 0x07, 0x00, 0xe3, 0xff, 0x08, 0x00, 0xe5, 0xff, 0x09, 0x00, 0xe8, 0xff, 0x0b, 0x00, 0xea, 0xff, 0x0c, 0x00, 0xec, 0xff, 0x0e, 0x00, 0xee, 0xff, 0x11, 0x00, 0xf0, 0xff, 0x13, 0x00, 0xf2, 0xff, 0x15, 0x00, 0xf5, 0xff, 0x16, 0x00, 0xf8, 0xff, 0x16, 0x00, 0xfb, 0xff, 0x15, 0x00, 0xff, 0xff, 0x13, 0x00, 0x03, 0x00, 0x12, 0x00, 0x06, 0x00, 0x11, 0x00, 0x09, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x12, 0x00, 0x0f, 0x00, 0x16, 0x00, 0x0e, 0x00, 0x1b, 0x00, 0x0c, 0x00, 0x1f, 0x00, 0x0b, 0x00, 0x22, 0x00, 0x0b, 0x00, 0x24, 0x00, 0x0b, 0x00, 0x26, 0x00, 0x0c, 0x00, 0x27, 0x00, 0x0c, 0x00, 0x28, 0x00, 0x0c, 0x00, 0x28, 0x00, 0x0b, 0x00, 0x29, 0x00, 0x09, 0x00, 0x2b, 0x00, 0x07, 0x00, 0x2c, 0x00, 0x05, 0x00, 0x2e, 0x00, 0x04, 0x00, 0x2e, 0x00, 0x04, 0x00, 0x2d, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x03, 0x00, 0x2a, 0x00, 0x02, 0x00, 0x27, 0x00, 0xff, 0xff, 0x25, 0x00, 0xfc, 0xff, 0x22, 0x00, 0xf9, 0xff, 0x1f, 0x00, 0xf7, 0xff, 0x1d, 0x00, 0xf5, 0xff, 0x1a, 0x00, 0xf4, 0xff, 0x17, 0x00, 0xf3, 0xff, 0x13, 0x00, 0xf2, 0xff, 0x0e, 0x00, 0xf1, 0xff, 0x09, 0x00, 0xef, 0xff, 0x04, 0x00, 0xee, 0xff, 0xff, 0xff, 0xec, 0xff, 0xfb, 0xff, 0xeb, 0xff, 0xf9, 0xff, 0xeb, 0xff, 0xf7, 0xff, 0xeb, 0xff, 0xf6, 0xff, 0xeb, 0xff, 0xf4, 0xff, 0xeb, 0xff, 0xf1, 0xff, 0xeb, 0xff, 0xed, 0xff, 0xeb, 0xff, 0xea, 0xff, 0xeb, 0xff, 0xe7, 0xff, 0xea, 0xff, 0xe6, 0xff, 0xea, 0xff, 0xe5, 0xff, 0xeb, 0xff, 0xe6, 0xff, 0xed, 0xff, 0xe6, 0xff, 0xf0, 0xff, 0xe6, 0xff, 0xf3, 0xff, 0xe5, 0xff, 0xf7, 0xff, 0xe3, 0xff, 0xf9, 0xff, 0xe1, 0xff, 0xfa, 0xff, 0xe0, 0xff, 0xfb, 0xff, 0xdf, 0xff, 0xfb, 0xff, 0xdf, 0xff, 0xfc, 0xff, 0xe0, 0xff, 0xfd, 0xff, 0xe1, 0xff, 0x01, 0x00, 0xe2, 0xff, 0x05, 0x00, 0xe2, 0xff, 0x09, 0x00, 0xe2, 0xff, 0x0c, 0x00, 0xe2, 0xff, 0x0e, 0x00, 0xe3, 0xff, 0x0d, 0x00, 0xe4, 0xff, 0x0c, 0x00, 0xe6, 0xff, 0x0b, 0x00, 0xe8, 0xff, 0x0b, 0x00, 0xeb, 0xff, 0x0b, 0x00, 0xee, 0xff, 0x0d, 0x00, 0xf2, 0xff, 0x0f, 0x00, 0xf5, 0xff, 0x11, 0x00, 0xf8, 0xff, 0x12, 0x00, 0xfa, 0xff, 0x11, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x0d, 0x00, 0x1b, 0x00, 0x0f, 0x00, 0x1d, 0x00, 0x10, 0x00, 0x1e, 0x00, 0x10, 0x00, 0x1f, 0x00, 0x0f, 0x00, 0x21, 0x00, 0x0e, 0x00, 0x25, 0x00, 0x0d, 0x00, 0x29, 0x00, 0x0d, 0x00, 0x2c, 0x00, 0x0d, 0x00, 0x2e, 0x00, 0x0d, 0x00, 0x2e, 0x00, 0x0e, 0x00, 0x2d, 0x00, 0x0d, 0x00, 0x2a, 0x00, 0x0c, 0x00, 0x27, 0x00, 0x0b, 0x00, 0x25, 0x00, 0x09, 0x00, 0x23, 0x00, 0x07, 0x00, 0x22, 0x00, 0x05, 0x00, 0x22, 0x00, 0x03, 0x00, 0x20, 0x00, 0x01, 0x00, 0x1d, 0x00, 0x01, 0x00, 0x19, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0xfe, 0xff, 0x0d, 0x00, 0xfc, 0xff, 0x0b, 0x00, 0xf9, 0xff, 0x09, 0x00, 0xf6, 0xff, 0x08, 0x00, 0xf3, 0xff, 0x06, 0x00, 0xf2, 0xff, 0x05, 0x00, 0xf3, 0xff, 0x02, 0x00, 0xf4, 0xff, 0x00, 0x00, 0xf6, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0xf9, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xf5, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf2, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xf3, 0xff, 0xf0, 0xff, 0xf5, 0xff, 0xed, 0xff, 0xf6, 0xff, 0xe9, 0xff, 0xf7, 0xff, 0xe5, 0xff, 0xf7, 0xff, 0xe2, 0xff, 0xf7, 0xff, 0xe0, 0xff, 0xf8, 0xff, 0xe1, 0xff, 0xfa, 0xff, 0xe2, 0xff, 0xfd, 0xff, 0xe3, 0xff, 0xff, 0xff, 0xe4, 0xff, 0x02, 0x00, 0xe3, 0xff, 0x04, 0x00, 0xe1, 0xff, 0x05, 0x00, 0xdf, 0xff, 0x07, 0x00, 0xde, 0xff, 0x08, 0x00, 0xde, 0xff, 0x0a, 0x00, 0xdf, 0xff, 0x0b, 0x00, 0xe2, 0xff, 0x0d, 0x00, 0xe5, 0xff, 0x0f, 0x00, 0xe9, 0xff, 0x10, 0x00, 0xec, 0xff, 0x12, 0x00, 0xee, 0xff, 0x12, 0x00, 0xef, 0xff, 0x13, 0x00, 0xf1, 0xff, 0x14, 0x00, 0xf3, 0xff, 0x15, 0x00, 0xf6, 0xff, 0x15, 0x00, 0xfa, 0xff, 0x16, 0x00, 0xfd, 0xff, 0x17, 0x00, 0x01, 0x00, 0x17, 0x00, 0x05, 0x00, 0x17, 0x00, 0x09, 0x00, 0x18, 0x00, 0x0c, 0x00, 0x18, 0x00, 0x0f, 0x00, 0x18, 0x00, 0x11, 0x00, 0x17, 0x00, 0x13, 0x00, 0x17, 0x00, 0x14, 0x00, 0x16, 0x00, 0x16, 0x00, 0x15, 0x00, 0x19, 0x00, 0x14, 0x00, 0x1b, 0x00, 0x13, 0x00, 0x1d, 0x00, 0x12, 0x00, 0x1f, 0x00, 0x12, 0x00, 0x1f, 0x00, 0x11, 0x00, 0x1e, 0x00, 0x0f, 0x00, 0x1e, 0x00, 0x0d, 0x00, 0x1d, 0x00, 0x0b, 0x00, 0x1e, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x08, 0x00, 0x20, 0x00, 0x07, 0x00, 0x20, 0x00, 0x06, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x01, 0x00, 0x1c, 0x00, 0xff, 0xff, 0x1a, 0x00, 0xfb, 0xff, 0x18, 0x00, 0xf9, 0xff, 0x18, 0x00, 0xf7, 0xff, 0x18, 0x00, 0xf6, 0xff, 0x17, 0x00, 0xf6, 0xff, 0x16, 0x00, 0xf5, 0xff, 0x14, 0x00, 0xf4, 0xff, 0x10, 0x00, 0xf2, 0xff, 0x0d, 0x00, 0xf0, 0xff, 0x0a, 0x00, 0xee, 0xff, 0x08, 0x00, 0xee, 0xff, 0x06, 0x00, 0xee, 0xff, 0x05, 0x00, 0xef, 0xff, 0x03, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xf1, 0xff, 0xfc, 0xff, 0xf1, 0xff, 0xf8, 0xff, 0xf2, 0xff, 0xf5, 0xff, 0xf2, 0xff, 0xf1, 0xff, 0xf2, 0xff, 0xef, 0xff, 0xf2, 0xff, 0xed, 0xff, 0xf3, 0xff, 0xeb, 0xff, 0xf3, 0xff, 0xe8, 0xff, 0xf4, 0xff, 0xe6, 0xff, 0xf4, 0xff, 0xe3, 0xff, 0xf5, 0xff, 0xe1, 0xff, 0xf5, 0xff, 0xde, 0xff, 0xf4, 0xff, 0xdc, 0xff, 0xf3, 0xff, 0xdb, 0xff, 0xf2, 0xff, 0xd9, 0xff, 0xf1, 0xff, 0xd8, 0xff, 0xf1, 0xff, 0xd7, 0xff, 0xf1, 0xff, 0xd6, 0xff, 0xf3, 0xff, 0xd7, 0xff, 0xf5, 0xff, 0xd8, 0xff, 0xf8, 0xff, 0xd8, 0xff, 0xf9, 0xff, 0xd8, 0xff, 0xfa, 0xff, 0xd9, 0xff, 0xf9, 0xff, 0xd9, 0xff, 0xf8, 0xff, 0xda, 0xff, 0xf8, 0xff, 0xdb, 0xff, 0xfa, 0xff, 0xdc, 0xff, 0xfd, 0xff, 0xdf, 0xff, 0x01, 0x00, 0xe1, 0xff, 0x04, 0x00, 0xe4, 0xff, 0x07, 0x00, 0xe6, 0xff, 0x08, 0x00, 0xe7, 0xff, 0x08, 0x00, 0xe8, 0xff, 0x07, 0x00, 0xe9, 0xff, 0x08, 0x00, 0xea, 0xff, 0x09, 0x00, 0xed, 0xff, 0x0b, 0x00, 0xf0, 0xff, 0x0d, 0x00, 0xf4, 0xff, 0x0e, 0x00, 0xf7, 0xff, 0x0e, 0x00, 0xfb, 0xff, 0x0c, 0x00, 0xfe, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x02, 0x00, 0x08, 0x00, 0x04, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x0f, 0x00, 0x05, 0x00, 0x12, 0x00, 0x03, 0x00, 0x15, 0x00, 0x02, 0x00, 0x17, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0xff, 0xff, 0x1a, 0x00, 0xfe, 0xff, 0x1a, 0x00, 0xfd, 0xff, 0x1b, 0x00, 0xfd, 0xff, 0x1c, 0x00, 0xfd, 0xff, 0x1d, 0x00, 0xfd, 0xff, 0x1d, 0x00, 0xfe, 0xff, 0x1d, 0x00, 0xfe, 0xff, 0x1d, 0x00, 0xfe, 0xff, 0x1b, 0x00, 0xfe, 0xff, 0x1a, 0x00, 0xfc, 0xff, 0x18, 0x00, 0xfb, 0xff, 0x16, 0x00, 0xfa, 0xff, 0x15, 0x00, 0xf9, 0xff, 0x14, 0x00, 0xf9, 0xff, 0x13, 0x00, 0xf9, 0xff, 0x11, 0x00, 0xf9, 0xff, 0x0e, 0x00, 0xf8, 0xff, 0x0b, 0x00, 0xf6, 0xff, 0x08, 0x00, 0xf3, 0xff, 0x05, 0x00, 0xf1, 0xff, 0x03, 0x00, 0xef, 0xff, 0x02, 0x00, 0xef, 0xff, 0x00, 0x00, 0xef, 0xff, 0xfe, 0xff, 0xee, 0xff, 0xfb, 0xff, 0xec, 0xff, 0xf8, 0xff, 0xea, 0xff, 0xf5, 0xff, 0xe9, 0xff, 0xf2, 0xff, 0xe8, 0xff, 0xf1, 0xff, 0xe9, 0xff, 0xf0, 0xff, 0xea, 0xff, 0xef, 0xff, 0xed, 0xff, 0xee, 0xff, 0xef, 0xff, 0xec, 0xff, 0xf1, 0xff, 0xe9, 0xff, 0xf1, 0xff, 0xe7, 0xff, 0xf1, 0xff, 0xe4, 0xff, 0xf2, 0xff, 0xe2, 0xff, 0xf3, 0xff, 0xe1, 0xff, 0xf5, 0xff, 0xe0, 0xff, 0xf8, 0xff, 0xe0, 0xff, 0xfc, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xe0, 0xff, 0x01, 0x00, 0xdf, 0xff, 0x03, 0x00, 0xdf, 0xff, 0x04, 0x00, 0xde, 0xff, 0x04, 0x00, 0xdd, 0xff, 0x04, 0x00, 0xdd, 0xff, 0x03, 0x00, 0xde, 0xff, 0x03, 0x00, 0xe0, 0xff, 0x04, 0x00, 0xe2, 0xff, 0x05, 0x00, 0xe5, 0xff, 0x06, 0x00, 0xe7, 0xff, 0x08, 0x00, 0xea, 0xff, 0x08, 0x00, 0xee, 0xff, 0x08, 0x00, 0xf1, 0xff, 0x07, 0x00, 0xf4, 0xff, 0x06, 0x00, 0xf6, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xff, 0xff, 0x06, 0x00, 0x03, 0x00, 0x07, 0x00, 0x07, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x12, 0x00, 0x06, 0x00, 0x15, 0x00, 0x04, 0x00, 0x17, 0x00, 0x05, 0x00, 0x19, 0x00, 0x06, 0x00, 0x1b, 0x00, 0x09, 0x00, 0x1e, 0x00, 0x0b, 0x00, 0x21, 0x00, 0x0d, 0x00, 0x24, 0x00, 0x0d, 0x00, 0x26, 0x00, 0x0c, 0x00, 0x27, 0x00, 0x0c, 0x00, 0x28, 0x00, 0x0c, 0x00, 0x28, 0x00, 0x0d, 0x00, 0x29, 0x00, 0x0f, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x2a, 0x00, 0x12, 0x00, 0x2b, 0x00, 0x12, 0x00, 0x2b, 0x00, 0x11, 0x00, 0x2b, 0x00, 0x0f, 0x00, 0x2b, 0x00, 0x0e, 0x00, 0x2a, 0x00, 0x0c, 0x00, 0x29, 0x00, 0x0b, 0x00, 0x28, 0x00, 0x0b, 0x00, 0x27, 0x00, 0x0a, 0x00, 0x26, 0x00, 0x09, 0x00, 0x25, 0x00, 0x08, 0x00, 0x24, 0x00, 0x06, 0x00, 0x22, 0x00, 0x05, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1a, 0x00, 0xfe, 0xff, 0x18, 0x00, 0xfc, 0xff, 0x16, 0x00, 0xfb, 0xff, 0x15, 0x00, 0xfb, 0xff, 0x13, 0x00, 0xfc, 0xff, 0x12, 0x00, 0xfc, 0xff, 0x11, 0x00, 0xfb, 0xff, 0x0f, 0x00, 0xf9, 0xff, 0x0d, 0x00, 0xf7, 0xff, 0x0a, 0x00, 0xf4, 0xff, 0x08, 0x00, 0xf1, 0xff, 0x05, 0x00, 0xf0, 0xff, 0x03, 0x00, 0xf0, 0xff, 0x02, 0x00, 0xf1, 0xff, 0x01, 0x00, 0xf2, 0xff, 0xff, 0xff, 0xf2, 0xff, 0xfd, 0xff, 0xf1, 0xff, 0xfa, 0xff, 0xef, 0xff, 0xf6, 0xff, 0xec, 0xff, 0xf3, 0xff, 0xeb, 0xff, 0xf1, 0xff, 0xeb, 0xff, 0xef, 0xff, 0xec, 0xff, 0xef, 0xff, 0xee, 0xff, 0xef, 0xff, 0xf0, 0xff, 0xee, 0xff, 0xf1, 0xff, 0xed, 0xff, 0xf2, 0xff, 0xec, 0xff, 0xf2, 0xff, 0xeb, 0xff, 0xf2, 0xff, 0xea, 0xff, 0xf2, 0xff, 0xea, 0xff, 0xf3, 0xff, 0xeb, 0xff, 0xf5, 0xff, 0xeb, 0xff, 0xf7, 0xff, 0xec, 0xff, 0xf8, 0xff, 0xee, 0xff, 0xfa, 0xff, 0xef, 0xff, 0xfb, 0xff, 0xf0, 0xff, 0xfb, 0xff, 0xf2, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf5, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xf8, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xff, 0xff, 0x07, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, 0x09, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x08, 0x00, 0x0f, 0x00, 0x09, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x07, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x03, 0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x07, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf4, 0xff, 0xfb, 0xff, 0xf2, 0xff, 0xfa, 0xff, 0xf1, 0xff, 0xfa, 0xff, 0xef, 0xff, 0xfb, 0xff, 0xed, 0xff, 0xfc, 0xff, 0xeb, 0xff, 0xfd, 0xff, 0xe9, 0xff, 0xfe, 0xff, 0xe6, 0xff, 0xfe, 0xff, 0xe5, 0xff, 0xfd, 0xff, 0xe4, 0xff, 0xfc, 0xff, 0xe4, 0xff, 0xfb, 0xff, 0xe4, 0xff, 0xfa, 0xff, 0xe4, 0xff, 0xfb, 0xff, 0xe3, 0xff, 0xfc, 0xff, 0xe1, 0xff, 0xfd, 0xff, 0xe0, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x01, 0x00, 0xdf, 0xff, 0x02, 0x00, 0xe0, 0xff, 0x02, 0x00, 0xe2, 0xff, 0x01, 0x00, 0xe4, 0xff, 0x01, 0x00, 0xe6, 0xff, 0x01, 0x00, 0xe7, 0xff, 0x03, 0x00, 0xe7, 0xff, 0x06, 0x00, 0xe7, 0xff, 0x0a, 0x00, 0xe8, 0xff, 0x0d, 0x00, 0xe8, 0xff, 0x10, 0x00, 0xe9, 0xff, 0x11, 0x00, 0xea, 0xff, 0x11, 0x00, 0xeb, 0xff, 0x10, 0x00, 0xec, 0xff, 0x10, 0x00, 0xed, 0xff, 0x10, 0x00, 0xee, 0xff, 0x11, 0x00, 0xef, 0xff, 0x13, 0x00, 0xf0, 0xff, 0x15, 0x00, 0xf0, 0xff, 0x16, 0x00, 0xf0, 0xff, 0x16, 0x00, 0xf1, 0xff, 0x15, 0x00, 0xf2, 0xff, 0x13, 0x00, 0xf3, 0xff, 0x11, 0x00, 0xf4, 0xff, 0x10, 0x00, 0xf6, 0xff, 0x10, 0x00, 0xf8, 0xff, 0x10, 0x00, 0xfa, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x10, 0x00, 0x06, 0x00, 0x11, 0x00, 0x06, 0x00, 0x12, 0x00, 0x05, 0x00, 0x14, 0x00, 0x05, 0x00, 0x16, 0x00, 0x03, 0x00, 0x19, 0x00, 0x01, 0x00, 0x1b, 0x00, 0xff, 0xff, 0x1c, 0x00, 0xfc, 0xff, 0x1d, 0x00, 0xfa, 0xff, 0x1d, 0x00, 0xf9, 0xff, 0x1c, 0x00, 0xf8, 0xff, 0x1c, 0x00, 0xf7, 0xff, 0x1c, 0x00, 0xf6, 0xff, 0x1c, 0x00, 0xf5, 0xff, 0x1c, 0x00, 0xf3, 0xff, 0x1c, 0x00, 0xf0, 0xff, 0x1c, 0x00, 0xee, 0xff, 0x1a, 0x00, 0xeb, 0xff, 0x18, 0x00, 0xea, 0xff, 0x15, 0x00, 0xe8, 0xff, 0x13, 0x00, 0xe7, 0xff, 0x11, 0x00, 0xe7, 0xff, 0x10, 0x00, 0xe7, 0xff, 0x0f, 0x00, 0xe6, 0xff, 0x0d, 0x00, 0xe5, 0xff, 0x0b, 0x00, 0xe4, 0xff, 0x09, 0x00, 0xe4, 0xff, 0x07, 0x00, 0xe4, 0xff, 0x05, 0x00, 0xe5, 0xff, 0x04, 0x00, 0xe7, 0xff, 0x02, 0x00, 0xe9, 0xff, 0xff, 0xff, 0xeb, 0xff, 0xfd, 0xff, 0xed, 0xff, 0xfb, 0xff, 0xef, 0xff, 0xfa, 0xff, 0xf0, 0xff, 0xf9, 0xff, 0xf2, 0xff, 0xf9, 0xff, 0xf3, 0xff, 0xf9, 0xff, 0xf5, 0xff, 0xf8, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf9, 0xff, 0xf5, 0xff, 0xfb, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf1, 0xff, 0xfe, 0xff, 0xf1, 0xff, 0x00, 0x00, 0xf1, 0xff, 0x02, 0x00, 0xf1, 0xff, 0x04, 0x00, 0xf1, 0xff, 0x06, 0x00, 0xf1, 0xff, 0x07, 0x00, 0xf1, 0xff, 0x08, 0x00, 0xf1, 0xff, 0x09, 0x00, 0xf1, 0xff, 0x0a, 0x00, 0xf2, 0xff, 0x0c, 0x00, 0xf4, 0xff, 0x0e, 0x00, 0xf5, 0xff, 0x10, 0x00, 0xf7, 0xff, 0x11, 0x00, 0xf8, 0xff, 0x12, 0x00, 0xf9, 0xff, 0x13, 0x00, 0xfa, 0xff, 0x14, 0x00, 0xfc, 0xff, 0x15, 0x00, 0xff, 0xff, 0x16, 0x00, 0x01, 0x00, 0x16, 0x00, 0x03, 0x00, 0x16, 0x00, 0x05, 0x00, 0x16, 0x00, 0x06, 0x00, 0x16, 0x00, 0x07, 0x00, 0x16, 0x00, 0x09, 0x00, 0x15, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x0c, 0x00, 0x13, 0x00, 0x0e, 0x00, 0x12, 0x00, 0x10, 0x00, 0x11, 0x00, 0x11, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x0c, 0x00, 0x15, 0x00, 0x0a, 0x00, 0x17, 0x00, 0x08, 0x00, 0x19, 0x00, 0x07, 0x00, 0x1b, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x1f, 0x00, 0x01, 0x00, 0x20, 0x00, 0xff, 0xff, 0x21, 0x00, 0xfd, 0xff, 0x23, 0x00, 0xfc, 0xff, 0x25, 0x00, 0xfb, 0xff, 0x26, 0x00, 0xfb, 0xff, 0x27, 0x00, 0xfa, 0xff, 0x26, 0x00, 0xfa, 0xff, 0x25, 0x00, 0xf9, 0xff, 0x24, 0x00, 0xf7, 0xff, 0x22, 0x00, 0xf6, 0xff, 0x22, 0x00, 0xf5, 0xff, 0x22, 0x00, 0xf4, 0xff, 0x21, 0x00, 0xf3, 0xff, 0x20, 0x00, 0xf2, 0xff, 0x1e, 0x00, 0xf1, 0xff, 0x1a, 0x00, 0xef, 0xff, 0x17, 0x00, 0xed, 0xff, 0x13, 0x00, 0xec, 0xff, 0x0f, 0x00, 0xea, 0xff, 0x0c, 0x00, 0xea, 0xff, 0x09, 0x00, 0xea, 0xff, 0x07, 0x00, 0xe9, 0xff, 0x04, 0x00, 0xe9, 0xff, 0x01, 0x00, 0xe9, 0xff, 0xfe, 0xff, 0xe9, 0xff, 0xfb, 0xff, 0xe8, 0xff, 0xf7, 0xff, 0xe8, 0xff, 0xf4, 0xff, 0xe9, 0xff, 0xf0, 0xff, 0xea, 0xff, 0xec, 0xff, 0xec, 0xff, 0xe9, 0xff, 0xee, 0xff, 0xe7, 0xff, 0xf0, 0xff, 0xe6, 0xff, 0xf2, 0xff, 0xe5, 0xff, 0xf4, 0xff, 0xe4, 0xff, 0xf5, 0xff, 0xe4, 0xff, 0xf7, 0xff, 0xe4, 0xff, 0xf9, 0xff, 0xe3, 0xff, 0xfc, 0xff, 0xe1, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x03, 0x00, 0xde, 0xff, 0x06, 0x00, 0xdf, 0xff, 0x09, 0x00, 0xe0, 0xff, 0x0b, 0x00, 0xe1, 0xff, 0x0d, 0x00, 0xe2, 0xff, 0x0f, 0x00, 0xe3, 0xff, 0x11, 0x00, 0xe2, 0xff, 0x13, 0x00, 0xe0, 0xff, 0x15, 0x00, 0xdf, 0xff, 0x18, 0x00, 0xdf, 0xff, 0x1a, 0x00, 0xdf, 0xff, 0x1b, 0x00, 0xe1, 0xff, 0x1c, 0x00, 0xe3, 0xff, 0x1d, 0x00, 0xe5, 0xff, 0x1d, 0x00, 0xe6, 0xff, 0x1d, 0x00, 0xe7, 0xff, 0x1c, 0x00, 0xe7, 0xff, 0x1c, 0x00, 0xe7, 0xff, 0x1c, 0x00, 0xe8, 0xff, 0x1c, 0x00, 0xe9, 0xff, 0x1c, 0x00, 0xeb, 0xff, 0x1b, 0x00, 0xed, 0xff, 0x1a, 0x00, 0xf0, 0xff, 0x18, 0x00, 0xf4, 0xff, 0x16, 0x00, 0xf7, 0xff, 0x14, 0x00, 0xfb, 0xff, 0x13, 0x00, 0xfd, 0xff, 0x12, 0x00, 0xff, 0xff, 0x12, 0x00, 0x01, 0x00, 0x12, 0x00, 0x02, 0x00, 0x12, 0x00, 0x04, 0x00, 0x11, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x12, 0x00, 0x09, 0x00, 0x13, 0x00, 0x09, 0x00, 0x13, 0x00, 0x08, 0x00, 0x12, 0x00, 0x07, 0x00, 0x11, 0x00, 0x05, 0x00, 0x11, 0x00, 0x02, 0x00, 0x12, 0x00, 0xff, 0xff, 0x13, 0x00, 0xfd, 0xff, 0x13, 0x00, 0xfa, 0xff, 0x12, 0x00, 0xf9, 0xff, 0x11, 0x00, 0xf7, 0xff, 0x10, 0x00, 0xf5, 0xff, 0x0f, 0x00, 0xf3, 0xff, 0x0e, 0x00, 0xf1, 0xff, 0x0d, 0x00, 0xef, 0xff, 0x0d, 0x00, 0xed, 0xff, 0x0d, 0x00, 0xeb, 0xff, 0x0d, 0x00, 0xe8, 0xff, 0x0c, 0x00, 0xe6, 0xff, 0x0c, 0x00, 0xe4, 0xff, 0x0b, 0x00, 0xe2, 0xff, 0x0b, 0x00, 0xe1, 0xff, 0x0b, 0x00, 0xe1, 0xff, 0x0b, 0x00, 0xe1, 0xff, 0x0a, 0x00, 0xe2, 0xff, 0x0a, 0x00, 0xe3, 0xff, 0x09, 0x00, 0xe4, 0xff, 0x07, 0x00, 0xe4, 0xff, 0x06, 0x00, 0xe4, 0xff, 0x05, 0x00, 0xe4, 0xff, 0x04, 0x00, 0xe4, 0xff, 0x03, 0x00, 0xe6, 0xff, 0x01, 0x00, 0xe8, 0xff, 0xfe, 0xff, 0xeb, 0xff, 0xfb, 0xff, 0xed, 0xff, 0xf8, 0xff, 0xef, 0xff, 0xf6, 0xff, 0xf1, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf1, 0xff, 0xf5, 0xff, 0xef, 0xff, 0xf8, 0xff, 0xee, 0xff, 0xfa, 0xff, 0xee, 0xff, 0xfc, 0xff, 0xed, 0xff, 0xfd, 0xff, 0xec, 0xff, 0xfe, 0xff, 0xeb, 0xff, 0xff, 0xff, 0xea, 0xff, 0x01, 0x00, 0xea, 0xff, 0x03, 0x00, 0xe9, 0xff, 0x06, 0x00, 0xe8, 0xff, 0x09, 0x00, 0xe8, 0xff, 0x0b, 0x00, 0xe7, 0xff, 0x0c, 0x00, 0xe7, 0xff, 0x0c, 0x00, 0xe8, 0xff, 0x0c, 0x00, 0xea, 0xff, 0x0d, 0x00, 0xeb, 0xff, 0x0d, 0x00, 0xed, 0xff, 0x0f, 0x00, 0xee, 0xff, 0x11, 0x00, 0xef, 0xff, 0x12, 0x00, 0xef, 0xff, 0x13, 0x00, 0xef, 0xff, 0x12, 0x00, 0xf0, 0xff, 0x11, 0x00, 0xf1, 0xff, 0x10, 0x00, 0xf3, 0xff, 0x10, 0x00, 0xf6, 0xff, 0x10, 0x00, 0xf9, 0xff, 0x11, 0x00, 0xfc, 0xff, 0x11, 0x00, 0xfe, 0xff, 0x11, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x0e, 0x00, 0x08, 0x00, 0x10, 0x00, 0x06, 0x00, 0x11, 0x00, 0x03, 0x00, 0x12, 0x00, 0x01, 0x00, 0x13, 0x00, 0xfe, 0xff, 0x14, 0x00, 0xfc, 0xff, 0x15, 0x00, 0xf9, 0xff, 0x17, 0x00, 0xf7, 0xff, 0x18, 0x00, 0xf4, 0xff, 0x19, 0x00, 0xf0, 0xff, 0x19, 0x00, 0xed, 0xff, 0x19, 0x00, 0xeb, 0xff, 0x18, 0x00, 0xe9, 0xff, 0x18, 0x00, 0xe7, 0xff, 0x19, 0x00, 0xe6, 0xff, 0x1a, 0x00, 0xe4, 0xff, 0x1a, 0x00, 0xe2, 0xff, 0x1b, 0x00, 0xe0, 0xff, 0x1a, 0x00, 0xde, 0xff, 0x18, 0x00, 0xdd, 0xff, 0x15, 0x00, 0xdd, 0xff, 0x13, 0x00, 0xdd, 0xff, 0x11, 0x00, 0xde, 0xff, 0x10, 0x00, 0xdf, 0xff, 0x0f, 0x00, 0xe0, 0xff, 0x0e, 0x00, 0xe1, 0xff, 0x0c, 0x00, 0xe2, 0xff, 0x0a, 0x00, 0xe3, 0xff, 0x08, 0x00, 0xe5, 0xff, 0x05, 0x00, 0xe8, 0xff, 0x03, 0x00, 0xeb, 0xff, 0x02, 0x00, 0xee, 0xff, 0x01, 0x00, 0xf1, 0xff, 0x00, 0x00, 0xf4, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x0b, 0x00, 0xf8, 0xff, 0x0e, 0x00, 0xf8, 0xff, 0x11, 0x00, 0xf7, 0xff, 0x13, 0x00, 0xf7, 0xff, 0x15, 0x00, 0xf6, 0xff, 0x16, 0x00, 0xf5, 0xff, 0x18, 0x00, 0xf5, 0xff, 0x1a, 0x00, 0xf4, 0xff, 0x1d, 0x00, 0xf4, 0xff, 0x1f, 0x00, 0xf4, 0xff, 0x22, 0x00, 0xf4, 0xff, 0x25, 0x00, 0xf4, 0xff, 0x28, 0x00, 0xf3, 0xff, 0x29, 0x00, 0xf2, 0xff, 0x2a, 0x00, 0xf1, 0xff, 0x2b, 0x00, 0xf0, 0xff, 0x2b, 0x00, 0xf0, 0xff, 0x2b, 0x00, 0xf0, 0xff, 0x2c, 0x00, 0xf2, 0xff, 0x2d, 0x00, 0xf4, 0xff, 0x2d, 0x00, 0xf6, 0xff, 0x2d, 0x00, 0xf6, 0xff, 0x2c, 0x00, 0xf7, 0xff, 0x2a, 0x00, 0xf6, 0xff, 0x27, 0x00, 0xf6, 0xff, 0x24, 0x00, 0xf6, 0xff, 0x21, 0x00, 0xf7, 0xff, 0x1e, 0x00, 0xf9, 0xff, 0x1b, 0x00, 0xfb, 0xff, 0x18, 0x00, 0xfe, 0xff, 0x15, 0x00, 0xff, 0xff, 0x12, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfa, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x08, 0x00, 0xf4, 0xff, 0x09, 0x00, 0xf2, 0xff, 0x09, 0x00, 0xf1, 0xff, 0x09, 0x00, 0xef, 0xff, 0x08, 0x00, 0xed, 0xff, 0x07, 0x00, 0xea, 0xff, 0x07, 0x00, 0xe8, 0xff, 0x07, 0x00, 0xe6, 0xff, 0x08, 0x00, 0xe5, 0xff, 0x08, 0x00, 0xe4, 0xff, 0x08, 0x00, 0xe4, 0xff, 0x07, 0x00, 0xe3, 0xff, 0x06, 0x00, 0xe2, 0xff, 0x04, 0x00, 0xe2, 0xff, 0x02, 0x00, 0xe1, 0xff, 0x01, 0x00, 0xe0, 0xff, 0x01, 0x00, 0xe0, 0xff, 0x01, 0x00, 0xe1, 0xff, 0x02, 0x00, 0xe2, 0xff, 0x03, 0x00, 0xe4, 0xff, 0x02, 0x00, 0xe5, 0xff, 0x02, 0x00, 0xe6, 0xff, 0x01, 0x00, 0xe6, 0xff, 0x00, 0x00, 0xe8, 0xff, 0x00, 0x00, 0xe9, 0xff, 0x01, 0x00, 0xeb, 0xff, 0x02, 0x00, 0xed, 0xff, 0x04, 0x00, 0xf0, 0xff, 0x04, 0x00, 0xf2, 0xff, 0x03, 0x00, 0xf4, 0xff, 0x02, 0x00, 0xf7, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0xfe, 0xff, 0x0d, 0x00, 0xfc, 0xff, 0x10, 0x00, 0xfa, 0xff, 0x13, 0x00, 0xf9, 0xff, 0x16, 0x00, 0xf9, 0xff, 0x19, 0x00, 0xfb, 0xff, 0x1b, 0x00, 0xfd, 0xff, 0x1c, 0x00, 0xff, 0xff, 0x1d, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x1c, 0x00, 0xff, 0xff, 0x1d, 0x00, 0xff, 0xff, 0x1d, 0x00, 0xfe, 0xff, 0x1e, 0x00, 0xff, 0xff, 0x1f, 0x00, 0xff, 0xff, 0x20, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x01, 0x00, 0x1d, 0x00, 0x02, 0x00, 0x1b, 0x00, 0x02, 0x00, 0x18, 0x00, 0x02, 0x00, 0x15, 0x00, 0x01, 0x00, 0x13, 0x00, 0x01, 0x00, 0x11, 0x00, 0x02, 0x00, 0x0f, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x05, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfa, 0xff, 0x09, 0x00, 0xf8, 0xff, 0x0a, 0x00, 0xf7, 0xff, 0x0c, 0x00, 0xf5, 0xff, 0x0d, 0x00, 0xf2, 0xff, 0x0d, 0x00, 0xef, 0xff, 0x0c, 0x00, 0xec, 0xff, 0x0b, 0x00, 0xe9, 0xff, 0x0b, 0x00, 0xe7, 0xff, 0x0b, 0x00, 0xe6, 0xff, 0x0c, 0x00, 0xe5, 0xff, 0x0d, 0x00, 0xe3, 0xff, 0x0e, 0x00, 0xe1, 0xff, 0x0f, 0x00, 0xdf, 0xff, 0x0f, 0x00, 0xde, 0xff, 0x0f, 0x00, 0xdc, 0xff, 0x0e, 0x00, 0xdb, 0xff, 0x0d, 0x00, 0xda, 0xff, 0x0c, 0x00, 0xda, 0xff, 0x0a, 0x00, 0xda, 0xff, 0x0a, 0x00, 0xda, 0xff, 0x0a, 0x00, 0xda, 0xff, 0x0a, 0x00, 0xdb, 0xff, 0x09, 0x00, 0xdc, 0xff, 0x08, 0x00, 0xde, 0xff, 0x06, 0x00, 0xe0, 0xff, 0x03, 0x00, 0xe2, 0xff, 0x01, 0x00, 0xe3, 0xff, 0xff, 0xff, 0xe3, 0xff, 0xfe, 0xff, 0xe4, 0xff, 0xfe, 0xff, 0xe5, 0xff, 0xfe, 0xff, 0xe8, 0xff, 0xfe, 0xff, 0xeb, 0xff, 0xfd, 0xff, 0xee, 0xff, 0xfb, 0xff, 0xf2, 0xff, 0xf8, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xf8, 0xff, 0xf4, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xfb, 0xff, 0xf5, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x07, 0x00, 0xf6, 0xff, 0x0a, 0x00, 0xf4, 0xff, 0x0d, 0x00, 0xf3, 0xff, 0x10, 0x00, 0xf2, 0xff, 0x12, 0x00, 0xf3, 0xff, 0x14, 0x00, 0xf4, 0xff, 0x16, 0x00, 0xf6, 0xff, 0x17, 0x00, 0xf7, 0xff, 0x18, 0x00, 0xf7, 0xff, 0x19, 0x00, 0xf6, 0xff, 0x1a, 0x00, 0xf4, 0xff, 0x1a, 0x00, 0xf2, 0xff, 0x1b, 0x00, 0xf1, 0xff, 0x1c, 0x00, 0xf0, 0xff, 0x1c, 0x00, 0xf1, 0xff, 0x1c, 0x00, 0xf2, 0xff, 0x1d, 0x00, 0xf3, 0xff, 0x1d, 0x00, 0xf4, 0xff, 0x1d, 0x00, 0xf3, 0xff, 0x1d, 0x00, 0xf2, 0xff, 0x1d, 0x00, 0xf1, 0xff, 0x1d, 0x00, 0xf0, 0xff, 0x1d, 0x00, 0xef, 0xff, 0x1d, 0x00, 0xf0, 0xff, 0x1c, 0x00, 0xf2, 0xff, 0x1a, 0x00, 0xf5, 0xff, 0x17, 0x00, 0xf7, 0xff, 0x14, 0x00, 0xf8, 0xff, 0x11, 0x00, 0xf8, 0xff, 0x0e, 0x00, 0xf7, 0xff, 0x0c, 0x00, 0xf6, 0xff, 0x09, 0x00, 0xf5, 0xff, 0x07, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf7, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xf4, 0xff, 0xfc, 0xff, 0xf2, 0xff, 0xfb, 0xff, 0xf0, 0xff, 0xfa, 0xff, 0xf0, 0xff, 0xf9, 0xff, 0xf0, 0xff, 0xf9, 0xff, 0xf0, 0xff, 0xf9, 0xff, 0xef, 0xff, 0xfb, 0xff, 0xee, 0xff, 0xfd, 0xff, 0xed, 0xff, 0xfe, 0xff, 0xeb, 0xff, 0xfe, 0xff, 0xea, 0xff, 0xfe, 0xff, 0xea, 0xff, 0xfe, 0xff, 0xea, 0xff, 0xfd, 0xff, 0xeb, 0xff, 0xfe, 0xff, 0xed, 0xff, 0x00, 0x00, 0xee, 0xff, 0x01, 0x00, 0xef, 0xff, 0x03, 0x00, 0xf0, 0xff, 0x04, 0x00, 0xf0, 0xff, 0x05, 0x00, 0xf1, 0xff, 0x04, 0x00, 0xf3, 0xff, 0x04, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0x03, 0x00, 0x07, 0x00, 0x05, 0x00, 0x08, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x10, 0x00, 0x05, 0x00, 0x13, 0x00, 0x05, 0x00, 0x15, 0x00, 0x04, 0x00, 0x17, 0x00, 0x04, 0x00, 0x18, 0x00, 0x04, 0x00, 0x18, 0x00, 0x04, 0x00, 0x18, 0x00, 0x04, 0x00, 0x18, 0x00, 0x04, 0x00, 0x18, 0x00, 0x03, 0x00, 0x18, 0x00, 0x02, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x18, 0x00, 0x02, 0x00, 0x18, 0x00, 0x02, 0x00, 0x18, 0x00, 0x02, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19, 0x00, 0xff, 0xff, 0x19, 0x00, 0xfe, 0xff, 0x19, 0x00, 0xfd, 0xff, 0x18, 0x00, 0xfd, 0xff, 0x17, 0x00, 0xfd, 0xff, 0x15, 0x00, 0xfd, 0xff, 0x13, 0x00, 0xfb, 0xff, 0x11, 0x00, 0xf9, 0xff, 0x10, 0x00, 0xf7, 0xff, 0x0e, 0x00, 0xf5, 0xff, 0x0d, 0x00, 0xf4, 0xff, 0x0b, 0x00, 0xf4, 0xff, 0x09, 0x00, 0xf4, 0xff, 0x07, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf5, 0xff, 0x00, 0x00, 0xf4, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfa, 0xff, 0xf2, 0xff, 0xf8, 0xff, 0xf2, 0xff, 0xf6, 0xff, 0xf2, 0xff, 0xf4, 0xff, 0xf2, 0xff, 0xf1, 0xff, 0xf4, 0xff, 0xee, 0xff, 0xf5, 0xff, 0xeb, 0xff, 0xf7, 0xff, 0xe8, 0xff, 0xf8, 0xff, 0xe6, 0xff, 0xfa, 0xff, 0xe4, 0xff, 0xfc, 0xff, 0xe3, 0xff, 0xfe, 0xff, 0xe2, 0xff, 0x00, 0x00, 0xe1, 0xff, 0x02, 0x00, 0xe0, 0xff, 0x03, 0x00, 0xdf, 0xff, 0x04, 0x00, 0xde, 0xff, 0x06, 0x00, 0xdd, 0xff, 0x07, 0x00, 0xdc, 0xff, 0x09, 0x00, 0xdc, 0xff, 0x0b, 0x00, 0xdc, 0xff, 0x0d, 0x00, 0xdc, 0xff, 0x0e, 0x00, 0xdd, 0xff, 0x0f, 0x00, 0xde, 0xff, 0x0f, 0x00, 0xe0, 0xff, 0x0e, 0x00, 0xe1, 0xff, 0x0e, 0x00, 0xe3, 0xff, 0x0e, 0x00, 0xe5, 0xff, 0x0e, 0x00, 0xe6, 0xff, 0x0e, 0x00, 0xe7, 0xff, 0x0d, 0x00, 0xe8, 0xff, 0x0c, 0x00, 0xea, 0xff, 0x0c, 0x00, 0xeb, 0xff, 0x0b, 0x00, 0xed, 0xff, 0x0b, 0x00, 0xef, 0xff, 0x0b, 0x00, 0xf1, 0xff, 0x0c, 0x00, 0xf2, 0xff, 0x0d, 0x00, 0xf3, 0xff, 0x0d, 0x00, 0xf4, 0xff, 0x0d, 0x00, 0xf4, 0xff, 0x0d, 0x00, 0xf5, 0xff, 0x0d, 0x00, 0xf7, 0xff, 0x0d, 0x00, 0xf8, 0xff, 0x0e, 0x00, 0xfa, 0xff, 0x10, 0x00, 0xfb, 0xff, 0x11, 0x00, 0xfc, 0xff, 0x12, 0x00, 0xfd, 0xff, 0x12, 0x00, 0xfe, 0xff, 0x11, 0x00, 0xff, 0xff, 0x10, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x0f, 0x00, 0x09, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x0d, 0x00, 0x0f, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x11, 0x00, 0x0a, 0x00, 0x13, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x0a, 0x00, 0x16, 0x00, 0x0a, 0x00, 0x17, 0x00, 0x09, 0x00, 0x18, 0x00, 0x08, 0x00, 0x18, 0x00, 0x06, 0x00, 0x18, 0x00, 0x04, 0x00, 0x17, 0x00, 0x02, 0x00, 0x16, 0x00, 0x01, 0x00, 0x15, 0x00, 0x00, 0x00, 0x14, 0x00, 0xff, 0xff, 0x14, 0x00, 0xfe, 0xff, 0x13, 0x00, 0xfd, 0xff, 0x13, 0x00, 0xfb, 0xff, 0x13, 0x00, 0xf9, 0xff, 0x12, 0x00, 0xf8, 0xff, 0x11, 0x00, 0xf6, 0xff, 0x0f, 0x00, 0xf5, 0xff, 0x0e, 0x00, 0xf5, 0xff, 0x0c, 0x00, 0xf4, 0xff, 0x0b, 0x00, 0xf4, 0xff, 0x0b, 0x00, 0xf4, 0xff, 0x0a, 0x00, 0xf5, 0xff, 0x09, 0x00, 0xf5, 0xff, 0x08, 0x00, 0xf6, 0xff, 0x06, 0x00, 0xf6, 0xff, 0x04, 0x00, 0xf6, 0xff, 0x02, 0x00, 0xf6, 0xff, 0x01, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf7, 0xff, 0x03, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf4, 0xff, 0x05, 0x00, 0xf3, 0xff, 0x06, 0x00, 0xf3, 0xff, 0x08, 0x00, 0xf3, 0xff, 0x0a, 0x00, 0xf3, 0xff, 0x0b, 0x00, 0xf3, 0xff, 0x0c, 0x00, 0xf4, 0xff, 0x0c, 0x00, 0xf4, 0xff, 0x0b, 0x00, 0xf5, 0xff, 0x0b, 0x00, 0xf7, 0xff, 0x0a, 0x00, 0xf9, 0xff, 0x0a, 0x00, 0xfb, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x0b, 0x00, 0xff, 0xff, 0x0c, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0b, 0x00, 0x0e, 0x00, 0x0c, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x10, 0x00, 0x0d, 0x00, 0x11, 0x00, 0x0b, 0x00, 0x11, 0x00, 0x08, 0x00, 0x11, 0x00, 0x05, 0x00, 0x11, 0x00, 0x03, 0x00, 0x10, 0x00, 0x03, 0x00, 0x10, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x10, 0x00, 0x04, 0x00, 0x10, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0xfe, 0xff, 0x10, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xfb, 0xff, 0x0f, 0x00, 0xfb, 0xff, 0x0f, 0x00, 0xfb, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0xfd, 0xff, 0x0d, 0x00, 0xfb, 0xff, 0x0c, 0x00, 0xf9, 0xff, 0x09, 0x00, 0xf6, 0xff, 0x07, 0x00, 0xf4, 0xff, 0x06, 0x00, 0xf2, 0xff, 0x04, 0x00, 0xf0, 0xff, 0x02, 0x00, 0xef, 0xff, 0x00, 0x00, 0xef, 0xff, 0xfd, 0xff, 0xef, 0xff, 0xfb, 0xff, 0xee, 0xff, 0xf9, 0xff, 0xec, 0xff, 0xf7, 0xff, 0xeb, 0xff, 0xf6, 0xff, 0xe9, 0xff, 0xf4, 0xff, 0xe8, 0xff, 0xf4, 0xff, 0xe7, 0xff, 0xf3, 0xff, 0xe7, 0xff, 0xf2, 0xff, 0xe7, 0xff, 0xf0, 0xff, 0xe8, 0xff, 0xef, 0xff, 0xe9, 0xff, 0xee, 0xff, 0xea, 0xff, 0xee, 0xff, 0xeb, 0xff, 0xee, 0xff, 0xeb, 0xff, 0xee, 0xff, 0xec, 0xff, 0xee, 0xff, 0xec, 0xff, 0xee, 0xff, 0xed, 0xff, 0xee, 0xff, 0xed, 0xff, 0xee, 0xff, 0xee, 0xff, 0xee, 0xff, 0xee, 0xff, 0xee, 0xff, 0xef, 0xff, 0xef, 0xff, 0xf0, 0xff, 0xf0, 0xff, 0xf1, 0xff, 0xf1, 0xff, 0xf3, 0xff, 0xf2, 0xff, 0xf4, 0xff, 0xf3, 0xff, 0xf6, 0xff, 0xf5, 0xff, 0xf6, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x03, 0x00, 0x06, 0x00, 0x03, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x09, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x0d, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x0e, 0x00, 0x08, 0x00, 0x10, 0x00, 0x07, 0x00, 0x11, 0x00, 0x07, 0x00, 0x13, 0x00, 0x07, 0x00, 0x15, 0x00, 0x08, 0x00, 0x15, 0x00, 0x08, 0x00, 0x15, 0x00, 0x07, 0x00, 0x14, 0x00, 0x05, 0x00, 0x14, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0xfe, 0xff, 0x12, 0x00, 0xfd, 0xff, 0x11, 0x00, 0xfd, 0xff, 0x10, 0x00, 0xfe, 0xff, 0x0e, 0x00, 0xff, 0xff, 0x0d, 0x00, 0xff, 0xff, 0x0c, 0x00, 0xfe, 0xff, 0x0b, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xfa, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf4, 0xff, 0xfe, 0xff, 0xf2, 0xff, 0xfd, 0xff, 0xf0, 0xff, 0xfd, 0xff, 0xee, 0xff, 0xfd, 0xff, 0xed, 0xff, 0xfd, 0xff, 0xec, 0xff, 0xfe, 0xff, 0xec, 0xff, 0xff, 0xff, 0xeb, 0xff, 0xff, 0xff, 0xea, 0xff, 0x00, 0x00, 0xe9, 0xff, 0x00, 0x00, 0xe8, 0xff, 0xff, 0xff, 0xe8, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xfe, 0xff, 0xeb, 0xff, 0xfe, 0xff, 0xec, 0xff, 0xfd, 0xff, 0xee, 0xff, 0xfd, 0xff, 0xee, 0xff, 0xfe, 0xff, 0xee, 0xff, 0xfe, 0xff, 0xee, 0xff, 0xfe, 0xff, 0xee, 0xff, 0xfe, 0xff, 0xee, 0xff, 0xfe, 0xff, 0xef, 0xff, 0xfe, 0xff, 0xf0, 0xff, 0xfe, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xf2, 0xff, 0x00, 0x00, 0xf2, 0xff, 0x01, 0x00, 0xf2, 0xff, 0x02, 0x00, 0xf2, 0xff, 0x04, 0x00, 0xf3, 0xff, 0x05, 0x00, 0xf4, 0xff, 0x06, 0x00, 0xf6, 0xff, 0x07, 0x00, 0xf8, 0xff, 0x09, 0x00, 0xf9, 0xff, 0x0a, 0x00, 0xfa, 0xff, 0x0a, 0x00, 0xfb, 0xff, 0x0b, 0x00, 0xfc, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0d, 0x00, 0xff, 0xff, 0x0e, 0x00, 0x01, 0x00, 0x10, 0x00, 0x04, 0x00, 0x11, 0x00, 0x06, 0x00, 0x12, 0x00, 0x09, 0x00, 0x12, 0x00, 0x0a, 0x00, 0x12, 0x00, 0x0c, 0x00, 0x11, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x11, 0x00, 0x0e, 0x00, 0x11, 0x00, 0x0e, 0x00, 0x12, 0x00, 0x0e, 0x00, 0x12, 0x00, 0x0d, 0x00, 0x13, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x08, 0x00, 0x14, 0x00, 0x05, 0x00, 0x13, 0x00, 0x04, 0x00, 0x12, 0x00, 0x02, 0x00, 0x11, 0x00, 0x01, 0x00, 0x10, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xff, 0xff, 0x0d, 0x00, 0xfe, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xf9, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xf6, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xf7, 0xff, 0xf3, 0xff, 0xf5, 0xff, 0xf2, 0xff, 0xf4, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf2, 0xff, 0xf2, 0xff, 0xf0, 0xff, 0xf1, 0xff, 0xef, 0xff, 0xf0, 0xff, 0xed, 0xff, 0xee, 0xff, 0xed, 0xff, 0xed, 0xff, 0xed, 0xff, 0xec, 0xff, 0xee, 0xff, 0xeb, 0xff, 0xef, 0xff, 0xeb, 0xff, 0xf0, 0xff, 0xeb, 0xff, 0xf2, 0xff, 0xeb, 0xff, 0xf3, 0xff, 0xeb, 0xff, 0xf3, 0xff, 0xeb, 0xff, 0xf4, 0xff, 0xeb, 0xff, 0xf4, 0xff, 0xea, 0xff, 0xf5, 0xff, 0xe9, 0xff, 0xf7, 0xff, 0xe9, 0xff, 0xf9, 0xff, 0xe9, 0xff, 0xfb, 0xff, 0xeb, 0xff, 0xfd, 0xff, 0xed, 0xff, 0xff, 0xff, 0xef, 0xff, 0x02, 0x00, 0xf1, 0xff, 0x04, 0x00, 0xf2, 0xff, 0x05, 0x00, 0xf3, 0xff, 0x06, 0x00, 0xf3, 0xff, 0x07, 0x00, 0xf4, 0xff, 0x08, 0x00, 0xf6, 0xff, 0x0a, 0x00, 0xf9, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0d, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x03, 0x00, 0x11, 0x00, 0x04, 0x00, 0x12, 0x00, 0x05, 0x00, 0x13, 0x00, 0x05, 0x00, 0x13, 0x00, 0x05, 0x00, 0x13, 0x00, 0x06, 0x00, 0x13, 0x00, 0x08, 0x00, 0x13, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x0d, 0x00, 0x12, 0x00, 0x0f, 0x00, 0x12, 0x00, 0x0f, 0x00, 0x12, 0x00, 0x0e, 0x00, 0x11, 0x00, 0x0d, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x0e, 0x00, 0x0d, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x09, 0x00, 0x11, 0x00, 0x08, 0x00, 0x12, 0x00, 0x06, 0x00, 0x11, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xff, 0xff, 0x0e, 0x00, 0xfd, 0xff, 0x0d, 0x00, 0xfc, 0xff, 0x0b, 0x00, 0xfb, 0xff, 0x09, 0x00, 0xfa, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf7, 0xff, 0x03, 0x00, 0xf6, 0xff, 0x02, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf4, 0xff, 0x01, 0x00, 0xf2, 0xff, 0x00, 0x00, 0xf1, 0xff, 0xff, 0xff, 0xef, 0xff, 0xfd, 0xff, 0xef, 0xff, 0xfc, 0xff, 0xee, 0xff, 0xfb, 0xff, 0xee, 0xff, 0xfb, 0xff, 0xee, 0xff, 0xfb, 0xff, 0xee, 0xff, 0xfc, 0xff, 0xee, 0xff, 0xfc, 0xff, 0xee, 0xff, 0xfc, 0xff, 0xee, 0xff, 0xfd, 0xff, 0xef, 0xff, 0xfd, 0xff, 0xf0, 0xff, 0xfd, 0xff, 0xf0, 0xff, 0xfe, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xf2, 0xff, 0x00, 0x00, 0xf2, 0xff, 0x02, 0x00, 0xf2, 0xff, 0x03, 0x00, 0xf2, 0xff, 0x03, 0x00, 0xf2, 0xff, 0x03, 0x00, 0xf2, 0xff, 0x02, 0x00, 0xf4, 0xff, 0x02, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf7, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x02, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x07, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x10, 0x00, 0x08, 0x00, 0x13, 0x00, 0x09, 0x00, 0x15, 0x00, 0x0a, 0x00, 0x16, 0x00, 0x0b, 0x00, 0x16, 0x00, 0x0b, 0x00, 0x16, 0x00, 0x0b, 0x00, 0x16, 0x00, 0x0a, 0x00, 0x16, 0x00, 0x09, 0x00, 0x17, 0x00, 0x08, 0x00, 0x18, 0x00, 0x07, 0x00, 0x18, 0x00, 0x08, 0x00, 0x19, 0x00, 0x09, 0x00, 0x19, 0x00, 0x09, 0x00, 0x17, 0x00, 0x09, 0x00, 0x16, 0x00, 0x08, 0x00, 0x14, 0x00, 0x07, 0x00, 0x13, 0x00, 0x06, 0x00, 0x12, 0x00, 0x05, 0x00, 0x10, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x06, 0x00, 0x06, 0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf6, 0xff, 0xff, 0xff, 0xf4, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfb, 0xff, 0xf2, 0xff, 0xf9, 0xff, 0xf1, 0xff, 0xf6, 0xff, 0xf1, 0xff, 0xf4, 0xff, 0xf0, 0xff, 0xf3, 0xff, 0xef, 0xff, 0xf2, 0xff, 0xee, 0xff, 0xf1, 0xff, 0xed, 0xff, 0xf1, 0xff, 0xec, 0xff, 0xf0, 0xff, 0xec, 0xff, 0xef, 0xff, 0xeb, 0xff, 0xee, 0xff, 0xec, 0xff, 0xee, 0xff, 0xec, 0xff, 0xee, 0xff, 0xec, 0xff, 0xed, 0xff, 0xeb, 0xff, 0xed, 0xff, 0xea, 0xff, 0xee, 0xff, 0xe9, 0xff, 0xef, 0xff, 0xe8, 0xff, 0xf1, 0xff, 0xe8, 0xff, 0xf3, 0xff, 0xe9, 0xff, 0xf4, 0xff, 0xea, 0xff, 0xf5, 0xff, 0xec, 0xff, 0xf6, 0xff, 0xee, 0xff, 0xf6, 0xff, 0xf0, 0xff, 0xf7, 0xff, 0xf1, 0xff, 0xf8, 0xff, 0xf2, 0xff, 0xfa, 0xff, 0xf3, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf7, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x09, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x13, 0x00, 0xff, 0xff, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x02, 0x00, 0x17, 0x00, 0x03, 0x00, 0x18, 0x00, 0x04, 0x00, 0x19, 0x00, 0x05, 0x00, 0x1b, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x06, 0x00, 0x1e, 0x00, 0x07, 0x00, 0x1f, 0x00, 0x07, 0x00, 0x1f, 0x00, 0x08, 0x00, 0x1f, 0x00, 0x09, 0x00, 0x1e, 0x00, 0x0a, 0x00, 0x1d, 0x00, 0x0b, 0x00, 0x1c, 0x00, 0x0d, 0x00, 0x1b, 0x00, 0x0e, 0x00, 0x1a, 0x00, 0x0e, 0x00, 0x19, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x0d, 0x00, 0x17, 0x00, 0x0c, 0x00, 0x16, 0x00, 0x0c, 0x00, 0x15, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x0b, 0x00, 0x12, 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x0d, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x09, 0x00, 0x01, 0x00, 0x07, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf6, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xfe, 0xff, 0xf5, 0xff, 0xfd, 0xff, 0xf5, 0xff, 0xfc, 0xff, 0xf5, 0xff, 0xfb, 0xff, 0xf5, 0xff, 0xfa, 0xff, 0xf5, 0xff, 0xf9, 0xff, 0xf6, 0xff, 0xf9, 0xff, 0xf7, 0xff, 0xf9, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf9, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x06, 0x00, 0x04, 0x00, 0x07, 0x00, 0x06, 0x00, 0x08, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x11, 0x00, 0x0a, 0x00, 0x11, 0x00, 0x08, 0x00, 0x12, 0x00, 0x07, 0x00, 0x12, 0x00, 0x06, 0x00, 0x12, 0x00, 0x06, 0x00, 0x12, 0x00, 0x05, 0x00, 0x11, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0xff, 0xff, 0x0b, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf7, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xf6, 0xff, 0xfb, 0xff, 0xf5, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xf9, 0xff, 0xf2, 0xff, 0xf8, 0xff, 0xf1, 0xff, 0xf8, 0xff, 0xf1, 0xff, 0xf7, 0xff, 0xf1, 0xff, 0xf7, 0xff, 0xf1, 0xff, 0xf6, 0xff, 0xf1, 0xff, 0xf5, 0xff, 0xf0, 0xff, 0xf4, 0xff, 0xf0, 0xff, 0xf3, 0xff, 0xef, 0xff, 0xf1, 0xff, 0xee, 0xff, 0xf0, 0xff, 0xee, 0xff, 0xf0, 0xff, 0xee, 0xff, 0xf0, 0xff, 0xef, 0xff, 0xf1, 0xff, 0xef, 0xff, 0xf3, 0xff, 0xef, 0xff, 0xf4, 0xff, 0xef, 0xff, 0xf5, 0xff, 0xef, 0xff, 0xf5, 0xff, 0xef, 0xff, 0xf5, 0xff, 0xef, 0xff, 0xf5, 0xff, 0xef, 0xff, 0xf5, 0xff, 0xef, 0xff, 0xf6, 0xff, 0xf0, 0xff, 0xf7, 0xff, 0xf1, 0xff, 0xf8, 0xff, 0xf1, 0xff, 0xfa, 0xff, 0xf2, 0xff, 0xfb, 0xff, 0xf2, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf4, 0xff, 0xfd, 0xff, 0xf5, 0xff, 0xfe, 0xff, 0xf5, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x07, 0x00, 0x05, 0x00, 0x09, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf7, 0xff, 0x03, 0x00, 0xf6, 0xff, 0x05, 0x00, 0xf5, 0xff, 0x06, 0x00, 0xf3, 0xff, 0x07, 0x00, 0xf2, 0xff, 0x07, 0x00, 0xef, 0xff, 0x06, 0x00, 0xed, 0xff, 0x06, 0x00, 0xec, 0xff, 0x06, 0x00, 0xeb, 0xff, 0x06, 0x00, 0xeb, 0xff, 0x07, 0x00, 0xec, 0xff, 0x08, 0x00, 0xed, 0xff, 0x08, 0x00, 0xee, 0xff, 0x08, 0x00, 0xef, 0xff, 0x08, 0x00, 0xef, 0xff, 0x07, 0x00, 0xee, 0xff, 0x06, 0x00, 0xee, 0xff, 0x05, 0x00, 0xee, 0xff, 0x04, 0x00, 0xf0, 0xff, 0x04, 0x00, 0xf2, 0xff, 0x04, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x07, 0x00, 0x07, 0x00, 0x08, 0x00, 0x06, 0x00, 0x08, 0x00, 0x05, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x09, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0xfe, 0xff, 0x10, 0x00, 0xfc, 0xff, 0x11, 0x00, 0xfb, 0xff, 0x11, 0x00, 0xfb, 0xff, 0x10, 0x00, 0xfb, 0xff, 0x10, 0x00, 0xfb, 0xff, 0x10, 0x00, 0xfb, 0xff, 0x11, 0x00, 0xfa, 0xff, 0x12, 0x00, 0xf9, 0xff, 0x13, 0x00, 0xf8, 0xff, 0x14, 0x00, 0xf7, 0xff, 0x13, 0x00, 0xf7, 0xff, 0x12, 0x00, 0xf8, 0xff, 0x10, 0x00, 0xf9, 0xff, 0x0f, 0x00, 0xfa, 0xff, 0x0e, 0x00, 0xfb, 0xff, 0x0d, 0x00, 0xfb, 0xff, 0x0d, 0x00, 0xfc, 0xff, 0x0d, 0x00, 0xfc, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf6, 0xff, 0xfd, 0xff, 0xf5, 0xff, 0xfc, 0xff, 0xf4, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0xfd, 0xff, 0xf2, 0xff, 0xfd, 0xff, 0xf2, 0xff, 0xfc, 0xff, 0xf1, 0xff, 0xfb, 0xff, 0xf1, 0xff, 0xfb, 0xff, 0xf1, 0xff, 0xfa, 0xff, 0xf1, 0xff, 0xfb, 0xff, 0xf1, 0xff, 0xfb, 0xff, 0xf2, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfe, 0xff, 0xf5, 0xff, 0xff, 0xff, 0xf6, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0x01, 0x00, 0x07, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x00, 0x09, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x09, 0x00, 0x03, 0x00, 0x07, 0x00, 0x02, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x06, 0x00, 0x03, 0x00, 0x06, 0x00, 0x02, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x05, 0x00, 0x04, 0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x04, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf6, 0xff, 0x06, 0x00, 0xf3, 0xff, 0x07, 0x00, 0xf2, 0xff, 0x07, 0x00, 0xf2, 0xff, 0x07, 0x00, 0xf2, 0xff, 0x07, 0x00, 0xf2, 0xff, 0x07, 0x00, 0xf1, 0xff, 0x07, 0x00, 0xf0, 0xff, 0x07, 0x00, 0xef, 0xff, 0x08, 0x00, 0xef, 0xff, 0x08, 0x00, 0xee, 0xff, 0x09, 0x00, 0xef, 0xff, 0x0a, 0x00, 0xf0, 0xff, 0x0b, 0x00, 0xf2, 0xff, 0x0c, 0x00, 0xf4, 0xff, 0x0c, 0x00, 0xf6, 0xff, 0x0b, 0x00, 0xf7, 0xff, 0x0a, 0x00, 0xf9, 0xff, 0x09, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x08, 0x00, 0xf7, 0xff, 0x09, 0x00, 0xf7, 0xff, 0x0b, 0x00, 0xf6, 0xff, 0x0c, 0x00, 0xf6, 0xff, 0x0d, 0x00, 0xf6, 0xff, 0x0d, 0x00, 0xf7, 0xff, 0x0d, 0x00, 0xf7, 0xff, 0x0d, 0x00, 0xf8, 0xff, 0x0e, 0x00, 0xf9, 0xff, 0x0e, 0x00, 0xfa, 0xff, 0x0f, 0x00, 0xfb, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xfd, 0xff, 0x10, 0x00, 0xfd, 0xff, 0x10, 0x00, 0xfd, 0xff, 0x11, 0x00, 0xfd, 0xff, 0x11, 0x00, 0xfd, 0xff, 0x11, 0x00, 0xfd, 0xff, 0x11, 0x00, 0xfe, 0xff, 0x11, 0x00, 0xfe, 0xff, 0x10, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xfd, 0xff, 0x0e, 0x00, 0xfd, 0xff, 0x0e, 0x00, 0xfe, 0xff, 0x0d, 0x00, 0xff, 0xff, 0x0d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x05, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x08, 0x00, 0x06, 0x00, 0x09, 0x00, 0x05, 0x00, 0x09, 0x00, 0x04, 0x00, 0x09, 0x00, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0xff, 0xff, 0x0a, 0x00, 0xff, 0xff, 0x0a, 0x00, 0xfe, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfa, 0xff, 0x09, 0x00, 0xf9, 0xff, 0x08, 0x00, 0xf7, 0xff, 0x08, 0x00, 0xf7, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x07, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfa, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf7, 0xff, 0x03, 0x00, 0xf6, 0xff, 0x04, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf5, 0xff, 0x05, 0x00, 0xf4, 0xff, 0x05, 0x00, 0xf4, 0xff, 0x05, 0x00, 0xf3, 0xff, 0x06, 0x00, 0xf1, 0xff, 0x06, 0x00, 0xf0, 0xff, 0x06, 0x00, 0xef, 0xff, 0x06, 0x00, 0xee, 0xff, 0x06, 0x00, 0xed, 0xff, 0x05, 0x00, 0xed, 0xff, 0x04, 0x00, 0xed, 0xff, 0x04, 0x00, 0xec, 0xff, 0x03, 0x00, 0xeb, 0xff, 0x03, 0x00, 0xea, 0xff, 0x03, 0x00, 0xe9, 0xff, 0x03, 0x00, 0xe8, 0xff, 0x02, 0x00, 0xe8, 0xff, 0x02, 0x00, 0xe8, 0xff, 0x00, 0x00, 0xe9, 0xff, 0xff, 0xff, 0xeb, 0xff, 0xfd, 0xff, 0xed, 0xff, 0xfc, 0xff, 0xef, 0xff, 0xfb, 0xff, 0xf0, 0xff, 0xfb, 0xff, 0xf1, 0xff, 0xfa, 0xff, 0xf2, 0xff, 0xfa, 0xff, 0xf3, 0xff, 0xfa, 0xff, 0xf5, 0xff, 0xf9, 0xff, 0xf7, 0xff, 0xf8, 0xff, 0xf9, 0xff, 0xf7, 0xff, 0xfb, 0xff, 0xf5, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xf1, 0xff, 0x01, 0x00, 0xf0, 0xff, 0x02, 0x00, 0xf0, 0xff, 0x04, 0x00, 0xef, 0xff, 0x05, 0x00, 0xef, 0xff, 0x05, 0x00, 0xf0, 0xff, 0x05, 0x00, 0xef, 0xff, 0x06, 0x00, 0xef, 0xff, 0x06, 0x00, 0xed, 0xff, 0x08, 0x00, 0xec, 0xff, 0x09, 0x00, 0xea, 0xff, 0x0b, 0x00, 0xea, 0xff, 0x0c, 0x00, 0xe9, 0xff, 0x0d, 0x00, 0xe9, 0xff, 0x0d, 0x00, 0xe9, 0xff, 0x0d, 0x00, 0xe9, 0xff, 0x0c, 0x00, 0xe9, 0xff, 0x0c, 0x00, 0xe9, 0xff, 0x0d, 0x00, 0xe9, 0xff, 0x0e, 0x00, 0xe9, 0xff, 0x0f, 0x00, 0xe9, 0xff, 0x10, 0x00, 0xe9, 0xff, 0x11, 0x00, 0xe9, 0xff, 0x10, 0x00, 0xea, 0xff, 0x10, 0x00, 0xeb, 0xff, 0x0f, 0x00, 0xec, 0xff, 0x0f, 0x00, 0xed, 0xff, 0x0f, 0x00, 0xee, 0xff, 0x10, 0x00, 0xf0, 0xff, 0x10, 0x00, 0xf1, 0xff, 0x10, 0x00, 0xf1, 0xff, 0x10, 0x00, 0xf2, 0xff, 0x10, 0x00, 0xf3, 0xff, 0x10, 0x00, 0xf4, 0xff, 0x10, 0x00, 0xf6, 0xff, 0x0f, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0xfb, 0xff, 0x0e, 0x00, 0xfd, 0xff, 0x0d, 0x00, 0xff, 0xff, 0x0d, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x09, 0x00, 0x09, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x02, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xff, 0xff, 0x0f, 0x00, 0xfe, 0xff, 0x11, 0x00, 0xfc, 0xff, 0x12, 0x00, 0xfb, 0xff, 0x13, 0x00, 0xfa, 0xff, 0x12, 0x00, 0xfa, 0xff, 0x11, 0x00, 0xfa, 0xff, 0x10, 0x00, 0xfa, 0xff, 0x0f, 0x00, 0xfb, 0xff, 0x0e, 0x00, 0xfb, 0xff, 0x0f, 0x00, 0xfb, 0xff, 0x10, 0x00, 0xfb, 0xff, 0x12, 0x00, 0xfa, 0xff, 0x13, 0x00, 0xf9, 0xff, 0x12, 0x00, 0xf8, 0xff, 0x10, 0x00, 0xf8, 0xff, 0x0e, 0x00, 0xf8, 0xff, 0x0c, 0x00, 0xfa, 0xff, 0x0b, 0x00, 0xfb, 0xff, 0x0b, 0x00, 0xfc, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf6, 0xff, 0x01, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf4, 0xff, 0x03, 0x00, 0xf4, 0xff, 0x04, 0x00, 0xf3, 0xff, 0x04, 0x00, 0xf2, 0xff, 0x04, 0x00, 0xf1, 0xff, 0x04, 0x00, 0xf0, 0xff, 0x04, 0x00, 0xf0, 0xff, 0x05, 0x00, 0xef, 0xff, 0x06, 0x00, 0xef, 0xff, 0x07, 0x00, 0xf0, 0xff, 0x07, 0x00, 0xf0, 0xff, 0x07, 0x00, 0xf1, 0xff, 0x06, 0x00, 0xf2, 0xff, 0x05, 0x00, 0xf2, 0xff, 0x03, 0x00, 0xf3, 0xff, 0x02, 0x00, 0xf3, 0xff, 0x01, 0x00, 0xf4, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf9, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x0a, 0x00, 0xff, 0xff, 0x0a, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x09, 0x00, 0x06, 0x00, 0x09, 0x00, 0x06, 0x00, 0x09, 0x00, 0x06, 0x00, 0x08, 0x00, 0x06, 0x00, 0x08, 0x00, 0x06, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x07, 0x00, 0x06, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x02, 0x00, 0x10, 0x00, 0x01, 0x00, 0x11, 0x00, 0x01, 0x00, 0x12, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00, 0x15, 0x00, 0x02, 0x00, 0x16, 0x00, 0x02, 0x00, 0x16, 0x00, 0x01, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13, 0x00, 0xff, 0xff, 0x12, 0x00, 0xfe, 0xff, 0x11, 0x00, 0xfe, 0xff, 0x10, 0x00, 0xfe, 0xff, 0x10, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xfe, 0xff, 0x0d, 0x00, 0xfe, 0xff, 0x0b, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf5, 0xff, 0xff, 0xff, 0xf5, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x00, 0x00, 0xf4, 0xff, 0x00, 0x00, 0xf4, 0xff, 0x00, 0x00, 0xf4, 0xff, 0xff, 0xff, 0xf4, 0xff, 0xff, 0xff, 0xf4, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf6, 0xff, 0x02, 0x00, 0xf7, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf7, 0xff, 0x04, 0x00, 0xf7, 0xff, 0x05, 0x00, 0xf6, 0xff, 0x05, 0x00, 0xf7, 0xff, 0x05, 0x00, 0xf7, 0xff, 0x05, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x07, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf5, 0xff, 0xfd, 0xff, 0xf4, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf2, 0xff, 0xfc, 0xff, 0xf1, 0xff, 0xfc, 0xff, 0xf1, 0xff, 0xfc, 0xff, 0xf1, 0xff, 0xfb, 0xff, 0xf1, 0xff, 0xfb, 0xff, 0xf0, 0xff, 0xfa, 0xff, 0xee, 0xff, 0xfa, 0xff, 0xed, 0xff, 0xfa, 0xff, 0xed, 0xff, 0xfb, 0xff, 0xed, 0xff, 0xfb, 0xff, 0xee, 0xff, 0xfb, 0xff, 0xef, 0xff, 0xfc, 0xff, 0xf0, 0xff, 0xfc, 0xff, 0xf1, 0xff, 0xfc, 0xff, 0xf1, 0xff, 0xfc, 0xff, 0xf1, 0xff, 0xfd, 0xff, 0xf1, 0xff, 0xfd, 0xff, 0xf2, 0xff, 0xfe, 0xff, 0xf4, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x05, 0x00, 0x10, 0x00, 0x05, 0x00, 0x11, 0x00, 0x04, 0x00, 0x12, 0x00, 0x03, 0x00, 0x12, 0x00, 0x02, 0x00, 0x11, 0x00, 0x01, 0x00, 0x11, 0x00, 0x02, 0x00, 0x11, 0x00, 0x03, 0x00, 0x11, 0x00, 0x04, 0x00, 0x11, 0x00, 0x05, 0x00, 0x10, 0x00, 0x06, 0x00, 0x10, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x05, 0x00, 0x10, 0x00, 0x06, 0x00, 0x10, 0x00, 0x07, 0x00, 0x10, 0x00, 0x07, 0x00, 0x10, 0x00, 0x07, 0x00, 0x10, 0x00, 0x07, 0x00, 0x10, 0x00, 0x07, 0x00, 0x10, 0x00, 0x05, 0x00, 0x11, 0x00, 0x04, 0x00, 0x11, 0x00, 0x04, 0x00, 0x10, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x09, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0xfb, 0xff, 0xf6, 0xff, 0xf9, 0xff, 0xf6, 0xff, 0xf8, 0xff, 0xf6, 0xff, 0xf7, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xf7, 0xff, 0xf5, 0xff, 0xf7, 0xff, 0xf4, 0xff, 0xf7, 0xff, 0xf3, 0xff, 0xf7, 0xff, 0xf2, 0xff, 0xf6, 0xff, 0xf2, 0xff, 0xf7, 0xff, 0xf2, 0xff, 0xf7, 0xff, 0xf3, 0xff, 0xf8, 0xff, 0xf3, 0xff, 0xf9, 0xff, 0xf4, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xf9, 0xff, 0xf5, 0xff, 0xf9, 0xff, 0xf7, 0xff, 0xf9, 0xff, 0xf8, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xff, 0xff, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x10, 0x00, 0x06, 0x00, 0x10, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x0f, 0x00, 0x09, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x09, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x10, 0x00, 0x04, 0x00, 0x10, 0x00, 0x02, 0x00, 0x10, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0xff, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x0b, 0x00, 0xfb, 0xff, 0x0a, 0x00, 0xf9, 0xff, 0x0a, 0x00, 0xf8, 0xff, 0x08, 0x00, 0xf7, 0xff, 0x06, 0x00, 0xf7, 0xff, 0x03, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xf6, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xf9, 0xff, 0xf3, 0xff, 0xf8, 0xff, 0xf1, 0xff, 0xf7, 0xff, 0xf0, 0xff, 0xf7, 0xff, 0xed, 0xff, 0xf7, 0xff, 0xeb, 0xff, 0xf8, 0xff, 0xe9, 0xff, 0xf9, 0xff, 0xe8, 0xff, 0xfa, 0xff, 0xe7, 0xff, 0xfb, 0xff, 0xe7, 0xff, 0xfb, 0xff, 0xe7, 0xff, 0xfa, 0xff, 0xe7, 0xff, 0xf9, 0xff, 0xe7, 0xff, 0xf9, 0xff, 0xe8, 0xff, 0xf9, 0xff, 0xe8, 0xff, 0xf9, 0xff, 0xe8, 0xff, 0xfa, 0xff, 0xe9, 0xff, 0xfb, 0xff, 0xea, 0xff, 0xfd, 0xff, 0xeb, 0xff, 0xfe, 0xff, 0xec, 0xff, 0xfe, 0xff, 0xed, 0xff, 0xfe, 0xff, 0xee, 0xff, 0xfd, 0xff, 0xef, 0xff, 0xfd, 0xff, 0xef, 0xff, 0xfd, 0xff, 0xf0, 0xff, 0xfe, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xf2, 0xff, 0x01, 0x00, 0xf4, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf7, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x08, 0x00, 0xf9, 0xff, 0x0a, 0x00, 0xfa, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x0b, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x09, 0x00, 0x11, 0x00, 0x09, 0x00, 0x11, 0x00, 0x0a, 0x00, 0x12, 0x00, 0x0a, 0x00, 0x13, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x09, 0x00, 0x15, 0x00, 0x09, 0x00, 0x16, 0x00, 0x08, 0x00, 0x17, 0x00, 0x07, 0x00, 0x16, 0x00, 0x06, 0x00, 0x15, 0x00, 0x06, 0x00, 0x14, 0x00, 0x06, 0x00, 0x12, 0x00, 0x06, 0x00, 0x10, 0x00, 0x06, 0x00, 0x0f, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xfd, 0xff, 0xf6, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x09, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x09, 0x00, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x06, 0x00, 0x08, 0x00, 0x05, 0x00, 0x08, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, 0x08, 0x00, 0x07, 0x00, 0x08, 0x00, 0x07, 0x00, 0x08, 0x00, 0x07, 0x00, 0x09, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x0d, 0x00, 0xff, 0xff, 0x0e, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0f, 0x00, 0xfb, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0e, 0x00, 0xfe, 0xff, 0x0b, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf9, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf5, 0xff, 0xfb, 0xff, 0xf4, 0xff, 0xfa, 0xff, 0xf3, 0xff, 0xf8, 0xff, 0xf3, 0xff, 0xf6, 0xff, 0xf3, 0xff, 0xf5, 0xff, 0xf2, 0xff, 0xf4, 0xff, 0xf1, 0xff, 0xf5, 0xff, 0xef, 0xff, 0xf5, 0xff, 0xec, 0xff, 0xf5, 0xff, 0xeb, 0xff, 0xf5, 0xff, 0xea, 0xff, 0xf4, 0xff, 0xea, 0xff, 0xf2, 0xff, 0xea, 0xff, 0xf1, 0xff, 0xeb, 0xff, 0xf1, 0xff, 0xec, 0xff, 0xf2, 0xff, 0xec, 0xff, 0xf3, 0xff, 0xeb, 0xff, 0xf5, 0xff, 0xeb, 0xff, 0xf6, 0xff, 0xea, 0xff, 0xf7, 0xff, 0xea, 0xff, 0xf7, 0xff, 0xeb, 0xff, 0xf7, 0xff, 0xec, 0xff, 0xf6, 0xff, 0xed, 0xff, 0xf6, 0xff, 0xef, 0xff, 0xf7, 0xff, 0xf1, 0xff, 0xf8, 0xff, 0xf2, 0xff, 0xf9, 0xff, 0xf3, 0xff, 0xfb, 0xff, 0xf4, 0xff, 0xfc, 0xff, 0xf4, 0xff, 0xfe, 0xff, 0xf5, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x06, 0x00, 0x04, 0x00, 0x07, 0x00, 0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x10, 0x00, 0x08, 0x00, 0x14, 0x00, 0x08, 0x00, 0x18, 0x00, 0x09, 0x00, 0x1a, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x0c, 0x00, 0x1c, 0x00, 0x0d, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x1d, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x0c, 0x00, 0x21, 0x00, 0x0b, 0x00, 0x21, 0x00, 0x0b, 0x00, 0x21, 0x00, 0x0b, 0x00, 0x1f, 0x00, 0x0c, 0x00, 0x1d, 0x00, 0x0d, 0x00, 0x1b, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x0f, 0x00, 0x16, 0x00, 0x0e, 0x00, 0x15, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x0c, 0x00, 0x12, 0x00, 0x0b, 0x00, 0x11, 0x00, 0x0a, 0x00, 0x0f, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x08, 0x00, 0x09, 0x00, 0x07, 0x00, 0x08, 0x00, 0x06, 0x00, 0x07, 0x00, 0x05, 0x00, 0x06, 0x00, 0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf4, 0xff, 0x00, 0x00, 0xf2, 0xff, 0xff, 0xff, 0xf2, 0xff, 0xfe, 0xff, 0xf2, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfb, 0xff, 0xf4, 0xff, 0xf9, 0xff, 0xf3, 0xff, 0xf8, 0xff, 0xf2, 0xff, 0xf8, 0xff, 0xf1, 0xff, 0xf8, 0xff, 0xef, 0xff, 0xf8, 0xff, 0xed, 0xff, 0xf9, 0xff, 0xed, 0xff, 0xf9, 0xff, 0xed, 0xff, 0xf8, 0xff, 0xee, 0xff, 0xf7, 0xff, 0xef, 0xff, 0xf7, 0xff, 0xf1, 0xff, 0xf7, 0xff, 0xf2, 0xff, 0xf7, 0xff, 0xf3, 0xff, 0xf8, 0xff, 0xf4, 0xff, 0xf9, 0xff, 0xf4, 0xff, 0xf9, 0xff, 0xf5, 0xff, 0xfa, 0xff, 0xf7, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x0a, 0x00, 0xfe, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x0d, 0x00, 0xfb, 0xff, 0x0e, 0x00, 0xfa, 0xff, 0x0e, 0x00, 0xfa, 0xff, 0x0d, 0x00, 0xfb, 0xff, 0x0c, 0x00, 0xfb, 0xff, 0x0b, 0x00, 0xfb, 0xff, 0x0a, 0x00, 0xfb, 0xff, 0x0a, 0x00, 0xfb, 0xff, 0x0a, 0x00, 0xfa, 0xff, 0x0a, 0x00, 0xfa, 0xff, 0x09, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf3, 0xff, 0xfe, 0xff, 0xf1, 0xff, 0xfe, 0xff, 0xef, 0xff, 0xfe, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xff, 0x00, 0x00, 0xee, 0xff, 0x00, 0x00, 0xed, 0xff, 0x00, 0x00, 0xec, 0xff, 0x00, 0x00, 0xea, 0xff, 0x00, 0x00, 0xe8, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xe7, 0xff, 0x00, 0x00, 0xe8, 0xff, 0x00, 0x00, 0xe9, 0xff, 0x01, 0x00, 0xe9, 0xff, 0x01, 0x00, 0xea, 0xff, 0x01, 0x00, 0xe9, 0xff, 0x00, 0x00, 0xe8, 0xff, 0x00, 0x00, 0xe7, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xe8, 0xff, 0xff, 0xff, 0xea, 0xff, 0xff, 0xff, 0xec, 0xff, 0xff, 0xff, 0xee, 0xff, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xf0, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xf2, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x07, 0x00, 0x05, 0x00, 0x08, 0x00, 0x05, 0x00, 0x08, 0x00, 0x05, 0x00, 0x08, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x10, 0x00, 0x03, 0x00, 0x10, 0x00, 0x04, 0x00, 0x10, 0x00, 0x04, 0x00, 0x10, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x10, 0x00, 0x05, 0x00, 0x10, 0x00, 0x05, 0x00, 0x11, 0x00, 0x06, 0x00, 0x12, 0x00, 0x06, 0x00, 0x12, 0x00, 0x06, 0x00, 0x11, 0x00, 0x06, 0x00, 0x10, 0x00, 0x06, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x08, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x04, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x09, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfb, 0xff, 0x0a, 0x00, 0xfa, 0xff, 0x0a, 0x00, 0xf9, 0xff, 0x0b, 0x00, 0xf8, 0xff, 0x0b, 0x00, 0xf8, 0xff, 0x0c, 0x00, 0xf8, 0xff, 0x0d, 0x00, 0xf9, 0xff, 0x0e, 0x00, 0xfa, 0xff, 0x0e, 0x00, 0xfb, 0xff, 0x0d, 0x00, 0xfc, 0xff, 0x0d, 0x00, 0xfc, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x0d, 0x00, 0xfd, 0xff, 0x0e, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x10, 0x00, 0x02, 0x00, 0x0f, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x05, 0x00, 0x10, 0x00, 0x05, 0x00, 0x10, 0x00, 0x05, 0x00, 0x10, 0x00, 0x06, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x09, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x06, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x07, 0x00, 0xf5, 0xff, 0x06, 0x00, 0xf3, 0xff, 0x05, 0x00, 0xf2, 0xff, 0x04, 0x00, 0xf1, 0xff, 0x03, 0x00, 0xf1, 0xff, 0x02, 0x00, 0xf0, 0xff, 0x01, 0x00, 0xef, 0xff, 0xff, 0xff, 0xee, 0xff, 0xfe, 0xff, 0xed, 0xff, 0xfd, 0xff, 0xed, 0xff, 0xfc, 0xff, 0xed, 0xff, 0xfb, 0xff, 0xed, 0xff, 0xfa, 0xff, 0xef, 0xff, 0xf9, 0xff, 0xf0, 0xff, 0xf7, 0xff, 0xf2, 0xff, 0xf6, 0xff, 0xf3, 0xff, 0xf4, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf3, 0xff, 0xf2, 0xff, 0xf3, 0xff, 0xf1, 0xff, 0xf4, 0xff, 0xf1, 0xff, 0xf5, 0xff, 0xf0, 0xff, 0xf7, 0xff, 0xef, 0xff, 0xf8, 0xff, 0xef, 0xff, 0xf9, 0xff, 0xee, 0xff, 0xfa, 0xff, 0xee, 0xff, 0xfa, 0xff, 0xed, 0xff, 0xfa, 0xff, 0xed, 0xff, 0xfa, 0xff, 0xee, 0xff, 0xfb, 0xff, 0xef, 0xff, 0xfc, 0xff, 0xf0, 0xff, 0xfe, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xf2, 0xff, 0x00, 0x00, 0xf3, 0xff, 0x00, 0x00, 0xf4, 0xff, 0x01, 0x00, 0xf6, 0xff, 0x01, 0x00, 0xf7, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x09, 0x00, 0x02, 0x00, 0x09, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x0d, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x03, 0x00, 0x10, 0x00, 0x03, 0x00, 0x11, 0x00, 0x02, 0x00, 0x11, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0xff, 0xff, 0x11, 0x00, 0xfe, 0xff, 0x11, 0x00, 0xfe, 0xff, 0x10, 0x00, 0xfd, 0xff, 0x10, 0x00, 0xfd, 0xff, 0x10, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0xfc, 0xff, 0x0e, 0x00, 0xfd, 0xff, 0x0d, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x0b, 0x00, 0xfb, 0xff, 0x0a, 0x00, 0xfb, 0xff, 0x09, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf7, 0xff, 0x02, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf5, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xfe, 0xff, 0xf5, 0xff, 0xfd, 0xff, 0xf5, 0xff, 0xfd, 0xff, 0xf5, 0xff, 0xfd, 0xff, 0xf6, 0xff, 0xfc, 0xff, 0xf5, 0xff, 0xfb, 0xff, 0xf5, 0xff, 0xf9, 0xff, 0xf6, 0xff, 0xf7, 0xff, 0xf6, 0xff, 0xf5, 0xff, 0xf8, 0xff, 0xf4, 0xff, 0xf9, 0xff, 0xf4, 0xff, 0xfb, 0xff, 0xf5, 0xff, 0xfc, 0xff, 0xf5, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf6, 0xff, 0x05, 0x00, 0xf5, 0xff, 0x07, 0x00, 0xf4, 0xff, 0x09, 0x00, 0xf4, 0xff, 0x0a, 0x00, 0xf4, 0xff, 0x0b, 0x00, 0xf5, 0xff, 0x0c, 0x00, 0xf7, 0xff, 0x0d, 0x00, 0xf8, 0xff, 0x0f, 0x00, 0xf9, 0xff, 0x11, 0x00, 0xf9, 0xff, 0x12, 0x00, 0xfa, 0xff, 0x13, 0x00, 0xf9, 0xff, 0x13, 0x00, 0xfa, 0xff, 0x13, 0x00, 0xfb, 0xff, 0x12, 0x00, 0xfc, 0xff, 0x11, 0x00, 0xfe, 0xff, 0x11, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x11, 0x00, 0x03, 0x00, 0x11, 0x00, 0x05, 0x00, 0x11, 0x00, 0x05, 0x00, 0x10, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x09, 0x00, 0x09, 0x00, 0x08, 0x00, 0x09, 0x00, 0x07, 0x00, 0x08, 0x00, 0x06, 0x00, 0x08, 0x00, 0x06, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x04, 0x00, 0x07, 0x00, 0x03, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x01, 0x00, 0x06, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf7, 0xff, 0x02, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf3, 0xff, 0x02, 0x00, 0xf1, 0xff, 0x02, 0x00, 0xf0, 0xff, 0x01, 0x00, 0xee, 0xff, 0x00, 0x00, 0xec, 0xff, 0xfe, 0xff, 0xeb, 0xff, 0xfd, 0xff, 0xe9, 0xff, 0xfd, 0xff, 0xe9, 0xff, 0xfd, 0xff, 0xe8, 0xff, 0xfd, 0xff, 0xe9, 0xff, 0xfe, 0xff, 0xe9, 0xff, 0xfd, 0xff, 0xe9, 0xff, 0xfd, 0xff, 0xe9, 0xff, 0xfc, 0xff, 0xea, 0xff, 0xfa, 0xff, 0xeb, 0xff, 0xf9, 0xff, 0xec, 0xff, 0xf9, 0xff, 0xee, 0xff, 0xf8, 0xff, 0xef, 0xff, 0xf8, 0xff, 0xf0, 0xff, 0xf9, 0xff, 0xf2, 0xff, 0xf8, 0xff, 0xf2, 0xff, 0xf8, 0xff, 0xf3, 0xff, 0xf7, 0xff, 0xf5, 0xff, 0xf5, 0xff, 0xf6, 0xff, 0xf4, 0xff, 0xf8, 0xff, 0xf3, 0xff, 0xfa, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfe, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xf3, 0xff, 0x00, 0x00, 0xf4, 0xff, 0x00, 0x00, 0xf4, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x00, 0x00, 0xf6, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x08, 0x00, 0xff, 0xff, 0x0a, 0x00, 0xff, 0xff, 0x0c, 0x00, 0xff, 0xff, 0x0e, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0xff, 0xff, 0x10, 0x00, 0xff, 0xff, 0x10, 0x00, 0xfe, 0xff, 0x10, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xfd, 0xff, 0x10, 0x00, 0xfd, 0xff, 0x11, 0x00, 0xfd, 0xff, 0x11, 0x00, 0xfd, 0xff, 0x12, 0x00, 0xfd, 0xff, 0x12, 0x00, 0xfd, 0xff, 0x11, 0x00, 0xfd, 0xff, 0x10, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0xfd, 0xff, 0x0e, 0x00, 0xfc, 0xff, 0x0d, 0x00, 0xfc, 0xff, 0x0d, 0x00, 0xfb, 0xff, 0x0c, 0x00, 0xfb, 0xff, 0x0b, 0x00, 0xfb, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf7, 0xff, 0x02, 0x00, 0xf6, 0xff, 0x02, 0x00, 0xf4, 0xff, 0x02, 0x00, 0xf4, 0xff, 0x03, 0x00, 0xf4, 0xff, 0x03, 0x00, 0xf4, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x04, 0x00, 0xf6, 0xff, 0x05, 0x00, 0xf7, 0xff, 0x06, 0x00, 0xf7, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x09, 0x00, 0xf7, 0xff, 0x0a, 0x00, 0xf7, 0xff, 0x0b, 0x00, 0xf7, 0xff, 0x0c, 0x00, 0xf8, 0xff, 0x0c, 0x00, 0xfa, 0xff, 0x0d, 0x00, 0xfb, 0xff, 0x0e, 0x00, 0xfc, 0xff, 0x0e, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0xfe, 0xff, 0x10, 0x00, 0xff, 0xff, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, 0x11, 0x00, 0x02, 0x00, 0x11, 0x00, 0x03, 0x00, 0x10, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x07, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0xff, 0xff, 0x0a, 0x00, 0xff, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xf5, 0xff, 0xfe, 0xff, 0xf4, 0xff, 0xfe, 0xff, 0xf3, 0xff, 0xff, 0xff, 0xf2, 0xff, 0x00, 0x00, 0xf2, 0xff, 0x01, 0x00, 0xf3, 0xff, 0x02, 0x00, 0xf3, 0xff, 0x03, 0x00, 0xf3, 0xff, 0x03, 0x00, 0xf2, 0xff, 0x03, 0x00, 0xf1, 0xff, 0x03, 0x00, 0xf0, 0xff, 0x03, 0x00, 0xf0, 0xff, 0x03, 0x00, 0xf0, 0xff, 0x03, 0x00, 0xf0, 0xff, 0x03, 0x00, 0xf0, 0xff, 0x04, 0x00, 0xf0, 0xff, 0x05, 0x00, 0xf0, 0xff, 0x05, 0x00, 0xf0, 0xff, 0x06, 0x00, 0xf0, 0xff, 0x06, 0x00, 0xf1, 0xff, 0x05, 0x00, 0xf2, 0xff, 0x05, 0x00, 0xf4, 0xff, 0x05, 0x00, 0xf5, 0xff, 0x06, 0x00, 0xf7, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x09, 0x00, 0x03, 0x00, 0x09, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x08, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x10, 0x00, 0x08, 0x00, 0x10, 0x00, 0x07, 0x00, 0x10, 0x00, 0x06, 0x00, 0x10, 0x00, 0x05, 0x00, 0x10, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x11, 0x00, 0x02, 0x00, 0x11, 0x00, 0x03, 0x00, 0x10, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0xfe, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x0c, 0x00, 0xfb, 0xff, 0x0c, 0x00, 0xfb, 0xff, 0x0b, 0x00, 0xfa, 0xff, 0x09, 0x00, 0xf8, 0xff, 0x08, 0x00, 0xf7, 0xff, 0x07, 0x00, 0xf5, 0xff, 0x06, 0x00, 0xf4, 0xff, 0x06, 0x00, 0xf3, 0xff, 0x07, 0x00, 0xf2, 0xff, 0x07, 0x00, 0xf2, 0xff, 0x07, 0x00, 0xf1, 0xff, 0x06, 0x00, 0xf1, 0xff, 0x04, 0x00, 0xf0, 0xff, 0x02, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xef, 0xff, 0xfe, 0xff, 0xef, 0xff, 0xfd, 0xff, 0xef, 0xff, 0xfd, 0xff, 0xf0, 0xff, 0xfd, 0xff, 0xf0, 0xff, 0xfd, 0xff, 0xf1, 0xff, 0xfc, 0xff, 0xf2, 0xff, 0xfb, 0xff, 0xf3, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xf8, 0xff, 0xf5, 0xff, 0xf7, 0xff, 0xf5, 0xff, 0xf7, 0xff, 0xf6, 0xff, 0xf7, 0xff, 0xf7, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf7, 0xff, 0xfb, 0xff, 0xf6, 0xff, 0xfb, 0xff, 0xf5, 0xff, 0xfb, 0xff, 0xf4, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xf8, 0xff, 0xf5, 0xff, 0xf8, 0xff, 0xf5, 0xff, 0xf7, 0xff, 0xf5, 0xff, 0xf7, 0xff, 0xf5, 0xff, 0xf7, 0xff, 0xf5, 0xff, 0xf8, 0xff, 0xf4, 0xff, 0xf8, 0xff, 0xf4, 0xff, 0xf8, 0xff, 0xf4, 0xff, 0xf8, 0xff, 0xf4, 0xff, 0xf8, 0xff, 0xf5, 0xff, 0xf8, 0xff, 0xf5, 0xff, 0xf8, 0xff, 0xf6, 0xff, 0xf9, 0xff, 0xf5, 0xff, 0xf9, 0xff, 0xf5, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xfa, 0xff, 0xf4, 0xff, 0xfb, 0xff, 0xf4, 0xff, 0xfb, 0xff, 0xf5, 0xff, 0xfc, 0xff, 0xf6, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf6, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x02, 0x00, 0xf7, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, 0x09, 0x00, 0x04, 0x00, 0x09, 0x00, 0x05, 0x00, 0x09, 0x00, 0x07, 0x00, 0x09, 0x00, 0x08, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x09, 0x00, 0x07, 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x06, 0x00, 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x03, 0x00, 0x08, 0x00, 0x02, 0x00, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf7, 0xff, 0x03, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x03, 0x00, 0xf4, 0xff, 0x03, 0x00, 0xf4, 0xff, 0x02, 0x00, 0xf4, 0xff, 0x02, 0x00, 0xf4, 0xff, 0x01, 0x00, 0xf5, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x03, 0x00, 0x06, 0x00, 0x04, 0x00, 0x07, 0x00, 0x05, 0x00, 0x07, 0x00, 0x06, 0x00, 0x08, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x03, 0x00, 0x10, 0x00, 0x03, 0x00, 0x10, 0x00, 0x04, 0x00, 0x10, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x10, 0x00, 0x04, 0x00, 0x10, 0x00, 0x04, 0x00, 0x10, 0x00, 0x05, 0x00, 0x10, 0x00, 0x06, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x07, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xf9, 0xff, 0xf6, 0xff, 0xfa, 0xff, 0xf5, 0xff, 0xfa, 0xff, 0xf3, 0xff, 0xfb, 0xff, 0xf2, 0xff, 0xfc, 0xff, 0xf1, 0xff, 0xfc, 0xff, 0xf0, 0xff, 0xfc, 0xff, 0xef, 0xff, 0xfb, 0xff, 0xee, 0xff, 0xf9, 0xff, 0xec, 0xff, 0xf9, 0xff, 0xeb, 0xff, 0xf8, 0xff, 0xea, 0xff, 0xf9, 0xff, 0xea, 0xff, 0xfa, 0xff, 0xea, 0xff, 0xfb, 0xff, 0xeb, 0xff, 0xfb, 0xff, 0xec, 0xff, 0xfa, 0xff, 0xec, 0xff, 0xfa, 0xff, 0xed, 0xff, 0xf9, 0xff, 0xed, 0xff, 0xf8, 0xff, 0xed, 0xff, 0xf7, 0xff, 0xed, 0xff, 0xf7, 0xff, 0xee, 0xff, 0xf7, 0xff, 0xf0, 0xff, 0xf7, 0xff, 0xf2, 0xff, 0xf7, 0xff, 0xf4, 0xff, 0xf7, 0xff, 0xf5, 0xff, 0xf8, 0xff, 0xf7, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf8, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x03, 0x00, 0x08, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x05, 0x00, 0x10, 0x00, 0x05, 0x00, 0x10, 0x00, 0x04, 0x00, 0x10, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0xff, 0xff, 0x08, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf6, 0xff, 0xfd, 0xff, 0xf5, 0xff, 0xfd, 0xff, 0xf4, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfe, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xed, 0xff, 0xff, 0xff, 0xed, 0xff, 0xff, 0xff, 0xed, 0xff, 0xff, 0xff, 0xed, 0xff, 0xff, 0xff, 0xed, 0xff, 0x00, 0x00, 0xed, 0xff, 0x01, 0x00, 0xed, 0xff, 0x02, 0x00, 0xed, 0xff, 0x02, 0x00, 0xed, 0xff, 0x02, 0x00, 0xee, 0xff, 0x02, 0x00, 0xef, 0xff, 0x01, 0x00, 0xf1, 0xff, 0x01, 0x00, 0xf2, 0xff, 0x01, 0x00, 0xf3, 0xff, 0x02, 0x00, 0xf4, 0xff, 0x02, 0x00, 0xf5, 0xff, 0x03, 0x00, 0xf7, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x08, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x0a, 0x00, 0xfe, 0xff, 0x0b, 0x00, 0xfe, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0d, 0x00, 0xfd, 0xff, 0x0e, 0x00, 0xfd, 0xff, 0x0e, 0x00, 0xfd, 0xff, 0x0f, 0x00, 0xfe, 0xff, 0x0f, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf6, 0xff, 0xfb, 0xff, 0xf4, 0xff, 0xfb, 0xff, 0xf3, 0xff, 0xfb, 0xff, 0xf1, 0xff, 0xfb, 0xff, 0xf1, 0xff, 0xfa, 0xff, 0xf1, 0xff, 0xfa, 0xff, 0xf1, 0xff, 0xfa, 0xff, 0xf1, 0xff, 0xfa, 0xff, 0xf1, 0xff, 0xfb, 0xff, 0xf1, 0xff, 0xfc, 0xff, 0xf1, 0xff, 0xfe, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xf1, 0xff, 0x00, 0x00, 0xf1, 0xff, 0x00, 0x00, 0xf2, 0xff, 0x00, 0x00, 0xf2, 0xff, 0x00, 0x00, 0xf3, 0xff, 0x00, 0x00, 0xf4, 0xff, 0x01, 0x00, 0xf6, 0xff, 0x02, 0x00, 0xf7, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xfa, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xff, 0xff, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0x03, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x05, 0x00, 0x07, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x08, 0x00, 0x10, 0x00, 0x09, 0x00, 0x11, 0x00, 0x0a, 0x00, 0x13, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x09, 0x00, 0x16, 0x00, 0x08, 0x00, 0x17, 0x00, 0x08, 0x00, 0x18, 0x00, 0x08, 0x00, 0x18, 0x00, 0x08, 0x00, 0x19, 0x00, 0x08, 0x00, 0x19, 0x00, 0x09, 0x00, 0x19, 0x00, 0x08, 0x00, 0x18, 0x00, 0x07, 0x00, 0x16, 0x00, 0x06, 0x00, 0x14, 0x00, 0x04, 0x00, 0x13, 0x00, 0x03, 0x00, 0x12, 0x00, 0x02, 0x00, 0x12, 0x00, 0x02, 0x00, 0x11, 0x00, 0x02, 0x00, 0x11, 0x00, 0x02, 0x00, 0x10, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0xff, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xf4, 0xff, 0xfe, 0xff, 0xf2, 0xff, 0xfd, 0xff, 0xef, 0xff, 0xfd, 0xff, 0xee, 0xff, 0xfd, 0xff, 0xec, 0xff, 0xfe, 0xff, 0xec, 0xff, 0xfe, 0xff, 0xeb, 0xff, 0xfe, 0xff, 0xea, 0xff, 0xfe, 0xff, 0xe9, 0xff, 0xfd, 0xff, 0xe9, 0xff, 0xfd, 0xff, 0xe8, 0xff, 0xfc, 0xff, 0xe8, 0xff, 0xfc, 0xff, 0xe8, 0xff, 0xfc, 0xff, 0xe8, 0xff, 0xfc, 0xff, 0xe9, 0xff, 0xfc, 0xff, 0xeb, 0xff, 0xfd, 0xff, 0xec, 0xff, 0xfd, 0xff, 0xee, 0xff, 0xfd, 0xff, 0xef, 0xff, 0xfd, 0xff, 0xf1, 0xff, 0xfd, 0xff, 0xf2, 0xff, 0xfd, 0xff, 0xf4, 0xff, 0xfd, 0xff, 0xf6, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf9, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x0a, 0x00, 0xfe, 0xff, 0x0b, 0x00, 0xff, 0xff, 0x0b, 0x00, 0xff, 0xff, 0x0b, 0x00, 0xff, 0xff, 0x0c, 0x00, 0xfe, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x0b, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xf9, 0xff, 0xf8, 0xff, 0xf9, 0xff, 0xf6, 0xff, 0xf8, 0xff, 0xf5, 0xff, 0xf8, 0xff, 0xf4, 0xff, 0xf9, 0xff, 0xf3, 0xff, 0xfa, 0xff, 0xf3, 0xff, 0xfb, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf2, 0xff, 0xfc, 0xff, 0xf1, 0xff, 0xfc, 0xff, 0xf0, 0xff, 0xfc, 0xff, 0xf0, 0xff, 0xfc, 0xff, 0xf1, 0xff, 0xfd, 0xff, 0xf2, 0xff, 0xfe, 0xff, 0xf4, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xff, 0xff, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x09, 0x00, 0x07, 0x00, 0x08, 0x00, 0x07, 0x00, 0x07, 0x00, 0x06, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf7, 0xff, 0x04, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf6, 0xff, 0x02, 0x00, 0xf6, 0xff, 0x01, 0x00, 0xf7, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x06, 0x00, 0x02, 0x00, 0x07, 0x00, 0x03, 0x00, 0x08, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x07, 0x00, 0x05, 0x00, 0x08, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x07, 0x00, 0x09, 0x00, 0x07, 0x00, 0x09, 0x00, 0x06, 0x00, 0x08, 0x00, 0x05, 0x00, 0x09, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x05, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf7, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf6, 0xff, 0xfa, 0xff, 0xf6, 0xff, 0xfa, 0xff, 0xf7, 0xff, 0xfa, 0xff, 0xf7, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf7, 0xff, 0xfa, 0xff, 0xf7, 0xff, 0xfb, 0xff, 0xf6, 0xff, 0xfc, 0xff, 0xf5, 0xff, 0xfe, 0xff, 0xf4, 0xff, 0xff, 0xff, 0xf4, 0xff, 0x01, 0x00, 0xf3, 0xff, 0x01, 0x00, 0xf3, 0xff, 0x02, 0x00, 0xf3, 0xff, 0x03, 0x00, 0xf4, 0xff, 0x04, 0x00, 0xf5, 0xff, 0x06, 0x00, 0xf6, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x08, 0x00, 0xf8, 0xff, 0x09, 0x00, 0xf8, 0xff, 0x0a, 0x00, 0xf8, 0xff, 0x0b, 0x00, 0xf8, 0xff, 0x0b, 0x00, 0xf8, 0xff, 0x0b, 0x00, 0xf9, 0xff, 0x0c, 0x00, 0xfa, 0xff, 0x0c, 0x00, 0xfb, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x0d, 0x00, 0xfd, 0xff, 0x0d, 0x00, 0xfd, 0xff, 0x0d, 0x00, 0xfe, 0xff, 0x0d, 0x00, 0xfe, 0xff, 0x0c, 0x00, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x09, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x0a, 0x00, 0xff, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x0b, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfb, 0xff, 0x0a, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xf9, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x07, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf7, 0xff, 0x06, 0x00, 0xf6, 0xff, 0x05, 0x00, 0xf4, 0xff, 0x04, 0x00, 0xf3, 0xff, 0x03, 0x00, 0xf2, 0xff, 0x02, 0x00, 0xf2, 0xff, 0x01, 0x00, 0xf2, 0xff, 0x00, 0x00, 0xf2, 0xff, 0x00, 0x00, 0xf3, 0xff, 0x00, 0x00, 0xf3, 0xff, 0xff, 0xff, 0xf3, 0xff, 0xfe, 0xff, 0xf2, 0xff, 0xfd, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf3, 0xff, 0xfc, 0xff, 0xf4, 0xff, 0xfc, 0xff, 0xf5, 0xff, 0xfc, 0xff, 0xf6, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x03, 0x00, 0x06, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf7, 0xff, 0x05, 0x00, 0xf6, 0xff, 0x06, 0x00, 0xf5, 0xff, 0x06, 0x00, 0xf6, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x07, 0x00, 0xf8, 0xff, 0x08, 0x00, 0xf8, 0xff, 0x09, 0x00, 0xf9, 0xff, 0x0b, 0x00, 0xf9, 0xff, 0x0c, 0x00, 0xf8, 0xff, 0x0d, 0x00, 0xf9, 0xff, 0x0d, 0x00, 0xf9, 0xff, 0x0e, 0x00, 0xfa, 0xff, 0x0e, 0x00, 0xfb, 0xff, 0x0e, 0x00, 0xfc, 0xff, 0x0e, 0x00, 0xfc, 0xff, 0x0d, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0b, 0x00, 0xfe, 0xff, 0x0a, 0x00, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x05, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xff, 0xff, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x06, 0x00, 0x03, 0x00, 0x06, 0x00, 0x03, 0x00, 0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0xff, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xfa, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x06, 0x00, 0x05, 0x00, 0x07, 0x00, 0x05, 0x00, 0x07, 0x00, 0x05, 0x00, 0x08, 0x00, 0x05, 0x00, 0x08, 0x00, 0x05, 0x00, 0x08, 0x00, 0x05, 0x00, 0x09, 0x00, 0x06, 0x00, 0x09, 0x00, 0x06, 0x00, 0x09, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x08, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x05, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfa, 0xff, 0x07, 0x00, 0xfa, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x08, 0x00, 0xf9, 0xff, 0x08, 0x00, 0xf9, 0xff, 0x08, 0x00, 0xf9, 0xff, 0x08, 0x00, 0xf9, 0xff, 0x08, 0x00, 0xf9, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfb, 0xff, 0x09, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfd, 0xff, 0x09, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xf9, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf6, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xff, 0xff, 0xf5, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x00, 0x00, 0xf4, 0xff, 0x01, 0x00, 0xf4, 0xff, 0x01, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf6, 0xff, 0x01, 0x00, 0xf7, 0xff, 0x01, 0x00, 0xf7, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x07, 0x00, 0xfa, 0xff, 0x07, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x02, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0xff, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x0a, 0x00, 0xfe, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x09, 0x00, 0xfd, 0xff, 0x09, 0x00, 0xfd, 0xff, 0x09, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfd, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf9, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf7, 0xff, 0x02, 0x00, 0xf6, 0xff, 0x01, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf7, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x09, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x03, 0x00, 0x06, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf7, 0xff, 0x03, 0x00, 0xf7, 0xff, 0x03, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf5, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf6, 0xff, 0x01, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfb, 0xff, 0x09, 0x00, 0xfb, 0xff, 0x09, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x07, 0x00, 0xfa, 0xff, 0x07, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x09, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x02, 0x00, 0x0f, 0x00, 0x02, 0x00, 0x0f, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0d, 0x00, 0xff, 0xff, 0x0d, 0x00, 0xff, 0xff, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xf6, 0xff, 0xfd, 0xff, 0xf6, 0xff, 0xfd, 0xff, 0xf6, 0xff, 0xfd, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xf5, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x00, 0x00, 0xf4, 0xff, 0x00, 0x00, 0xf4, 0xff, 0x00, 0x00, 0xf3, 0xff, 0x00, 0x00, 0xf3, 0xff, 0xff, 0xff, 0xf4, 0xff, 0xff, 0xff, 0xf4, 0xff, 0xff, 0xff, 0xf5, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf5, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x03, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x03, 0x00, 0x08, 0x00, 0x03, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfc, 0xff, 0x0a, 0x00, 0xfc, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x0b, 0x00, 0xfc, 0xff, 0x0c, 0x00, 0xfc, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0d, 0x00, 0xfd, 0xff, 0x0d, 0x00, 0xfe, 0xff, 0x0d, 0x00, 0xfe, 0xff, 0x0d, 0x00, 0xfe, 0xff, 0x0d, 0x00, 0xfe, 0xff, 0x0c, 0x00, 0xfe, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0b, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0c, 0x00, 0xfd, 0xff, 0x0b, 0x00, 0xfe, 0xff, 0x0b, 0x00, 0xfe, 0xff, 0x0a, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xfa, 0xff, 0x05, 0x00, 0xfa, 0xff, 0x05, 0x00, 0xfa, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0xff, 0xff, 0x08, 0x00, 0xff, 0xff, 0x08, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x07, 0x00, 0xf8, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x06, 0x00, 0xf7, 0xff, 0x06, 0x00, 0xf7, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xf9, 0xff, 0xf8, 0xff, 0xfa, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x07, 0x00, 0x06, 0x00, 0x08, 0x00, 0x05, 0x00, 0x09, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x0d, 0x00, 0x08, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x07, 0x00, 0x0a, 0x00, 0x06, 0x00, 0x09, 0x00, 0x06, 0x00, 0x08, 0x00, 0x05, 0x00, 0x07, 0x00, 0x05, 0x00, 0x06, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf5, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x0a, 0x00, 0xfe, 0xff, 0x0a, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xf9, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0xff, 0xff, 0x08, 0x00, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x00, 0x08, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x09, 0x00, 0x05, 0x00, 0x09, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x03, 0x00, 0x07, 0x00, 0x03, 0x00, 0x07, 0x00, 0x04, 0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x05, 0x00, 0x08, 0x00, 0x05, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x07, 0x00, 0x03, 0x00, 0x07, 0x00, 0x03, 0x00, 0x08, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x09, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf6, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x01, 0x00, 0xf5, 0xff, 0x01, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf5, 0xff, 0x02, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf6, 0xff, 0x03, 0x00, 0xf7, 0xff, 0x04, 0x00, 0xf7, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0xff, 0xff, 0x0a, 0x00, 0xff, 0xff, 0x0a, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x08, 0x00, 0xff, 0xff, 0x08, 0x00, 0xff, 0xff, 0x08, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf7, 0xff, 0x06, 0x00, 0xf7, 0xff, 0x06, 0x00, 0xf6, 0xff, 0x06, 0x00, 0xf6, 0xff, 0x07, 0x00, 0xf6, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x07, 0x00, 0xf7, 0xff, 0x07, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf6, 0xff, 0xfe, 0xff, 0xf5, 0xff, 0xff, 0xff, 0xf5, 0xff, 0xff, 0xff, 0xf5, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x00, 0x00, 0xf5, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf6, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfc, 0xff, 0x09, 0x00, 0xfd, 0xff, 0x09, 0x00, 0xfd, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x05, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf8, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x07, 0x00, 0xf9, 0xff, 0x08, 0x00, 0xf9, 0xff, 0x09, 0x00, 0xf9, 0xff, 0x09, 0x00, 0xfa, 0xff, 0x09, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x08, 0x00, 0xfa, 0xff, 0x07, 0x00, 0xfa, 0xff, 0x07, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x05, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x03, 0x00, 0x06, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x07, 0x00, 0x06, 0x00, 0x07, 0x00, 0x06, 0x00, 0x08, 0x00, 0x06, 0x00, 0x08, 0x00, 0x06, 0x00, 0x09, 0x00, 0x07, 0x00, 0x09, 0x00, 0x07, 0x00, 0x09, 0x00, 0x07, 0x00, 0x08, 0x00, 0x06, 0x00, 0x08, 0x00, 0x06, 0x00, 0x08, 0x00, 0x05, 0x00, 0x08, 0x00, 0x05, 0x00, 0x08, 0x00, 0x05, 0x00, 0x08, 0x00, 0x05, 0x00, 0x08, 0x00, 0x06, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x03, 0x00, 0x07, 0x00, 0x03, 0x00, 0x07, 0x00, 0x03, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x07, 0x00, 0x05, 0x00, 0x07, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x03, 0x00, 0x07, 0x00, 0x03, 0x00, 0x07, 0x00, 0x03, 0x00, 0x07, 0x00, 0x03, 0x00, 0x08, 0x00, 0x03, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf7, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, 0x09, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0xff, 0xff, 0x08, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x03, 0x00, 0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x09, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0xff, 0xff, 0x0a, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xfd, 0xff, 0x09, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfc, 0xff, 0x08, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfb, 0xff, 0x07, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x06, 0x00, 0x03, 0x00, 0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x07, 0x00, 0x05, 0x00, 0x07, 0x00, 0x05, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x08, 0x00, 0x03, 0x00, 0x08, 0x00, 0x03, 0x00, 0x09, 0x00, 0x03, 0x00, 0x09, 0x00, 0x03, 0x00, 0x09, 0x00, 0x04, 0x00, 0x09, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x0a, 0x00, 0x05, 0x00, 0x09, 0x00, 0x05, 0x00, 0x09, 0x00, 0x05, 0x00, 0x08, 0x00, 0x05, 0x00, 0x08, 0x00, 0x05, 0x00, 0x07, 0x00, 0x05, 0x00, 0x07, 0x00, 0x05, 0x00, 0x07, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x05, 0x00, 0x06, 0x00, 0x04, 0x00, 0x06, 0x00, 0x03, 0x00, 0x06, 0x00, 0x03, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x06, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x03, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0xff, 0xff, 0x08, 0x00, 0xff, 0xff, 0x08, 0x00, 0xff, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xfa, 0xff, 0x06, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xf9, 0xff, 0x05, 0x00, 0xf8, 0xff, 0x04, 0x00, 0xf8, 0xff, 0x03, 0x00, 0xf8, 0xff, 0x02, 0x00, 0xf7, 0xff, 0x01, 0x00, 0xf7, 0xff, 0x01, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0x00, 0x00, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xf9, 0xff, 0x00, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xf9, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, 0x00, 0x09, 0x00, 0x01, 0x00, 0x08, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x02, 0x00, 0x07, 0x00, 0x03, 0x00, 0x06, 0x00, 0x03, 0x00, 0x06, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfd, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfc, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfd, 0xff, 0xf9, 0xff, 0xfe, 0xff, 0xf9, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xff, 0xff, 0x08, 0x00, 0xff, 0xff, 0x08, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x05, 0x00, 0x02, 0x00, 0x06, 0x00, 0x02, 0x00, 0x06, 0x00, 0x03, 0x00, 0x06, 0x00, 0x03, 0x00, 0x05, 0x00, 0x04, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00, 0x03, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfc, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x05, 0x00, 0xfb, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xfa, 0xff, 0x04, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x03, 0x00, 0xf9, 0xff, 0x02, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x01, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfe, 0xff, 0xf8, 0xff, 0xfd, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfc, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf8, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xf9, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x02, 0x00, 0x07, 0x00, 0x03, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x04, 0x00, 0x07, 0x00, 0x05, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x05, 0x00, 0x07, 0x00, 0x05, 0x00, 0x07, 0x00, 0x04, 0x00, 0x08, 0x00, 0x04, 0x00, 0x08, 0x00, 0x03, 0x00, 0x09, 0x00, 0x03, 0x00, 0x09, 0x00, 0x02, 0x00, 0x09, 0x00, 0x02, 0x00, 0x09, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x09, 0x00, 0xff, 0xff, 0x08, 0x00, 0xff, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfc, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfd, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xfe, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0xff, 0xff, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfc, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfb, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x05, 0x00, 0x02, 0x00, 0x05, 0x00, 0x02, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x05, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x08, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x09, 0x00, 0xfe, 0xff, 0x0a, 0x00, 0xff, 0xff, 0x0a, 0x00, 0xff, 0xff, 0x0a, 0x00, 0xff, 0xff, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x06, 0x00, 0x02, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x05, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x02, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0xfb, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x01, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x02, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfa, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfb, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x05, 0x00, 0xff, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfe, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x07, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x06, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x05, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x04, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x03, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfc, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x02, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfd, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xfe, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0xff, 0x03, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xff, 0xff, 0x04, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x03, 0x00, 0xfe, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x02, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfd, 0xff, 0x01, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xff, 0xff, 0xfc, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x01, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x72, 0x65, 0x67, 0x6e, 0x5c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x6d, 0xff, 0xce, 0xe1, 0x45, 0x11, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xa0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x50, 0x6f, 0x70, 0x5f, 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x65, 0x64, 0x5f, 0x32, 0x00, 0x00, 0x58, 0x99, 0xd6, 0x39, 0x01, 0x00, 0x00, 0x00, 0x90, 0x6e, 0xc5, 0xbc, 0xa6, 0x7f, 0x00, 0x00, 0x75, 0x6d, 0x69, 0x64, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x01, 0x6d, 0xff, 0xce, 0xe1, 0x45, 0x11, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; NSUInteger length = sizeof(bytes) / sizeof(Byte); return [NSData dataWithBytesNoCopy:(void *)bytes length:length freeWhenDone:NO]; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeControl+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKLikeControl.h" @interface FBSDKLikeControl () - (NSDictionary *)analyticsParameters; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeDialog.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import @protocol FBSDKLikeDialogDelegate; @interface FBSDKLikeDialog : NSObject + (instancetype)likeWithObjectID:(NSString *)objectID objectType:(FBSDKLikeObjectType)objectType delegate:(id)delegate; @property (nonatomic, weak) id delegate; @property (nonatomic, copy) NSString *objectID; @property (nonatomic, assign) FBSDKLikeObjectType objectType; @property (nonatomic, assign) BOOL shouldFailOnDataError; @property (nonatomic, weak) UIViewController *fromViewController; - (BOOL)canLike; - (BOOL)like; - (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef; @end @protocol FBSDKLikeDialogDelegate - (void)likeDialog:(FBSDKLikeDialog *)likeDialog didCompleteWithResults:(NSDictionary *)results; - (void)likeDialog:(FBSDKLikeDialog *)likeDialog didFailWithError:(NSError *)error; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeDialog.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKLikeDialog.h" #import "FBSDKCoreKit+Internal.h" #import "FBSDKShareConstants.h" #import "FBSDKShareDefines.h" #import "FBSDKShareError.h" @implementation FBSDKLikeDialog #define FBSDK_LIKE_METHOD_MIN_VERSION @"20140410" #define FBSDK_LIKE_METHOD_NAME @"like" #define FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_LIKE @"like" #define FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_UNLIKE @"unlike" #pragma mark - Class Methods + (void)initialize { if ([FBSDKLikeDialog class] == self) { [FBSDKServerConfigurationManager loadServerConfigurationWithCompletionBlock:NULL]; } } + (instancetype)likeWithObjectID:(NSString *)objectID objectType:(FBSDKLikeObjectType)objectType delegate:(id)delegate { FBSDKLikeDialog *dialog = [[self alloc] init]; dialog.objectID = objectID; dialog.objectType = objectType; dialog.delegate = delegate; [dialog like]; return dialog; } #pragma mark - Public Methods - (BOOL)canLike { return YES; } - (BOOL)like { NSError *error; if (![self canLike]) { error = [FBSDKShareError errorWithCode:FBSDKShareDialogNotAvailableErrorCode message:@"Like dialog is not available."]; [_delegate likeDialog:self didFailWithError:error]; return NO; } if (![self validateWithError:&error]) { [_delegate likeDialog:self didFailWithError:error]; return NO; } NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; [FBSDKInternalUtility dictionary:parameters setObject:self.objectID forKey:@"object_id"]; [FBSDKInternalUtility dictionary:parameters setObject:NSStringFromFBSDKLikeObjectType(self.objectType) forKey:@"object_type"]; FBSDKBridgeAPIRequest * webRequest = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeWeb scheme:FBSDK_SHARE_JS_DIALOG_SCHEME methodName:FBSDK_LIKE_METHOD_NAME methodVersion:nil parameters:parameters userInfo:nil]; FBSDKBridgeAPICallbackBlock completionBlock = ^(FBSDKBridgeAPIResponse *response) { [self _handleCompletionWithDialogResults:response.responseParameters error:response.error]; }; FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration]; BOOL useSafariViewController = [configuration useSafariViewControllerForDialogName:FBSDKDialogConfigurationNameLike]; if ([self _canLikeNative]) { FBSDKBridgeAPIRequest *nativeRequest = [FBSDKBridgeAPIRequest bridgeAPIRequestWithProtocolType:FBSDKBridgeAPIProtocolTypeNative scheme:FBSDK_CANOPENURL_FACEBOOK methodName:FBSDK_LIKE_METHOD_NAME methodVersion:FBSDK_LIKE_METHOD_MIN_VERSION parameters:parameters userInfo:nil]; void (^networkCompletionBlock)(FBSDKBridgeAPIResponse *) = ^(FBSDKBridgeAPIResponse *response) { if (response.error.code == FBSDKAppVersionUnsupportedErrorCode) { [[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:webRequest useSafariViewController:useSafariViewController fromViewController:self.fromViewController completionBlock:completionBlock]; } else { completionBlock(response); } }; [[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:nativeRequest useSafariViewController:useSafariViewController fromViewController:self.fromViewController completionBlock:networkCompletionBlock]; } else { [[FBSDKApplicationDelegate sharedInstance] openBridgeAPIRequest:webRequest useSafariViewController:useSafariViewController fromViewController:self.fromViewController completionBlock:completionBlock]; } return YES; } - (BOOL)validateWithError:(NSError *__autoreleasing *)errorRef { if (![self.objectID length]) { if (errorRef != NULL) { *errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"objectID" message:nil]; } return NO; } if (errorRef != NULL) { *errorRef = nil; } return YES; } #pragma mark - Helper Methods - (BOOL)_canLikeNative { FBSDKServerConfiguration *configuration = [FBSDKServerConfigurationManager cachedServerConfiguration]; BOOL useNativeDialog = [configuration useNativeDialogForDialogName:FBSDKDialogConfigurationNameLike]; return (useNativeDialog && [FBSDKInternalUtility isFacebookAppInstalled]); } - (void)_handleCompletionWithDialogResults:(NSDictionary *)results error:(NSError *)error { if (!_delegate) { return; } NSString *completionGesture = results[FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY]; if (completionGesture && !error) { [_delegate likeDialog:self didCompleteWithResults:[results copy]]; } else { [_delegate likeDialog:self didFailWithError:error]; } } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKMessengerIcon.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKCoreKit+Internal.h" @interface FBSDKMessengerIcon : FBSDKIcon @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKMessengerIcon.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKMessengerIcon.h" @implementation FBSDKMessengerIcon - (CGPathRef)pathWithSize:(CGSize)size { CGAffineTransform transformValue = CGAffineTransformMakeScale(size.width / 61.0, size.height / 61.0); const CGAffineTransform *transform = &transformValue; CGMutablePathRef path = CGPathCreateMutable(); CGPathMoveToPoint(path, transform, 30.001, 0.962); CGPathAddCurveToPoint(path, transform, 13.439, 0.962, 0.014, 13.462, 0.014, 28.882); CGPathAddCurveToPoint(path, transform, 0.014, 37.165, 3.892, 44.516, 10.046, 49.549); CGPathAddLineToPoint(path, transform, 10.046, 61.176); CGPathAddLineToPoint(path, transform, 19.351, 54.722); CGPathAddCurveToPoint(path, transform, 22.662, 55.870, 26.250, 56.502, 30.002, 56.502); CGPathAddCurveToPoint(path, transform, 46.565, 56.502, 59.990, 44.301, 59.990, 28.882); CGPathAddCurveToPoint(path, transform, 59.989, 13.462, 46.564, 0.962, 30.001, 0.962); CGPathCloseSubpath(path); CGPathMoveToPoint(path, transform, 33.159, 37.473); CGPathAddLineToPoint(path, transform, 25.403, 29.484); CGPathAddLineToPoint(path, transform, 10.467, 37.674); CGPathAddLineToPoint(path, transform, 26.843, 20.445); CGPathAddLineToPoint(path, transform, 34.599, 28.433); CGPathAddLineToPoint(path, transform, 49.535, 20.244); CGPathAddLineToPoint(path, transform, 33.159, 37.473); CGPathCloseSubpath(path); CGPathRef result = CGPathCreateCopy(path); CGPathRelease(path); return CFAutorelease(result); } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareDefines.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #define FBSDK_SHARE_JS_DIALOG_SCHEME @"web" #define FBSDK_SHARE_METHOD_NAME @"share" #define FBSDK_SHARE_OPEN_GRAPH_METHOD_NAME @"ogshare" #define FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY @"completionGesture" #define FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_CANCEL @"cancel" #define FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST @"post" #define FBSDK_SHARE_RESULT_DID_COMPLETE_KEY @"didComplete" #define FBSDK_SHARE_RESULT_PHOTO_IDS_KEY @"photo_ids" #define FBSDK_SHARE_RESULT_POST_ID_KEY @"postId" #define FBSDK_SHARE_VIDEO_END_OFFSET @"end_offset" #define FBSDK_SHARE_VIDEO_FILE_CHUNK @"video_file_chunk" #define FBSDK_SHARE_VIDEO_ID @"video_id" #define FBSDK_SHARE_VIDEO_SIZE @"file_size" #define FBSDK_SHARE_VIDEO_START_OFFSET @"start_offset" #define FBSDK_SHARE_VIDEO_UPLOAD_PHASE @"upload_phase" #define FBSDK_SHARE_VIDEO_UPLOAD_PHASE_FINISH @"finish" #define FBSDK_SHARE_VIDEO_UPLOAD_PHASE_START @"start" #define FBSDK_SHARE_VIDEO_UPLOAD_PHASE_TRANSFER @"transfer" #define FBSDK_SHARE_VIDEO_UPLOAD_SESSION_ID @"upload_session_id" #define FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS @"success" #define FBSDK_SHARE_WEB_PARAM_POST_ID_KEY @"post_id" #define FBSDK_SHARE_WEB_SCHEME @"https" ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareError.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import "FBSDKCoreKit+Internal.h" @interface FBSDKShareError : FBSDKError @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareError.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareError.h" #import "FBSDKShareConstants.h" @implementation FBSDKShareError + (NSString *)errorDomain { return FBSDKShareErrorDomain; } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareKit+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import "FBSDKShareDefines.h" #import "FBSDKShareError.h" #import "FBSDKShareOpenGraphValueContainer+Internal.h" #import "FBSDKShareUtility.h" #import "FBSDKVideoUploader.h" ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareLinkContent+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareLinkContent.h" @interface FBSDKShareLinkContent () // Deprecated parameters for Feed Dialog - for usage with Unity only. @property (nonatomic, copy) NSDictionary *feedParameters; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareOpenGraphValueContainer+Internal.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import @interface FBSDKShareOpenGraphValueContainer () - (NSDictionary *)allProperties; - (BOOL)isEqualToShareOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)object; - (BOOL)requireKeyNamespace; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import #import #import #import #if !TARGET_OS_TV #import #import #endif @interface FBSDKShareUtility : NSObject + (void)assertCollection:(id)collection ofClass:itemClass name:(NSString *)name; + (void)assertCollection:(id)collection ofClassStrings:(NSArray *)classStrings name:(NSString *)name; + (void)assertOpenGraphKey:(id)key requireNamespace:(BOOL)requireNamespace; + (void)assertOpenGraphValue:(id)value; + (void)assertOpenGraphValues:(NSDictionary *)dictionary requireKeyNamespace:(BOOL)requireKeyNamespace; + (id)convertOpenGraphValue:(id)value; + (BOOL)buildWebShareContent:(id)content methodName:(NSString *__autoreleasing *)methodNameRef parameters:(NSDictionary *__autoreleasing *)parametersRef error:(NSError *__autoreleasing *)errorRef; + (void)buildAsyncWebPhotoContent:(FBSDKSharePhotoContent *)content completionHandler:(void(^)(BOOL, NSString *, NSDictionary *))completion; + (NSDictionary *)convertOpenGraphValues:(NSDictionary *)dictionary; + (NSDictionary *)feedShareDictionaryForContent:(id)content; + (NSString *)hashtagStringFromHashtag:(FBSDKHashtag *)hashtag; + (NSDictionary *)parametersForShareContent:(id)shareContent shouldFailOnDataError:(BOOL)shouldFailOnDataError; + (void)testShareContent:(id)shareContent containsMedia:(BOOL *)containsMediaRef containsPhotos:(BOOL *)containsPhotosRef containsVideos:(BOOL *)containsVideosRef; + (BOOL)shareMediaContentContainsPhotosAndVideos:(FBSDKShareMediaContent *)shareMediaContent; + (BOOL)validateAssetLibraryURLWithShareVideoContent:(FBSDKShareVideoContent *)videoContent name:(NSString *)name error:(NSError *__autoreleasing *)errorRef; + (BOOL)validateAssetLibraryURLsWithShareMediaContent:(FBSDKShareMediaContent *)mediaContent name:(NSString *)name error:(NSError *__autoreleasing *)errorRef; + (BOOL)validateShareContent:(id)shareContent error:(NSError *__autoreleasing *)errorRef; + (BOOL)validateShareLinkContent:(FBSDKShareLinkContent *)linkContent error:(NSError *__autoreleasing *)errorRef; + (BOOL)validateShareMediaContent:(FBSDKShareMediaContent *)mediaContent error:(NSError *__autoreleasing *)errorRef; + (BOOL)validateShareOpenGraphContent:(FBSDKShareOpenGraphContent *)openGraphContent error:(NSError *__autoreleasing *)errorRef; + (BOOL)validateSharePhotoContent:(FBSDKSharePhotoContent *)photoContent error:(NSError *__autoreleasing *)errorRef; + (NSString *)getOpenGraphNameAndNamespaceFromFullName:(NSString *)fullName namespace:(NSString **)namespace; #if !TARGET_OS_TV + (BOOL)validateAppInviteContent:(FBSDKAppInviteContent *)appInviteContent error:(NSError *__autoreleasing *)errorRef; + (BOOL)validateGameRequestContent:(FBSDKGameRequestContent *)gameRequestContent error:(NSError *__autoreleasing *)errorRef; #endif @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKShareUtility.h" #import #import "FBSDKCoreKit+Internal.h" #import "FBSDKShareConstants.h" #import "FBSDKShareError.h" #import "FBSDKShareLinkContent+Internal.h" #import "FBSDKShareMediaContent.h" #import "FBSDKShareOpenGraphContent.h" #import "FBSDKShareOpenGraphObject.h" #import "FBSDKSharePhoto.h" #import "FBSDKSharePhotoContent.h" #import "FBSDKShareVideo.h" #import "FBSDKShareVideoContent.h" #import "FBSDKSharingContent.h" @implementation FBSDKShareUtility #pragma mark - Class Methods + (void)assertCollection:(id)collection ofClassStrings:(NSArray *)classStrings name:(NSString *)name { for (id item in collection) { BOOL validClass = NO; for (NSString *classString in classStrings) { if ([item isKindOfClass:NSClassFromString(classString)]) { validClass = YES; break; } } if (!validClass) { NSString *reason = [[NSString alloc] initWithFormat: @"Invalid value found in %@: %@ - %@", name, item, collection]; @throw [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil]; } } } + (void)assertCollection:(id)collection ofClass:itemClass name:(NSString *)name { for (id item in collection) { if (![item isKindOfClass:itemClass]) { NSString *reason = [[NSString alloc] initWithFormat: @"Invalid value found in %@: %@ - %@", name, item, collection]; @throw [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil]; } } } + (void)assertOpenGraphKey:(id)key requireNamespace:(BOOL)requireNamespace { if (![key isKindOfClass:[NSString class]]) { NSString *reason = [[NSString alloc] initWithFormat:@"Invalid key found in Open Graph dictionary: %@", key]; @throw [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil]; } if (!requireNamespace) { return; } NSArray *components = [key componentsSeparatedByString:@":"]; if ([components count] < 2) { NSString *reason = [[NSString alloc] initWithFormat:@"Open Graph keys must be namespaced: %@", key]; @throw [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil]; } for (NSString *component in components) { if (![component length]) { NSString *reason = [[NSString alloc] initWithFormat:@"Invalid key found in Open Graph dictionary: %@", key]; @throw [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil]; } } } + (void)assertOpenGraphValue:(id)value { if ([self _isOpenGraphValue:value]) { return; } if ([value isKindOfClass:[NSDictionary class]]) { [self assertOpenGraphValues:(NSDictionary *)value requireKeyNamespace:YES]; return; } if ([value isKindOfClass:[NSArray class]]) { for (id subValue in (NSArray *)value) { [self assertOpenGraphValue:subValue]; } return; } NSString *reason = [[NSString alloc] initWithFormat:@"Invalid Open Graph value found: %@", value]; @throw [NSException exceptionWithName:NSInvalidArgumentException reason:reason userInfo:nil]; } + (void)assertOpenGraphValues:(NSDictionary *)dictionary requireKeyNamespace:(BOOL)requireKeyNamespace { [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { [self assertOpenGraphKey:key requireNamespace:requireKeyNamespace]; [self assertOpenGraphValue:value]; }]; } + (BOOL)buildWebShareContent:(id)content methodName:(NSString *__autoreleasing *)methodNameRef parameters:(NSDictionary *__autoreleasing *)parametersRef error:(NSError *__autoreleasing *)errorRef { NSString *methodName = nil; NSDictionary *parameters = nil; if ([content isKindOfClass:[FBSDKShareOpenGraphContent class]]) { methodName = @"share_open_graph"; FBSDKShareOpenGraphContent *openGraphContent = (FBSDKShareOpenGraphContent *)content; FBSDKShareOpenGraphAction *action = openGraphContent.action; NSDictionary *properties = [self _convertOpenGraphValueContainer:action requireNamespace:NO]; NSString *propertiesJSON = [FBSDKInternalUtility JSONStringForObject:properties error:errorRef invalidObjectHandler:NULL]; parameters = @{ @"action_type": action.actionType, @"action_properties": propertiesJSON, }; } else if ([content isKindOfClass:[FBSDKShareLinkContent class]]) { FBSDKShareLinkContent *linkContent = (FBSDKShareLinkContent *)content; methodName = @"share"; if (linkContent.contentURL != nil) { parameters = @{ @"href": linkContent.contentURL.absoluteString }; } } NSString *hashtagString = [self hashtagStringFromHashtag:content.hashtag]; if (hashtagString != nil) { NSMutableDictionary *mutableParameters = [parameters mutableCopy]; [FBSDKInternalUtility dictionary:mutableParameters setObject:hashtagString forKey:@"hashtag"]; parameters = [mutableParameters copy]; } if (methodNameRef != NULL) { *methodNameRef = methodName; } if (parametersRef != NULL) { *parametersRef = parameters; } if (errorRef != NULL) { *errorRef = nil; } return YES; } + (void)buildAsyncWebPhotoContent:(FBSDKSharePhotoContent *)content completionHandler:(void(^)(BOOL, NSString *, NSDictionary *))completion { void(^stageImageCompletion)(NSArray *) = ^(NSArray *stagedURIs) { NSString *methodName = @"share"; NSMutableDictionary *parameters = [[FBSDKShareUtility parametersForShareContent:content shouldFailOnDataError:NO] mutableCopy]; [parameters removeObjectForKey:@"photos"]; NSString *stagedURIJSONString = [FBSDKInternalUtility JSONStringForObject:stagedURIs error:nil invalidObjectHandler:NULL]; [FBSDKInternalUtility dictionary:parameters setObject:stagedURIJSONString forKey:@"media"]; NSString *hashtagString = [self hashtagStringFromHashtag:content.hashtag]; if (hashtagString != nil) { [FBSDKInternalUtility dictionary:parameters setObject:hashtagString forKey:@"hashtag"]; } if (completion != NULL) { completion(YES, methodName, [parameters copy]); } }; [self _stageImagesForPhotoContent:(FBSDKSharePhotoContent *)content withCompletionHandler:stageImageCompletion]; } + (id)convertOpenGraphValue:(id)value { if ([self _isOpenGraphValue:value]) { return value; } else if ([value isKindOfClass:[NSDictionary class]]) { NSDictionary *properties = (NSDictionary *)value; if ([FBSDKTypeUtility stringValue:properties[@"type"]]) { return [FBSDKShareOpenGraphObject objectWithProperties:properties]; } else { NSURL *imageURL = [FBSDKTypeUtility URLValue:properties[@"url"]]; if (imageURL) { FBSDKSharePhoto *sharePhoto = [FBSDKSharePhoto photoWithImageURL:imageURL userGenerated:[FBSDKTypeUtility boolValue:properties[@"user_generated"]]]; sharePhoto.caption = [FBSDKTypeUtility stringValue:properties[@"caption"]]; return sharePhoto; } else { return nil; } } } else if ([value isKindOfClass:[NSArray class]]) { NSMutableArray *array = [[NSMutableArray alloc] init]; for (id subValue in (NSArray *)value) { [FBSDKInternalUtility array:array addObject:[self convertOpenGraphValue:subValue]]; } return [array copy]; } else { return nil; } } + (NSDictionary *)convertOpenGraphValues:(NSDictionary *)dictionary { NSMutableDictionary *convertedDictionary = [[NSMutableDictionary alloc] init]; [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { [FBSDKInternalUtility dictionary:convertedDictionary setObject:[self convertOpenGraphValue:obj] forKey:key]; }]; return [convertedDictionary copy]; } + (NSDictionary *)feedShareDictionaryForContent:(id)content { NSMutableDictionary *parameters = nil; if ([content isKindOfClass:[FBSDKShareLinkContent class]]) { FBSDKShareLinkContent *linkContent = (FBSDKShareLinkContent *)content; parameters = [[NSMutableDictionary alloc] initWithDictionary:linkContent.feedParameters]; [FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentDescription forKey:@"description"]; [FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentURL forKey:@"link"]; [FBSDKInternalUtility dictionary:parameters setObject:linkContent.quote forKey:@"quote"]; [FBSDKInternalUtility dictionary:parameters setObject:[self hashtagStringFromHashtag:linkContent.hashtag] forKey:@"hashtag"]; [FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentTitle forKey:@"name"]; [FBSDKInternalUtility dictionary:parameters setObject:linkContent.imageURL forKey:@"picture"]; [FBSDKInternalUtility dictionary:parameters setObject:linkContent.ref forKey:@"ref"]; } return [parameters copy]; } + (NSString *)hashtagStringFromHashtag:(FBSDKHashtag *)hashtag { if (!hashtag) { return nil; } if (hashtag.isValid) { return hashtag.stringRepresentation; } else { [FBSDKLogger singleShotLogEntry:FBSDKLoggingBehaviorDeveloperErrors formatString:@"Invalid hashtag: '%@'", hashtag.stringRepresentation]; return nil; } } + (NSDictionary *)parametersForShareContent:(id)shareContent shouldFailOnDataError:(BOOL)shouldFailOnDataError { NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; [self _addToParameters:parameters forShareContent:shareContent]; parameters[@"dataFailuresFatal"] = @(shouldFailOnDataError); if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { [self _addToParameters:parameters forShareLinkContent:(FBSDKShareLinkContent *)shareContent]; } else if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) { [self _addToParameters:parameters forSharePhotoContent:(FBSDKSharePhotoContent *)shareContent]; } else if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { [self _addToParameters:parameters forShareVideoContent:(FBSDKShareVideoContent *)shareContent]; } else if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) { [self _addToParameters:parameters forShareOpenGraphContent:(FBSDKShareOpenGraphContent *)shareContent]; } return [parameters copy]; } + (void)testShareContent:(id)shareContent containsMedia:(BOOL *)containsMediaRef containsPhotos:(BOOL *)containsPhotosRef containsVideos:(BOOL *)containsVideosRef { BOOL containsMedia = NO; BOOL containsPhotos = NO; BOOL containsVideos = NO; if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { containsMedia = NO; containsPhotos = NO; containsVideos = NO; } else if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { containsMedia = YES; containsVideos = YES; containsPhotos = NO; } else if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) { [self _testObject:((FBSDKSharePhotoContent *)shareContent).photos containsMedia:&containsMedia containsPhotos:&containsPhotos containsVideos:&containsVideos]; } else if ([shareContent isKindOfClass:[FBSDKShareMediaContent class]]) { [self _testObject:((FBSDKShareMediaContent *)shareContent).media containsMedia:&containsMedia containsPhotos:&containsPhotos containsVideos:&containsVideos]; } else if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) { [self _testOpenGraphValueContainer:((FBSDKShareOpenGraphContent *)shareContent).action containsMedia:&containsMedia containsPhotos:&containsPhotos containsVideos:&containsVideos]; } if (containsMediaRef != NULL) { *containsMediaRef = containsMedia; } if (containsPhotosRef != NULL) { *containsPhotosRef = containsPhotos; } if (containsVideosRef != NULL) { *containsVideosRef = containsVideos; } } #if !TARGET_OS_TV + (BOOL)validateAppInviteContent:(FBSDKAppInviteContent *)appInviteContent error:(NSError *__autoreleasing *)errorRef { return ([self _validateRequiredValue:appInviteContent name:@"content" error:errorRef] && [self _validateRequiredValue:appInviteContent.appLinkURL name:@"appLinkURL" error:errorRef] && [self _validateNetworkURL:appInviteContent.appLinkURL name:@"appLinkURL" error:errorRef] && [self _validateNetworkURL:appInviteContent.appInvitePreviewImageURL name:@"appInvitePreviewImageURL" error:errorRef] && [self validatePromoCodeWithError:appInviteContent error:errorRef]); } + (BOOL)validatePromoCodeWithError:(FBSDKAppInviteContent *)appInviteContent error:(NSError *__autoreleasing *)errorRef { NSString *promoText = appInviteContent.promotionText; NSString *promoCode = appInviteContent.promotionCode; NSMutableCharacterSet *alphanumericWithSpaces = [NSMutableCharacterSet alphanumericCharacterSet]; [alphanumericWithSpaces formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]]; if ([promoText length] > 0 || [promoCode length] > 0) { // Check for validity of promo text and promo code. if (!([promoText length] > 0 && [promoText length] <= 80)) { if (errorRef != NULL) { *errorRef = [FBSDKError invalidArgumentErrorWithName:@"promotionText" value:promoText message:@"Invalid value for promotionText, promotionText has to be between 1 and 80 characters long."]; } return NO; } if (!([promoCode length] <= 10)) { if (errorRef != NULL) { *errorRef = [FBSDKError invalidArgumentErrorWithName:@"promotionCode" value:promoCode message:@"Invalid value for promotionCode, promotionCode has to be between 0 and 10 characters long and is required when promoCode is set."]; } return NO; } if ([promoText rangeOfCharacterFromSet:[alphanumericWithSpaces invertedSet]].location != NSNotFound) { if(errorRef != NULL) { *errorRef = [FBSDKError invalidArgumentErrorWithName:@"promotionText" value:promoText message:@"Invalid value for promotionText, promotionText can contain only alphanumeric characters and spaces."]; } return NO; } if ([promoCode length] > 0 && [promoCode rangeOfCharacterFromSet:[alphanumericWithSpaces invertedSet]].location != NSNotFound) { if (errorRef != NULL) { *errorRef = [FBSDKError invalidArgumentErrorWithName:@"promotionCode" value:promoCode message:@"Invalid value for promotionCode, promotionCode can contain only alphanumeric characters and spaces."]; } return NO; } } if (errorRef != NULL) { *errorRef = nil; } return YES; } #endif + (BOOL)validateAssetLibraryURLWithShareVideoContent:(FBSDKShareVideoContent *)videoContent name:(NSString *)name error:(NSError *__autoreleasing *)errorRef { FBSDKShareVideo *video = videoContent.video; NSURL *videoURL = video.videoURL; return [self _validateAssetLibraryVideoURL:videoURL name:name error:errorRef]; } + (BOOL)validateAssetLibraryURLsWithShareMediaContent:(FBSDKShareMediaContent *)mediaContent name:(NSString *)name error:(NSError *__autoreleasing *)errorRef { for (id media in mediaContent.media) { if ([media isKindOfClass:[FBSDKShareVideo class]]) { FBSDKShareVideo *video = (FBSDKShareVideo *)media; if (![self _validateAssetLibraryVideoURL:video.videoURL name:name error:errorRef]) { return NO; } } } return YES; } #if !TARGET_OS_TV + (BOOL)validateGameRequestContent:(FBSDKGameRequestContent *)gameRequestContent error:(NSError *__autoreleasing *)errorRef { if (![self _validateRequiredValue:gameRequestContent name:@"content" error:errorRef] || ![self _validateRequiredValue:gameRequestContent.message name:@"message" error:errorRef]) { return NO; } BOOL mustHaveobjectID = gameRequestContent.actionType == FBSDKGameRequestActionTypeSend || gameRequestContent.actionType == FBSDKGameRequestActionTypeAskFor; BOOL hasobjectID = [gameRequestContent.objectID length] > 0; if (mustHaveobjectID ^ hasobjectID) { if (errorRef != NULL) { NSString *message = @"The objectID is required when the actionType is either send or askfor."; *errorRef = [FBSDKShareError requiredArgumentErrorWithName:@"objectID" message:message]; } return NO; } BOOL hasTo = [gameRequestContent.recipients count] > 0; BOOL hasFilters = gameRequestContent.filters != FBSDKGameRequestFilterNone; BOOL hasSuggestions = [gameRequestContent.recipientSuggestions count] > 0; if (hasTo && hasFilters) { if (errorRef != NULL) { NSString *message = @"Cannot specify to and filters at the same time."; *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"recipients" value:gameRequestContent.recipients message:message]; } return NO; } if (hasTo && hasSuggestions) { if (errorRef != NULL) { NSString *message = @"Cannot specify to and suggestions at the same time."; *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"recipients" value:gameRequestContent.recipients message:message]; } return NO; } if (hasFilters && hasSuggestions) { if (errorRef != NULL) { NSString *message = @"Cannot specify filters and suggestions at the same time."; *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"recipientSuggestions" value:gameRequestContent.recipientSuggestions message:message]; } return NO; } if ([gameRequestContent.data length] > 255) { if (errorRef != NULL) { NSString *message = @"The data cannot be longer than 255 characters"; *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"data" value:gameRequestContent.data message:message]; } return NO; } if (errorRef != NULL) { *errorRef = nil; } return [self _validateArgumentWithName:@"actionType" value:gameRequestContent.actionType isIn:@[@(FBSDKGameRequestActionTypeNone), @(FBSDKGameRequestActionTypeSend), @(FBSDKGameRequestActionTypeAskFor), @(FBSDKGameRequestActionTypeTurn)] error:errorRef] && [self _validateArgumentWithName:@"filters" value:gameRequestContent.filters isIn:@[@(FBSDKGameRequestFilterNone), @(FBSDKGameRequestFilterAppUsers), @(FBSDKGameRequestFilterAppNonUsers)] error:errorRef]; } #endif + (BOOL)validateShareContent:(id)shareContent error:(NSError *__autoreleasing *)errorRef { if (![self _validateRequiredValue:shareContent name:@"shareContent" error:errorRef]) { return NO; } else if ([shareContent isKindOfClass:[FBSDKShareLinkContent class]]) { return [self validateShareLinkContent:(FBSDKShareLinkContent *)shareContent error:errorRef]; } else if ([shareContent isKindOfClass:[FBSDKSharePhotoContent class]]) { return [self validateSharePhotoContent:(FBSDKSharePhotoContent *)shareContent error:errorRef]; } else if ([shareContent isKindOfClass:[FBSDKShareVideoContent class]]) { return [self validateShareVideoContent:(FBSDKShareVideoContent *)shareContent error:errorRef]; } else if ([shareContent isKindOfClass:[FBSDKShareMediaContent class]]) { return [self validateShareMediaContent:(FBSDKShareMediaContent *)shareContent error:errorRef]; } else if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) { return [self validateShareOpenGraphContent:(FBSDKShareOpenGraphContent *)shareContent error:errorRef]; } else { if (errorRef != NULL) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"shareContent" value:shareContent message:nil]; } return NO; } } + (BOOL)validateShareOpenGraphContent:(FBSDKShareOpenGraphContent *)openGraphContent error:(NSError *__autoreleasing *)errorRef { FBSDKShareOpenGraphAction *action = openGraphContent.action; NSString *previewPropertyName = openGraphContent.previewPropertyName; id object = action[previewPropertyName]; return ([self _validateRequiredValue:openGraphContent name:@"shareContent" error:errorRef] && [self _validateRequiredValue:action name:@"action" error:errorRef] && [self _validateRequiredValue:previewPropertyName name:@"previewPropertyName" error:errorRef] && [self _validateRequiredValue:object name:previewPropertyName error:errorRef]); } + (BOOL)validateSharePhotoContent:(FBSDKSharePhotoContent *)photoContent error:(NSError *__autoreleasing *)errorRef { NSArray *photos = photoContent.photos; if (![self _validateRequiredValue:photoContent name:@"shareContent" error:errorRef] || ![self _validateArray:photos minCount:1 maxCount:6 name:@"photos" error:errorRef]) { return NO; } for (FBSDKSharePhoto *photo in photos) { if (!photo.image) { if (errorRef != NULL) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"photos" value:photos message:@"photos must have UIImages"]; } return NO; } } return YES; } + (BOOL)validateShareMediaContent:(FBSDKShareMediaContent *)mediaContent error:(NSError *__autoreleasing *)errorRef { NSArray *medias = mediaContent.media; if (![self _validateRequiredValue:mediaContent name:@"shareContent" error:errorRef] || ![self _validateArray:medias minCount:1 maxCount:20 name:@"photos" error:errorRef]) { return NO; } for (id media in medias) { if ([media isKindOfClass:[FBSDKSharePhoto class]]) { FBSDKSharePhoto *photo = (FBSDKSharePhoto *)media; if (!photo.image) { if (errorRef != NULL) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"media" value:media message:@"photos must have UIImages"]; } return NO; } } else if ([media isKindOfClass:[FBSDKShareVideo class]]) { FBSDKShareVideo *video = (FBSDKShareVideo *)media; NSURL *videoURL = video.videoURL; return ([self _validateRequiredValue:video name:@"video" error:errorRef] && [self _validateRequiredValue:videoURL name:@"videoURL" error:errorRef]); } else { if (errorRef != NULL) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:@"media" value:media message:@"Only FBSDKSharePhoto and FBSDKShareVideo are allowed in `media` property"]; } return NO; } } return YES; } + (BOOL)validateShareLinkContent:(FBSDKShareLinkContent *)linkContent error:(NSError *__autoreleasing *)errorRef { return ([self _validateRequiredValue:linkContent name:@"shareContent" error:errorRef] && [self _validateNetworkURL:linkContent.contentURL name:@"contentURL" error:errorRef] && [self _validateNetworkURL:linkContent.imageURL name:@"imageURL" error:errorRef]); } + (BOOL)validateShareVideoContent:(FBSDKShareVideoContent *)videoContent error:(NSError *__autoreleasing *)errorRef { FBSDKShareVideo *video = videoContent.video; NSURL *videoURL = video.videoURL; return ([self _validateRequiredValue:videoContent name:@"videoContent" error:errorRef] && [self _validateRequiredValue:video name:@"video" error:errorRef] && [self _validateRequiredValue:videoURL name:@"videoURL" error:errorRef]); } + (BOOL)shareMediaContentContainsPhotosAndVideos:(FBSDKShareMediaContent *)shareMediaContent { BOOL containsPhotos = NO; BOOL containsVideos = NO; [self testShareContent:shareMediaContent containsMedia:NULL containsPhotos:&containsPhotos containsVideos:&containsVideos]; return containsVideos && containsPhotos; } #pragma mark - Object Lifecycle - (instancetype)init { FBSDK_NO_DESIGNATED_INITIALIZER(); return nil; } #pragma mark - Helper Methods + (void)_addToParameters:(NSMutableDictionary *)parameters forShareContent:(id)shareContent { NSString *hashtagString = [self hashtagStringFromHashtag:shareContent.hashtag]; if (hashtagString != nil) { [FBSDKInternalUtility dictionary:parameters setObject:@[hashtagString] forKey:@"hashtags"]; } if ([shareContent isKindOfClass:[FBSDKShareOpenGraphContent class]]) { FBSDKShareOpenGraphAction *action = ((FBSDKShareOpenGraphContent *)shareContent).action; [action setArray:shareContent.peopleIDs forKey:@"tags"]; [action setString:shareContent.placeID forKey:@"place"]; [action setString:shareContent.ref forKey:@"ref"]; } else { [FBSDKInternalUtility dictionary:parameters setObject:shareContent.peopleIDs forKey:@"tags"]; [FBSDKInternalUtility dictionary:parameters setObject:shareContent.placeID forKey:@"place"]; [FBSDKInternalUtility dictionary:parameters setObject:shareContent.ref forKey:@"ref"]; } } + (void)_addToParameters:(NSMutableDictionary *)parameters forShareOpenGraphContent:(FBSDKShareOpenGraphContent *)openGraphContent { NSString *previewPropertyName = [self getOpenGraphNameAndNamespaceFromFullName:openGraphContent.previewPropertyName namespace:nil]; [FBSDKInternalUtility dictionary:parameters setObject:previewPropertyName forKey:@"previewPropertyName"]; [FBSDKInternalUtility dictionary:parameters setObject:openGraphContent.action.actionType forKey:@"actionType"]; [FBSDKInternalUtility dictionary:parameters setObject:[self _convertOpenGraphValueContainer:openGraphContent.action requireNamespace:NO] forKey:@"action"]; } + (void)_addToParameters:(NSMutableDictionary *)parameters forSharePhotoContent:(FBSDKSharePhotoContent *)photoContent { [FBSDKInternalUtility dictionary:parameters setObject:[photoContent.photos valueForKeyPath:@"image"] forKey:@"photos"]; } + (void)_addToParameters:(NSMutableDictionary *)parameters forShareLinkContent:(FBSDKShareLinkContent *)linkContent { [FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentURL forKey:@"link"]; [FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentTitle forKey:@"name"]; [FBSDKInternalUtility dictionary:parameters setObject:linkContent.contentDescription forKey:@"description"]; [FBSDKInternalUtility dictionary:parameters setObject:linkContent.imageURL forKey:@"picture"]; } + (void)_addToParameters:(NSMutableDictionary *)parameters forShareVideoContent:(FBSDKShareVideoContent *)videoContent { NSMutableDictionary *videoParameters = [[NSMutableDictionary alloc] init]; FBSDKShareVideo *video = videoContent.video; NSURL *videoURL = video.videoURL; if (videoURL) { videoParameters[@"assetURL"] = videoURL; } [FBSDKInternalUtility dictionary:videoParameters setObject:[self _convertPhoto:videoContent.previewPhoto] forKey:@"previewPhoto"]; parameters[@"video"] = videoParameters; } + (id)_convertObject:(id)object { if ([object isKindOfClass:[FBSDKShareOpenGraphValueContainer class]]) { object = [self _convertOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)object requireNamespace:YES]; } else if ([object isKindOfClass:[FBSDKSharePhoto class]]) { object = [self _convertPhoto:(FBSDKSharePhoto *)object]; } else if ([object isKindOfClass:[NSArray class]]) { NSMutableArray *array = [[NSMutableArray alloc] init]; for (id item in (NSArray *)object) { [FBSDKInternalUtility array:array addObject:[self _convertObject:item]]; } object = array; } return object; } + (NSDictionary *)_convertOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)container requireNamespace:(BOOL)requireNamespace { NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; NSMutableDictionary *data = [[NSMutableDictionary alloc] init]; [container enumerateKeysAndObjectsUsingBlock:^(NSString *key, id object, BOOL *stop) { // if we have an FBSDKShareOpenGraphObject and a type, then we are creating a new object instance; set the flag if ([key isEqualToString:@"og:type"] && [container isKindOfClass:[FBSDKShareOpenGraphObject class]]) { dictionary[@"fbsdk:create_object"] = @YES; dictionary[key] = object; } id value = [self _convertObject:object]; if (value) { NSString *namespace; key = [self getOpenGraphNameAndNamespaceFromFullName:key namespace:&namespace]; if (requireNamespace) { if ([namespace isEqualToString:@"og"]) { dictionary[key] = value; } else { data[key] = value; } } else { dictionary[key] = value; } } }]; if ([data count]) { dictionary[@"data"] = data; } return dictionary; } + (NSString *)getOpenGraphNameAndNamespaceFromFullName:(NSString *)fullName namespace:(NSString **)namespace { if (namespace) { *namespace = nil; } if ([fullName isEqualToString:@"fb:explicitly_shared"]) { return fullName; } NSUInteger index = [fullName rangeOfString:@":"].location; if ((index != NSNotFound) && (fullName.length > index + 1)) { if (namespace) { *namespace = [fullName substringToIndex:index]; } return [fullName substringFromIndex:index + 1]; } return fullName; } + (NSDictionary *)_convertPhoto:(FBSDKSharePhoto *)photo { if (!photo) { return nil; } NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; dictionary[@"user_generated"] = @(photo.userGenerated); [FBSDKInternalUtility dictionary:dictionary setObject:photo.caption forKey:@"caption"]; [FBSDKInternalUtility dictionary:dictionary setObject:photo.image ?: photo.imageURL.absoluteString forKey:@"url"]; return dictionary; } + (BOOL)_isOpenGraphValue:(id)value { return ((value == nil) || [value isKindOfClass:[NSNull class]] || [value isKindOfClass:[NSNumber class]] || [value isKindOfClass:[NSString class]] || [value isKindOfClass:[NSURL class]] || [value isKindOfClass:[FBSDKSharePhoto class]] || [value isKindOfClass:[FBSDKShareOpenGraphObject class]]); } + (void)_stageImagesForPhotoContent:(FBSDKSharePhotoContent *)content withCompletionHandler:(void(^)(NSArray *))completion { __block NSMutableArray *stagedURIs = [NSMutableArray array]; dispatch_group_t group = dispatch_group_create(); for (FBSDKSharePhoto *photo in content.photos) { if (photo.image != nil) { dispatch_group_enter(group); NSDictionary *stagingParameters = @{ @"file" : photo.image, }; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:@"me/staging_resources" parameters:stagingParameters HTTPMethod:@"POST"]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { NSString *photoStagedURI = result[@"uri"]; if (photoStagedURI != nil) { [stagedURIs addObject:photoStagedURI]; dispatch_group_leave(group); } }]; } } dispatch_group_notify(group, dispatch_get_main_queue(), ^{ if (completion != NULL) { completion([stagedURIs copy]); } }); } + (void)_testObject:(id)object containsMedia:(BOOL *)containsMediaRef containsPhotos:(BOOL *)containsPhotosRef containsVideos:(BOOL *)containsVideosRef { BOOL containsMedia = NO; BOOL containsPhotos = NO; BOOL containsVideos = NO; if ([object isKindOfClass:[FBSDKSharePhoto class]]) { containsMedia = (((FBSDKSharePhoto *)object).image != nil); containsPhotos = YES; } else if ([object isKindOfClass:[FBSDKShareVideo class]]) { containsMedia = YES; containsVideos = YES; } else if ([object isKindOfClass:[FBSDKShareOpenGraphValueContainer class]]) { [self _testOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)object containsMedia:&containsMedia containsPhotos:&containsPhotos containsVideos:&containsVideos]; } else if ([object isKindOfClass:[NSArray class]]) { for (id item in (NSArray *)object) { BOOL itemContainsMedia = NO; BOOL itemContainsPhotos = NO; BOOL itemContainsVideos = NO; [self _testObject:item containsMedia:&itemContainsMedia containsPhotos:&itemContainsPhotos containsVideos:&itemContainsVideos]; containsMedia |= itemContainsMedia; containsPhotos |= itemContainsPhotos; containsVideos |= itemContainsVideos; if (containsMedia && containsPhotos && containsVideos) { break; } } } if (containsMediaRef != NULL) { *containsMediaRef = containsMedia; } if (containsPhotosRef != NULL) { *containsPhotosRef = containsPhotos; } if (containsVideosRef != NULL) { *containsVideosRef = containsVideos; } } + (void)_testOpenGraphValueContainer:(FBSDKShareOpenGraphValueContainer *)container containsMedia:(BOOL *)containsMediaRef containsPhotos:(BOOL *)containsPhotosRef containsVideos:(BOOL *)containsVideosRef { __block BOOL containsMedia = NO; __block BOOL containsPhotos = NO; __block BOOL containsVideos = NO; [container enumerateKeysAndObjectsUsingBlock:^(NSString *key, id object, BOOL *stop) { BOOL itemContainsMedia = NO; BOOL itemContainsPhotos = NO; BOOL itemContainsVideos = NO; [self _testObject:object containsMedia:&itemContainsMedia containsPhotos:&itemContainsPhotos containsVideos:&itemContainsVideos]; containsMedia |= itemContainsMedia; containsPhotos |= itemContainsPhotos; containsVideos |= itemContainsVideos; if (containsMedia && containsPhotos && containsVideosRef) { *stop = YES; } }]; if (containsMediaRef != NULL) { *containsMediaRef = containsMedia; } if (containsPhotosRef != NULL) { *containsPhotosRef = containsPhotos; } if (containsVideosRef != NULL) { *containsVideosRef = containsVideos; } } + (BOOL)_validateArray:(NSArray *)array minCount:(NSUInteger)minCount maxCount:(NSUInteger)maxCount name:(NSString *)name error:(NSError *__autoreleasing *)errorRef { NSUInteger count = [array count]; if ((count < minCount) || (count > maxCount)) { if (errorRef != NULL) { NSString *message = [[NSString alloc] initWithFormat:@"%@ must have %lu to %lu values", name, (unsigned long)minCount, (unsigned long)maxCount]; *errorRef = [FBSDKShareError invalidArgumentErrorWithName:name value:array message:message]; } return NO; } else { if (errorRef != NULL) { *errorRef = nil; } return YES; } } + (BOOL)_validateFileURL:(NSURL *)URL name:(NSString *)name error:(NSError *__autoreleasing *)errorRef { if (!URL) { if (errorRef != NULL) { *errorRef = nil; } return YES; } if (!URL.isFileURL) { if (errorRef != NULL) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:name value:URL message:nil]; } return NO; } // ensure that the file exists. per the latest spec for NSFileManager, we should not be checking for file existence, // so they have removed that option for URLs and discourage it for paths, so we just construct a mapped NSData. NSError *fileError; if (![[NSData alloc] initWithContentsOfURL:URL options:NSDataReadingMapped error:&fileError]) { if (errorRef != NULL) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:name value:URL message:@"Error reading file" underlyingError:fileError]; } return NO; } if (errorRef != NULL) { *errorRef = nil; } return YES; } + (BOOL)_validateNetworkURL:(NSURL *)URL name:(NSString *)name error:(NSError *__autoreleasing *)errorRef { if (!URL || [FBSDKInternalUtility isBrowserURL:URL]) { if (errorRef != NULL) { *errorRef = nil; } return YES; } else { if (errorRef != NULL) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:name value:URL message:nil]; } return NO; } } + (BOOL)_validateRequiredValue:(id)value name:(NSString *)name error:(NSError *__autoreleasing *)errorRef { if (!value || ([value isKindOfClass:[NSString class]] && ![(NSString *)value length]) || ([value isKindOfClass:[NSArray class]] && ![(NSArray *)value count]) || ([value isKindOfClass:[NSDictionary class]] && ![(NSDictionary *)value count])) { if (errorRef != NULL) { *errorRef = [FBSDKShareError requiredArgumentErrorWithName:name message:nil]; } return NO; } if (errorRef != NULL) { *errorRef = nil; } return YES; } + (BOOL)_validateArgumentWithName:(NSString *)argumentName value:(NSUInteger)value isIn:(NSArray *)possibleValues error:(NSError *__autoreleasing *)errorRef { for (NSNumber *possibleValue in possibleValues) { if (value == [possibleValue unsignedIntegerValue]) { if (errorRef != NULL) { *errorRef = nil; } return YES; } } if (errorRef != NULL) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:argumentName value:@(value) message:nil]; } return NO; } + (BOOL)_validateAssetLibraryVideoURL:(NSURL *)videoURL name:(NSString *)name error:(NSError *__autoreleasing *)errorRef { if (!videoURL || [[videoURL.scheme lowercaseString] isEqualToString:@"assets-library"]) { if (errorRef != NULL) { *errorRef = nil; } return YES; } else { if (errorRef != NULL) { *errorRef = [FBSDKShareError invalidArgumentErrorWithName:name value:videoURL message:nil]; } return NO; } } @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.h ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import #import #import #import @protocol FBSDKVideoUploaderDelegate; /*! @abstract A utility class for uploading through the chunk upload graph API. Using this class requires an access token in `[FBSDKAccessToken currentAccessToken]` that has been granted the "publish_actions" permission. @discussion see https://developers.facebook.com/docs/graph-api/video-uploads */ @interface FBSDKVideoUploader : NSObject /*! @abstract Initialize videoUploader @param videoName The file name of the video to be uploaded @param videoSize The size of the video to be uploaded @param parameters Optional parameters for video uploads. See Graph API documentation for the full list of parameters https://developers.facebook.com/docs/graph-api/reference/video @param delegate Receiver's delegate */ - (instancetype)initWithVideoName:(NSString *)videoName videoSize:(NSUInteger)videoSize parameters:(NSDictionary *)parameters delegate:(id)delegate NS_DESIGNATED_INITIALIZER; /*! @abstract The video to be uploaded. */ @property (readonly, copy, nonatomic) FBSDKShareVideo *video; /*! @abstract Optional parameters for video uploads. See Graph API documentation for the full list of parameters https://developers.facebook.com/docs/graph-api/reference/video */ @property (copy, nonatomic) NSDictionary *parameters; /*! @abstract The graph node to which video should be uploaded */ @property (nonatomic, copy) NSString *graphNode; /*! @abstract Receiver's delegate */ @property (weak, nonatomic) id delegate; /*! @abstract Start upload process */ //TODO #6229672 add cancel and/or pause - (void)start; @end /*! @abstract A delegate for `FBSDKVideoUploader`. @discussion The delegate passes video chunk to `FBSDKVideoUploader` object in `NSData` format and is notified with the results of the uploader. */ @protocol FBSDKVideoUploaderDelegate /*! @abstract get chunk of the video to be uploaded in 'NSData' format @param videoUploader The `FBSDKVideoUploader` object which is performing the upload process @param startOffset The start offset of video chunk to be uploaded @param endOffset The end offset of video chunk being to be uploaded */ - (NSData *)videoChunkDataForVideoUploader:(FBSDKVideoUploader *)videoUploader startOffset:(NSUInteger) startOffset endOffset:(NSUInteger) endOffset; /*! @abstract Notify the delegate that upload process success. @param videoUploader The `FBSDKVideoUploader` object which is performing the upload process @param results The result from successful upload */ - (void)videoUploader:(FBSDKVideoUploader *)videoUploader didCompleteWithResults:(NSDictionary *)results; /*! @abstract Notify the delegate that upload process fails. @param videoUploader The `FBSDKVideoUploader` object which is performing the upload process @param error The error object from unsuccessful upload */ - (void)videoUploader:(FBSDKVideoUploader *)videoUploader didFailWithError:(NSError *)error; @end ================================================ FILE: Pods/FBSDKShareKit/FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.m ================================================ // Copyright (c) 2014-present, Facebook, Inc. All rights reserved. // // You are hereby granted a non-exclusive, worldwide, royalty-free license to use, // copy, modify, and distribute this software in source code or binary form for use // in connection with the web services and APIs provided by Facebook. // // As with any software that integrates with the Facebook platform, your use of // this software is subject to the Facebook Developer Principles and Policies // [http://developers.facebook.com/policy/]. This copyright notice shall be // included in all copies or substantial portions of the software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #import "FBSDKVideoUploader.h" #import #import #import #import "FBSDKShareDefines.h" #import "FBSDKShareError.h" static NSString *const FBSDKVideoUploaderDefaultGraphNode = @"me"; static NSString *const FBSDKVideoUploaderEdge = @"videos"; @implementation FBSDKVideoUploader { NSNumber *_videoID; NSNumber *_uploadSessionID; NSNumberFormatter *_numberFormatter; NSString *_graphPath; NSString *_videoName; NSUInteger _videoSize; } - (instancetype)init NS_UNAVAILABLE { assert(0); } #pragma Public Method - (instancetype)initWithVideoName:(NSString *)videoName videoSize:(NSUInteger)videoSize parameters:(NSDictionary *)parameters delegate:(id)delegate { self = [super init]; if (self) { _parameters = [parameters copy]; _delegate = delegate; _graphNode = FBSDKVideoUploaderDefaultGraphNode; _videoName = videoName; _videoSize = videoSize; } return self; } - (void)start { _graphPath = [self _graphPathWithSuffix:FBSDKVideoUploaderEdge, nil]; [self _postStartRequest]; } #pragma Helper Method - (void)_postStartRequest { FBSDKGraphRequestHandler startRequestCompletionHandler = ^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (error) { [self.delegate videoUploader:self didFailWithError:error]; return; } else { result = [FBSDKTypeUtility dictionaryValue:result]; NSNumber *uploadSessionID = [self.numberFormatter numberFromString:result[FBSDK_SHARE_VIDEO_UPLOAD_SESSION_ID]]; NSNumber *videoID = [self.numberFormatter numberFromString:result[FBSDK_SHARE_VIDEO_ID]]; NSDictionary *offsetDictionary = [self _extractOffsetsFromResultDictionary:result]; if (uploadSessionID == nil || videoID == nil) { [self.delegate videoUploader:self didFailWithError:[ FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode message:@"Failed to get valid upload_session_id or video_id."]]; return; } else if (offsetDictionary == nil) { return; } _uploadSessionID = uploadSessionID; _videoID = videoID; [self _startTransferRequestWithOffsetDictionary:offsetDictionary]; } }; if (_videoSize == 0) { [self.delegate videoUploader:self didFailWithError:[ FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode message:[NSString stringWithFormat:@"Invalid video size: %lu", (unsigned long)_videoSize]]]; return; } [[[FBSDKGraphRequest alloc] initWithGraphPath:_graphPath parameters:@{ FBSDK_SHARE_VIDEO_UPLOAD_PHASE: FBSDK_SHARE_VIDEO_UPLOAD_PHASE_START, FBSDK_SHARE_VIDEO_SIZE: [NSString stringWithFormat:@"%tu", _videoSize], } HTTPMethod:@"POST"] startWithCompletionHandler:startRequestCompletionHandler]; } - (void)_startTransferRequestWithOffsetDictionary:(NSDictionary *)offsetDictionary { dispatch_queue_t dataQueue; NSOperatingSystemVersion iOS8Version = { .majorVersion = 8, .minorVersion = 0, .patchVersion = 0 }; if ([FBSDKInternalUtility isOSRunTimeVersionAtLeast:iOS8Version]) { dataQueue = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0); } else { dataQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); } NSUInteger startOffset = [offsetDictionary[FBSDK_SHARE_VIDEO_START_OFFSET] unsignedIntegerValue]; NSUInteger endOffset = [offsetDictionary[FBSDK_SHARE_VIDEO_END_OFFSET] unsignedIntegerValue]; if (startOffset == endOffset) { [self _postFinishRequest]; return; } else { dispatch_async(dataQueue, ^{ size_t chunkSize = (unsigned long)(endOffset - startOffset); NSData *data = [self.delegate videoChunkDataForVideoUploader:self startOffset:startOffset endOffset:endOffset]; if (data == nil || data.length != chunkSize) { [self.delegate videoUploader:self didFailWithError:[FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode message: [NSString stringWithFormat:@"Fail to get video chunk with start offset: %lu, end offset : %lu.", (unsigned long)startOffset, (unsigned long)endOffset]]]; return; } dispatch_async(dispatch_get_main_queue(), ^{ FBSDKGraphRequestDataAttachment *dataAttachment = [[FBSDKGraphRequestDataAttachment alloc] initWithData:data filename:_videoName contentType:nil]; FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc] initWithGraphPath:_graphPath parameters:@{ FBSDK_SHARE_VIDEO_UPLOAD_PHASE: FBSDK_SHARE_VIDEO_UPLOAD_PHASE_TRANSFER, FBSDK_SHARE_VIDEO_START_OFFSET: offsetDictionary[FBSDK_SHARE_VIDEO_START_OFFSET], FBSDK_SHARE_VIDEO_UPLOAD_SESSION_ID: _uploadSessionID, FBSDK_SHARE_VIDEO_FILE_CHUNK: dataAttachment, } HTTPMethod:@"POST"]; [request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *innerError) { if (innerError) { [self.delegate videoUploader:self didFailWithError:innerError]; return; } NSDictionary *innerOffsetDictionary = [self _extractOffsetsFromResultDictionary:result]; if (innerOffsetDictionary == nil) { return; } [self _startTransferRequestWithOffsetDictionary:innerOffsetDictionary]; }]; }); }); } } - (void)_postFinishRequest { NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init]; parameters[FBSDK_SHARE_VIDEO_UPLOAD_PHASE] = FBSDK_SHARE_VIDEO_UPLOAD_PHASE_FINISH; parameters[FBSDK_SHARE_VIDEO_UPLOAD_SESSION_ID] = _uploadSessionID; [parameters addEntriesFromDictionary:self.parameters]; [[[FBSDKGraphRequest alloc] initWithGraphPath:_graphPath parameters:parameters HTTPMethod:@"POST"] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (error) { [self.delegate videoUploader:self didFailWithError:error]; } else { result = [FBSDKTypeUtility dictionaryValue:result]; if (result[FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS] == nil) { [self.delegate videoUploader:self didFailWithError:[FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode message:@"Failed to finish uploading."]]; return; } NSMutableDictionary *shareResult = [[NSMutableDictionary alloc] init]; shareResult[FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS] = result[FBSDK_SHARE_VIDEO_UPLOAD_SUCCESS]; shareResult[FBSDK_SHARE_RESULT_COMPLETION_GESTURE_KEY] = FBSDK_SHARE_RESULT_COMPLETION_GESTURE_VALUE_POST; shareResult[FBSDK_SHARE_VIDEO_ID] = _videoID; [self.delegate videoUploader:self didCompleteWithResults:shareResult]; } }]; } - (NSDictionary *)_extractOffsetsFromResultDictionary:(id)result { result = [FBSDKTypeUtility dictionaryValue:result]; NSNumber *startNum = [self.numberFormatter numberFromString:result[FBSDK_SHARE_VIDEO_START_OFFSET]]; NSNumber *endNum = [self.numberFormatter numberFromString:result[FBSDK_SHARE_VIDEO_END_OFFSET]]; if (startNum == nil || endNum == nil) { [self.delegate videoUploader:self didFailWithError:[FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode message:@"Fail to get valid start_offset or end_offset."]]; return nil; } if ([startNum compare:endNum] == NSOrderedDescending) { [self.delegate videoUploader:self didFailWithError:[FBSDKShareError errorWithCode:FBSDKShareUnknownErrorCode message:@"Invalid offset: start_offset is greater than end_offset."]]; return nil; } NSMutableDictionary *shareResults = [[NSMutableDictionary alloc] init]; shareResults[FBSDK_SHARE_VIDEO_START_OFFSET] = startNum; shareResults[FBSDK_SHARE_VIDEO_END_OFFSET] = endNum; return shareResults; } - (NSNumberFormatter *)numberFormatter { if (!_numberFormatter) { _numberFormatter = [[NSNumberFormatter alloc] init]; _numberFormatter.numberStyle = NSNumberFormatterDecimalStyle; } return _numberFormatter; } - (NSString *)_graphPathWithSuffix:(NSString *)suffix, ... NS_REQUIRES_NIL_TERMINATION { NSMutableString *graphPath = [[NSMutableString alloc] initWithString:self.graphNode]; va_list args; va_start(args, suffix); for (NSString *arg = suffix; arg != nil; arg = va_arg(args, NSString *)) { [graphPath appendFormat:@"/%@", arg]; } va_end(args); return graphPath; } @end ================================================ FILE: Pods/FBSDKShareKit/LICENSE ================================================ Copyright (c) 2014-present, Facebook, Inc. All rights reserved. You are hereby granted a non-exclusive, worldwide, royalty-free license to use, copy, modify, and distribute this software in source code or binary form for use in connection with the web services and APIs provided by Facebook. As with any software that integrates with the Facebook platform, your use of this software is subject to the Facebook Developer Principles and Policies [http://developers.facebook.com/policy/]. This copyright 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. ================================================ FILE: Pods/FBSDKShareKit/README.mdown ================================================ Facebook SDK for iOS ==================== This open-source library allows you to integrate Facebook into your iOS app. Learn more about the provided samples, documentation, integrating the SDK into your app, accessing source code, and more at https://developers.facebook.com/docs/ios NOTE: By default, the Facebook SDK for iOS is installed in ~/Documents/FacebookSDK TRY IT OUT ---------- 1. Download the SDK at https://developers.facebook.com/docs/ios or via CocoaPods by adding the 'FBSDKCoreKit', 'FBSDKLoginKit', and 'FBSDKShareKit' pods. 2. Test your install: build and run the project at ~/Documents/FacebookSDK/Samples/Scrumptious/Scrumptious.xcodeproj 3. Check-out the tutorials available online at: https://developers.facebook.com/docs/ios/getting-started 4. Start coding! Visit https://developers.facebook.com/docs/ios for tutorials and reference documentation. FEATURES -------- * Login - https://developers.facebook.com/docs/facebook-login * Sharing - https://developers.facebook.com/docs/sharing * App Links - https://developers.facebook.com/docs/applinks * Graph API - https://developers.facebook.com/docs/ios/graph * Analytics for Apps - https://developers.facebook.com/docs/analytics GIVE FEEDBACK ------------- Please report bugs or issues to https://developers.facebook.com/bugs/ You can also join the Facebook Developers Group on Facebook (https://www.facebook.com/groups/fbdevelopers/) or ask questions on Stack Overflow (http://facebook.stackoverflow.com) LICENSE ------- See the LICENSE file. DEVELOPER TERMS --------------- - By enabling Facebook integrations, including through this SDK, you can share information with Facebook, including information about people’s use of your app. Facebook will use information received in accordance with our Data Use Policy [https://www.facebook.com/about/privacy/], including to provide you with insights about the effectiveness of your ads and the use of your app. These integrations also enable us and our partners to serve ads on and off Facebook. - You may limit your sharing of information with us by updating the Insights control in the developer tool [https://developers.facebook.com/apps/{app_id}/settings/advanced]. - If you use a Facebook integration, including to share information with us, you agree and confirm that you have provided appropriate and sufficiently prominent notice to and obtained the appropriate consent from your users regarding such collection, use, and disclosure (including, at a minimum, through your privacy policy). You further agree that you will not share information with us about children under the age of 13. - You agree to comply with all applicable laws and regulations and also agree to our Terms , including our Platform Policies .and Advertising Guidelines, as applicable . By using the Facebook SDK for iOS you agree to these terms. ================================================ FILE: Pods/Firebase/Core/Sources/Firebase.h ================================================ #import #import #if !defined(__has_include) #error "Firebase.h won't import anything if your compiler doesn't support __has_include. Please \ import the headers individually." #else #if __has_include() #import #endif #if __has_include() #import #endif #if __has_include() #import #endif #if __has_include() #import #endif #if __has_include() #import #endif #if __has_include() #import #endif #if __has_include() #import #endif #if __has_include() #import #endif #if __has_include() #import #endif #if __has_include() #import #endif #if __has_include() #import #endif #endif // defined(__has_include) ================================================ FILE: Pods/Firebase/Core/Sources/module.modulemap ================================================ module Firebase { export * header "Firebase.h" } ================================================ FILE: Pods/Firebase/README.md ================================================ # Firebase APIs for iOS Simplify your iOS development, grow your user base, and monetize more effectively with Firebase services. Much more information can be found at [https://firebase.google.com](https://firebase.google.com). ## Install a Firebase SDK using CocoaPods Firebase distributes several iOS specific APIs and SDKs via CocoaPods. You can install the CocoaPods tool on OS X by running the following command from the terminal. Detailed information is available in the [Getting Started guide](https://guides.cocoapods.org/using/getting-started.html#getting-started). ``` $ sudo gem install cocoapods ``` ## Try out an SDK You can try any of the SDKs with `pod try`. Run the following command and select the SDK you are interested in when prompted: ``` $ pod try Firebase ``` Note that some SDKs may require credentials. More information is available in the SDK-specific documentation at [https://firebase.google.com/docs/](https://firebase.google.com/docs/). ## Add a Firebase SDK to your iOS app CocoaPods is used to install and manage dependencies in existing Xcode projects. 1. Create an Xcode project, and save it to your local machine. 2. Create a file named `Podfile` in your project directory. This file defines your project's dependencies, and is commonly referred to as a Podspec. 3. Open `Podfile`, and add your dependencies. A simple Podspec is shown here: ``` platform :ios, '7.0' pod 'Firebase' ``` 4. Save the file. 5. Open a terminal and `cd` to the directory containing the Podfile. ``` $ cd /project/ ``` 6. Run the `pod install` command. This will install the SDKs specified in the Podspec, along with any dependencies they may have. ``` $ pod install ``` 7. Open your app's `.xcworkspace` file to launch Xcode. Use this file for all development on your app. 8. You can also install other Firebase SDKs by adding the subspecs in the Podfile. ``` pod 'Firebase/AdMob' pod 'Firebase/Analytics' pod 'Firebase/AppIndexing' pod 'Firebase/Auth' pod 'Firebase/Crash' pod 'Firebase/Database' pod 'Firebase/DynamicLinks' pod 'Firebase/Invites' pod 'Firebase/Messaging' pod 'Firebase/RemoteConfig' pod 'Firebase/Storage' ``` ================================================ FILE: Pods/FirebaseAnalytics/Frameworks/frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h ================================================ #import #import "FIRAnalytics.h" /** * Provides App Delegate handlers to be used in your App Delegate. * * To save time integrating Firebase Analytics in an application, Firebase Analytics does not * require delegation implementation from the AppDelegate. Instead this is automatically done by * Firebase Analytics. Should you choose instead to delegate manually, you can turn off the App * Delegate Proxy by adding FirebaseAppDelegateProxyEnabled into your app's Info.plist and setting * it to NO, and adding the methods in this category to corresponding delegation handlers. * * To handle Universal Links, you must return YES in * [UIApplicationDelegate application:didFinishLaunchingWithOptions:]. */ @interface FIRAnalytics (AppDelegate) /** * Handles events related to a URL session that are waiting to be processed. * * For optimal use of Firebase Analytics, call this method from the * [UIApplicationDelegate application:handleEventsForBackgroundURLSession:completionHandler] * method of the app delegate in your app. * * @param identifier The identifier of the URL session requiring attention. * @param completionHandler The completion handler to call when you finish processing the events. * Calling this completion handler lets the system know that your app's user interface is * updated and a new snapshot can be taken. */ + (void)handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)(void))completionHandler; /** * Handles the event when the app is launched by a URL. * * Call this method from [UIApplicationDelegate application:openURL:options:] (on iOS 9.0 and * above), or [UIApplicationDelegate application:openURL:sourceApplication:annotation:] (on iOS 8.x * and below) in your app. * * @param url The URL resource to open. This resource can be a network resource or a file. */ + (void)handleOpenURL:(NSURL *)url; /** * Handles the event when the app receives data associated with user activity that includes a * Universal Link (on iOS 9.0 and above). * * Call this method from [UIApplication continueUserActivity:restorationHandler:] in your app * delegate (on iOS 9.0 and above). * * @param userActivity The activity object containing the data associated with the task the user * was performing. */ + (void)handleUserActivity:(id)userActivity; @end ================================================ FILE: Pods/FirebaseAnalytics/Frameworks/frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics.h ================================================ #import #import "FIREventNames.h" #import "FIRParameterNames.h" #import "FIRUserPropertyNames.h" /// The top level Firebase Analytics singleton that provides methods for logging events and setting /// user properties. See the developer guides for general /// information on using Firebase Analytics in your apps. @interface FIRAnalytics : NSObject /// Logs an app event. The event can have up to 25 parameters. Events with the same name must have /// the same parameters. Up to 500 event names are supported. Using predefined events and/or /// parameters is recommended for optimal reporting. /// /// The following event names are reserved and cannot be used: ///
    ///
  • app_clear_data
  • ///
  • app_remove
  • ///
  • app_update
  • ///
  • error
  • ///
  • first_open
  • ///
  • in_app_purchase
  • ///
  • notification_dismiss
  • ///
  • notification_foreground
  • ///
  • notification_open
  • ///
  • notification_receive
  • ///
  • os_update
  • ///
  • session_start
  • ///
  • user_engagement
  • ///
/// /// @param name The name of the event. Should contain 1 to 32 alphanumeric characters or /// underscores. The name must start with an alphabetic character. Some event names are /// reserved. See FIREventNames.h for the list of reserved event names. The "firebase_" prefix /// is reserved and should not be used. Note that event names are case-sensitive and that /// logging two events whose names differ only in case will result in two distinct events. /// @param parameters The dictionary of event parameters. Passing nil indicates that the event has /// no parameters. Parameter names can be up to 24 characters long and must start with an /// alphabetic character and contain only alphanumeric characters and underscores. Only NSString /// and NSNumber (signed 64-bit integer and 64-bit floating-point number) parameter types are /// supported. NSString parameter values can be up to 36 characters long. The "firebase_" prefix /// is reserved and should not be used for parameter names. + (void)logEventWithName:(nonnull NSString *)name parameters:(nullable NSDictionary *)parameters; /// Sets a user property to a given value. Up to 25 user property names are supported. Once set, /// user property values persist throughout the app lifecycle and across sessions. /// /// The following user property names are reserved and cannot be used: ///
    ///
  • first_open_time
  • ///
  • last_deep_link_referrer
  • ///
  • user_id
  • ///
/// /// @param value The value of the user property. Values can be up to 36 characters long. Setting the /// value to nil removes the user property. /// @param name The name of the user property to set. Should contain 1 to 24 alphanumeric characters /// or underscores and must start with an alphabetic character. The "firebase_" prefix is /// reserved and should not be used for user property names. + (void)setUserPropertyString:(nullable NSString *)value forName:(nonnull NSString *)name; /// Sets the user ID property. This feature must be used in accordance with /// Google's Privacy Policy /// /// @param userID The user ID to ascribe to the user of this app on this device, which must be /// non-empty and no more than 36 characters long. Setting userID to nil removes the user ID. + (void)setUserID:(nullable NSString *)userID; @end ================================================ FILE: Pods/FirebaseAnalytics/Frameworks/frameworks/FirebaseAnalytics.framework/Headers/FIRAnalyticsConfiguration.h ================================================ #import ================================================ FILE: Pods/FirebaseAnalytics/Frameworks/frameworks/FirebaseAnalytics.framework/Headers/FIRApp.h ================================================ #import ================================================ FILE: Pods/FirebaseAnalytics/Frameworks/frameworks/FirebaseAnalytics.framework/Headers/FIRConfiguration.h ================================================ #import ================================================ FILE: Pods/FirebaseAnalytics/Frameworks/frameworks/FirebaseAnalytics.framework/Headers/FIREventNames.h ================================================ /// @file FIREventNames.h /// /// Predefined event names. /// /// An Event is an important occurrence in your app that you want to measure. You can report up to /// 500 different types of Events per app and you can associate up to 25 unique parameters with each /// Event type. Some common events are suggested below, but you may also choose to specify custom /// Event types that are associated with your specific app. Each event type is identified by a /// unique name. Event names can be up to 32 characters long, may only contain alphanumeric /// characters and underscores ("_"), and must start with an alphabetic character. The "firebase_" /// prefix is reserved and should not be used. /// Add Payment Info event. This event signifies that a user has submitted their payment information /// to your app. static NSString *const kFIREventAddPaymentInfo = @"add_payment_info"; /// E-Commerce Add To Cart event. This event signifies that an item was added to a cart for /// purchase. Add this event to a funnel with kFIREventEcommercePurchase to gauge the effectiveness /// of your checkout process. Note: If you supply the {@link kFIRParameterValue} parameter, you must /// also supply the {@link kFIRParameterCurrency} parameter so that revenue metrics can be computed /// accurately. Params: /// ///
    ///
  • {@link kFIRParameterQuantity} (signed 64-bit integer as NSNumber)
  • ///
  • {@link kFIRParameterItemID} (NSString)
  • ///
  • {@link kFIRParameterItemName} (NSString)
  • ///
  • {@link kFIRParameterItemCategory} (NSString)
  • ///
  • {@link kFIRParameterItemLocationID} (NSString) (optional)
  • ///
  • {@link kFIRParameterPrice} (double as NSNumber) (optional)
  • ///
  • {@link kFIRParameterCurrency} (NSString) (optional)
  • ///
  • {@link kFIRParameterValue} (double as NSNumber) (optional)
  • ///
  • {@link kFIRParameterOrigin} (NSString) (optional)
  • ///
  • {@link kFIRParameterDestination} (NSString) (optional)
  • ///
  • {@link kFIRParameterStartDate} (NSString) (optional)
  • ///
  • {@link kFIRParameterEndDate} (NSString) (optional)
  • ///
static NSString *const kFIREventAddToCart = @"add_to_cart"; /// E-Commerce Add To Wishlist event. This event signifies that an item was added to a wishlist. /// Use this event to identify popular gift items in your app. Note: If you supply the /// {@link kFIRParameterValue} parameter, you must also supply the {@link kFIRParameterCurrency} /// parameter so that revenue metrics can be computed accurately. Params: /// ///
    ///
  • {@link kFIRParameterQuantity} (signed 64-bit integer as NSNumber)
  • ///
  • {@link kFIRParameterItemID} (NSString)
  • ///
  • {@link kFIRParameterItemName} (NSString)
  • ///
  • {@link kFIRParameterItemCategory} (NSString)
  • ///
  • {@link kFIRParameterItemLocationID} (NSString) (optional)
  • ///
  • {@link kFIRParameterPrice} (double as NSNumber) (optional)
  • ///
  • {@link kFIRParameterCurrency} (NSString) (optional)
  • ///
  • {@link kFIRParameterValue} (double as NSNumber) (optional)
  • ///
static NSString *const kFIREventAddToWishlist = @"add_to_wishlist"; /// App Open event. By logging this event when an App is moved to the foreground, developers can /// understand how often users leave and return during the course of a Session. Although Sessions /// are automatically reported, this event can provide further clarification around the continuous /// engagement of app-users. static NSString *const kFIREventAppOpen = @"app_open"; /// E-Commerce Begin Checkout event. This event signifies that a user has begun the process of /// checking out. Add this event to a funnel with your kFIREventEcommercePurchase event to gauge the /// effectiveness of your checkout process. Note: If you supply the {@link kFIRParameterValue} /// parameter, you must also supply the {@link kFIRParameterCurrency} parameter so that revenue /// metrics can be computed accurately. Params: /// ///
    ///
  • {@link kFIRParameterValue} (double as NSNumber) (optional)
  • ///
  • {@link kFIRParameterCurrency} (NSString) (optional)
  • ///
  • {@link kFIRParameterTransactionID} (NSString) (optional)
  • ///
  • {@link kFIRParameterStartDate} (NSString) (optional)
  • ///
  • {@link kFIRParameterEndDate} (NSString) (optional)
  • ///
  • {@link kFIRParameterNumberOfNights} (signed 64-bit integer as NSNumber) (optional) for /// hotel bookings
  • ///
  • {@link kFIRParameterNumberOfRooms} (signed 64-bit integer as NSNumber) (optional) for /// hotel bookings
  • ///
  • {@link kFIRParameterNumberOfPassengers} (signed 64-bit integer as NSNumber) (optional) /// for travel bookings
  • ///
  • {@link kFIRParameterOrigin} (NSString) (optional)
  • ///
  • {@link kFIRParameterDestination} (NSString) (optional)
  • ///
  • {@link kFIRParameterTravelClass} (NSString) (optional) for travel bookings
  • ///
static NSString *const kFIREventBeginCheckout = @"begin_checkout"; /// Earn Virtual Currency event. This event tracks the awarding of virtual currency in your app. Log /// this along with {@link kFIREventSpendVirtualCurrency} to better understand your virtual economy. /// Params: /// ///
    ///
  • {@link kFIRParameterVirtualCurrencyName} (NSString)
  • ///
  • {@link kFIRParameterValue} (signed 64-bit integer or double as NSNumber)
  • ///
static NSString *const kFIREventEarnVirtualCurrency = @"earn_virtual_currency"; /// E-Commerce Purchase event. This event signifies that an item was purchased by a user. Note: /// This is different from the in-app purchase event, which is reported automatically for App /// Store-based apps. Note: If you supply the {@link kFIRParameterValue} parameter, you must also /// supply the {@link kFIRParameterCurrency} parameter so that revenue metrics can be computed /// accurately. Params: /// ///
    ///
  • {@link kFIRParameterCurrency} (NSString) (optional)
  • ///
  • {@link kFIRParameterValue} (double as NSNumber) (optional)
  • ///
  • {@link kFIRParameterTransactionID} (NSString) (optional)
  • ///
  • {@link kFIRParameterTax} (double as NSNumber) (optional)
  • ///
  • {@link kFIRParameterShipping} (double as NSNumber) (optional)
  • ///
  • {@link kFIRParameterCoupon} (NSString) (optional)
  • ///
  • {@link kFIRParameterLocation} (NSString) (optional)
  • ///
  • {@link kFIRParameterStartDate} (NSString) (optional)
  • ///
  • {@link kFIRParameterEndDate} (NSString) (optional)
  • ///
  • {@link kFIRParameterNumberOfNights} (signed 64-bit integer as NSNumber) (optional) for /// hotel bookings
  • ///
  • {@link kFIRParameterNumberOfRooms} (signed 64-bit integer as NSNumber) (optional) for /// hotel bookings
  • ///
  • {@link kFIRParameterNumberOfPassengers} (signed 64-bit integer as NSNumber) (optional) /// for travel bookings
  • ///
  • {@link kFIRParameterOrigin} (NSString) (optional)
  • ///
  • {@link kFIRParameterDestination} (NSString) (optional)
  • ///
  • {@link kFIRParameterTravelClass} (NSString) (optional) for travel bookings
  • ///
static NSString *const kFIREventEcommercePurchase = @"ecommerce_purchase"; /// Generate Lead event. Log this event when a lead has been generated in the app to understand the /// efficacy of your install and re-engagement campaigns. Note: If you supply the /// {@link kFIRParameterValue} parameter, you must also supply the {@link kFIRParameterCurrency} /// parameter so that revenue metrics can be computed accurately. Params: /// ///
    ///
  • {@link kFIRParameterCurrency} (NSString) (optional)
  • ///
  • {@link kFIRParameterValue} (double as NSNumber) (optional)
  • ///
static NSString *const kFIREventGenerateLead = @"generate_lead"; /// Join Group event. Log this event when a user joins a group such as a guild, team or family. Use /// this event to analyze how popular certain groups or social features are in your app. Params: /// ///
    ///
  • {@link kFIRParameterGroupID} (NSString)
  • ///
static NSString *const kFIREventJoinGroup = @"join_group"; /// Level Up event. This event signifies that a player has leveled up in your gaming app. It can /// help you gauge the level distribution of your userbase and help you identify certain levels that /// are difficult to pass. Params: /// ///
    ///
  • {@link kFIRParameterLevel} (signed 64-bit integer as NSNumber)
  • ///
  • {@link kFIRParameterCharacter} (NSString) (optional)
  • ///
static NSString *const kFIREventLevelUp = @"level_up"; /// Login event. Apps with a login feature can report this event to signify that a user has logged /// in. static NSString *const kFIREventLogin = @"login"; /// Post Score event. Log this event when the user posts a score in your gaming app. This event can /// help you understand how users are actually performing in your game and it can help you correlate /// high scores with certain audiences or behaviors. Params: /// ///
    ///
  • {@link kFIRParameterScore} (signed 64-bit integer as NSNumber)
  • ///
  • {@link kFIRParameterLevel} (signed 64-bit integer as NSNumber) (optional)
  • ///
  • {@link kFIRParameterCharacter} (NSString) (optional)
  • ///
static NSString *const kFIREventPostScore = @"post_score"; /// Present Offer event. This event signifies that the app has presented a purchase offer to a user. /// Add this event to a funnel with the kFIREventAddToCart and kFIREventEcommercePurchase to gauge /// your conversion process. Note: If you supply the {@link kFIRParameterValue} parameter, you must /// also supply the {@link kFIRParameterCurrency} parameter so that revenue metrics can be computed /// accurately. Params: /// ///
    ///
  • {@link kFIRParameterQuantity} (signed 64-bit integer as NSNumber)
  • ///
  • {@link kFIRParameterItemID} (NSString)
  • ///
  • {@link kFIRParameterItemName} (NSString)
  • ///
  • {@link kFIRParameterItemCategory} (NSString)
  • ///
  • {@link kFIRParameterItemLocationID} (NSString) (optional)
  • ///
  • {@link kFIRParameterPrice} (double as NSNumber) (optional)
  • ///
  • {@link kFIRParameterCurrency} (NSString) (optional)
  • ///
  • {@link kFIRParameterValue} (double as NSNumber) (optional)
  • ///
static NSString *const kFIREventPresentOffer = @"present_offer"; /// E-Commerce Purchase Refund event. This event signifies that an item purchase was refunded. /// Note: If you supply the {@link kFIRParameterValue} parameter, you must also supply the /// {@link kFIRParameterCurrency} parameter so that revenue metrics can be computed accurately. /// Params: /// ///
    ///
  • {@link kFIRParameterCurrency} (NSString) (optional)
  • ///
  • {@link kFIRParameterValue} (double as NSNumber) (optional)
  • ///
  • {@link kFIRParameterTransactionID} (NSString) (optional)
  • ///
static NSString *const kFIREventPurchaseRefund = @"purchase_refund"; /// Search event. Apps that support search features can use this event to contextualize search /// operations by supplying the appropriate, corresponding parameters. This event can help you /// identify the most popular content in your app. Params: /// ///
    ///
  • {@link kFIRParameterSearchTerm} (NSString)
  • ///
  • {@link kFIRParameterStartDate} (NSString) (optional)
  • ///
  • {@link kFIRParameterEndDate} (NSString) (optional)
  • ///
  • {@link kFIRParameterNumberOfNights} (signed 64-bit integer as NSNumber) (optional) for /// hotel bookings
  • ///
  • {@link kFIRParameterNumberOfRooms} (signed 64-bit integer as NSNumber) (optional) for /// hotel bookings
  • ///
  • {@link kFIRParameterNumberOfPassengers} (signed 64-bit integer as NSNumber) (optional) /// for travel bookings
  • ///
  • {@link kFIRParameterOrigin} (NSString) (optional)
  • ///
  • {@link kFIRParameterDestination} (NSString) (optional)
  • ///
  • {@link kFIRParameterTravelClass} (NSString) (optional) for travel bookings
  • ///
static NSString *const kFIREventSearch = @"search"; /// Select Content event. This general purpose event signifies that a user has selected some content /// of a certain type in an app. The content can be any object in your app. This event can help you /// identify popular content and categories of content in your app. Params: /// ///
    ///
  • {@link kFIRParameterContentType} (NSString)
  • ///
  • {@link kFIRParameterItemID} (NSString)
  • ///
static NSString *const kFIREventSelectContent = @"select_content"; /// Share event. Apps with social features can log the Share event to identify the most viral /// content. Params: /// ///
    ///
  • {@link kFIRParameterContentType} (NSString)
  • ///
  • {@link kFIRParameterItemID} (NSString)
  • ///
static NSString *const kFIREventShare = @"share"; /// Sign Up event. This event indicates that a user has signed up for an account in your app. The /// parameter signifies the method by which the user signed up. Use this event to understand the /// different behaviors between logged in and logged out users. Params: /// ///
    ///
  • {@link kFIRParameterSignUpMethod} (NSString)
  • ///
static NSString *const kFIREventSignUp = @"sign_up"; /// Spend Virtual Currency event. This event tracks the sale of virtual goods in your app and can /// help you identify which virtual goods are the most popular objects of purchase. Params: /// ///
    ///
  • {@link kFIRParameterItemName} (NSString)
  • ///
  • {@link kFIRParameterVirtualCurrencyName} (NSString)
  • ///
  • {@link kFIRParameterValue} (signed 64-bit integer or double as NSNumber)
  • ///
static NSString *const kFIREventSpendVirtualCurrency = @"spend_virtual_currency"; /// Tutorial Begin event. This event signifies the start of the on-boarding process in your app. Use /// this in a funnel with kFIREventTutorialComplete to understand how many users complete this /// process and move on to the full app experience. static NSString *const kFIREventTutorialBegin = @"tutorial_begin"; /// Tutorial End event. Use this event to signify the user's completion of your app's on-boarding /// process. Add this to a funnel with kFIREventTutorialBegin to gauge the completion rate of your /// on-boarding process. static NSString *const kFIREventTutorialComplete = @"tutorial_complete"; /// Unlock Achievement event. Log this event when the user has unlocked an achievement in your /// game. Since achievements generally represent the breadth of a gaming experience, this event can /// help you understand how many users are experiencing all that your game has to offer. Params: /// ///
    ///
  • {@link kFIRParameterAchievementID} (NSString)
  • ///
static NSString *const kFIREventUnlockAchievement = @"unlock_achievement"; /// View Item event. This event signifies that some content was shown to the user. This content may /// be a product, a webpage or just a simple image or text. Use the appropriate parameters to /// contextualize the event. Use this event to discover the most popular items viewed in your app. /// Note: If you supply the {@link kFIRParameterValue} parameter, you must also supply the /// {@link kFIRParameterCurrency} parameter so that revenue metrics can be computed accurately. /// Params: /// ///
    ///
  • {@link kFIRParameterItemID} (NSString)
  • ///
  • {@link kFIRParameterItemName} (NSString)
  • ///
  • {@link kFIRParameterItemCategory} (NSString)
  • ///
  • {@link kFIRParameterItemLocationID} (NSString) (optional)
  • ///
  • {@link kFIRParameterPrice} (double as NSNumber) (optional)
  • ///
  • {@link kFIRParameterQuantity} (signed 64-bit integer as NSNumber) (optional)
  • ///
  • {@link kFIRParameterCurrency} (NSString) (optional)
  • ///
  • {@link kFIRParameterValue} (double as NSNumber) (optional)
  • ///
  • {@link kFIRParameterStartDate} (NSString) (optional)
  • ///
  • {@link kFIRParameterEndDate} (NSString) (optional)
  • ///
  • {@link kFIRParameterFlightNumber} (NSString) (optional) for travel bookings
  • ///
  • {@link kFIRParameterNumberOfPassengers} (signed 64-bit integer as NSNumber) (optional) /// for travel bookings
  • ///
  • {@link kFIRParameterNumberOfNights} (signed 64-bit integer as NSNumber) (optional) for /// travel bookings
  • ///
  • {@link kFIRParameterNumberOfRooms} (signed 64-bit integer as NSNumber) (optional) for /// travel bookings
  • ///
  • {@link kFIRParameterOrigin} (NSString) (optional)
  • ///
  • {@link kFIRParameterDestination} (NSString) (optional)
  • ///
  • {@link kFIRParameterSearchTerm} (NSString) (optional) for travel bookings
  • ///
  • {@link kFIRParameterTravelClass} (NSString) (optional) for travel bookings
  • ///
static NSString *const kFIREventViewItem = @"view_item"; /// View Item List event. Log this event when the user has been presented with a list of items of a /// certain category. Params: /// ///
    ///
  • {@link kFIRParameterItemCategory} (NSString)
  • ///
static NSString *const kFIREventViewItemList = @"view_item_list"; /// View Search Results event. Log this event when the user has been presented with the results of a /// search. Params: /// ///
    ///
  • {@link kFIRParameterSearchTerm} (NSString)
  • ///
static NSString *const kFIREventViewSearchResults = @"view_search_results"; ================================================ FILE: Pods/FirebaseAnalytics/Frameworks/frameworks/FirebaseAnalytics.framework/Headers/FIROptions.h ================================================ #import ================================================ FILE: Pods/FirebaseAnalytics/Frameworks/frameworks/FirebaseAnalytics.framework/Headers/FIRParameterNames.h ================================================ /// @file FIRParameterNames.h /// /// Predefined event parameter names. /// /// Params supply information that contextualize Events. You can associate up to 25 unique Params /// with each Event type. Some Params are suggested below for certain common Events, but you are /// not limited to these. You may supply extra Params for suggested Events or custom Params for /// Custom events. Param names can be up to 24 characters long, may only contain alphanumeric /// characters and underscores ("_"), and must start with an alphabetic character. Param values can /// be up to 36 characters long. The "firebase_" prefix is reserved and should not be used. /// Game achievement ID (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterAchievementID : @"10_matches_won",
///       // ...
///     };
/// 
static NSString *const kFIRParameterAchievementID = @"achievement_id"; /// Character used in game (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterCharacter : @"beat_boss",
///       // ...
///     };
/// 
static NSString *const kFIRParameterCharacter = @"character"; /// Type of content selected (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterContentType : @"news article",
///       // ...
///     };
/// 
static NSString *const kFIRParameterContentType = @"content_type"; /// Coupon code for a purchasable item (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterCoupon : @"zz123",
///       // ...
///     };
/// 
static NSString *const kFIRParameterCoupon = @"coupon"; /// Purchase currency in 3-letter /// ISO_4217 format (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterCurrency : @"USD",
///       // ...
///     };
/// 
static NSString *const kFIRParameterCurrency = @"currency"; /// Flight or Travel destination (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterDestination : @"Mountain View, CA",
///       // ...
///     };
/// 
static NSString *const kFIRParameterDestination = @"destination"; /// The arrival date, check-out date or rental end date for the item. This should be in /// YYYY-MM-DD format (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterEndDate : @"2015-09-14",
///       // ...
///     };
/// 
static NSString *const kFIRParameterEndDate = @"end_date"; /// Flight number for travel events (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterFlightNumber : @"ZZ800",
///       // ...
///     };
/// 
static NSString *const kFIRParameterFlightNumber = @"flight_number"; /// Group/clan/guild ID (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterGroupID : @"g1",
///       // ...
///     };
/// 
static NSString *const kFIRParameterGroupID = @"group_id"; /// Item category (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterItemCategory : @"t-shirts",
///       // ...
///     };
/// 
static NSString *const kFIRParameterItemCategory = @"item_category"; /// Item ID (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterItemID : @"p7654",
///       // ...
///     };
/// 
static NSString *const kFIRParameterItemID = @"item_id"; /// The Google Place ID (NSString) that /// corresponds to the associated item. Alternatively, you can supply your own custom Location ID. ///
///     NSDictionary *params = @{
///       kFIRParameterItemLocationID : @"ChIJiyj437sx3YAR9kUWC8QkLzQ",
///       // ...
///     };
/// 
static NSString *const kFIRParameterItemLocationID = @"item_location_id"; /// Item name (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterItemName : @"abc",
///       // ...
///     };
/// 
static NSString *const kFIRParameterItemName = @"item_name"; /// Level in game (signed 64-bit integer as NSNumber). ///
///     NSDictionary *params = @{
///       kFIRParameterLevel : @(42),
///       // ...
///     };
/// 
static NSString *const kFIRParameterLevel = @"level"; /// Location (NSString). The Google Place ID /// that corresponds to the associated event. Alternatively, you can supply your own custom /// Location ID. ///
///     NSDictionary *params = @{
///       kFIRParameterLocation : @"ChIJiyj437sx3YAR9kUWC8QkLzQ",
///       // ...
///     };
/// 
static NSString *const kFIRParameterLocation = @"location"; /// Number of nights staying at hotel (signed 64-bit integer as NSNumber). ///
///     NSDictionary *params = @{
///       kFIRParameterNumberOfNights : @(3),
///       // ...
///     };
/// 
static NSString *const kFIRParameterNumberOfNights = @"number_of_nights"; /// Number of passengers traveling (signed 64-bit integer as NSNumber). ///
///     NSDictionary *params = @{
///       kFIRParameterNumberOfPassengers : @(11),
///       // ...
///     };
/// 
static NSString *const kFIRParameterNumberOfPassengers = @"number_of_passengers"; /// Number of rooms for travel events (signed 64-bit integer as NSNumber). ///
///     NSDictionary *params = @{
///       kFIRParameterNumberOfRooms : @(2),
///       // ...
///     };
/// 
static NSString *const kFIRParameterNumberOfRooms = @"number_of_rooms"; /// Flight or Travel origin (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterOrigin : @"Mountain View, CA",
///       // ...
///     };
/// 
static NSString *const kFIRParameterOrigin = @"origin"; /// Purchase price (double as NSNumber). ///
///     NSDictionary *params = @{
///       kFIRParameterPrice : @(1.0),
///       kFIRParameterCurrency : @"USD",  // e.g. $1.00 USD
///       // ...
///     };
/// 
static NSString *const kFIRParameterPrice = @"price"; /// Purchase quantity (signed 64-bit integer as NSNumber). ///
///     NSDictionary *params = @{
///       kFIRParameterQuantity : @(1),
///       // ...
///     };
/// 
static NSString *const kFIRParameterQuantity = @"quantity"; /// Score in game (signed 64-bit integer as NSNumber). ///
///     NSDictionary *params = @{
///       kFIRParameterScore : @(4200),
///       // ...
///     };
/// 
static NSString *const kFIRParameterScore = @"score"; /// The search string/keywords used (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterSearchTerm : @"periodic table",
///       // ...
///     };
/// 
static NSString *const kFIRParameterSearchTerm = @"search_term"; /// Shipping cost (double as NSNumber). ///
///     NSDictionary *params = @{
///       kFIRParameterShipping : @(9.50),
///       kFIRParameterCurrency : @"USD",  // e.g. $9.50 USD
///       // ...
///     };
/// 
static NSString *const kFIRParameterShipping = @"shipping"; /// Sign up method (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterSignUpMethod : @"google",
///       // ...
///     };
/// 
static NSString *const kFIRParameterSignUpMethod = @"sign_up_method"; /// The departure date, check-in date or rental start date for the item. This should be in /// YYYY-MM-DD format (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterStartDate : @"2015-09-14",
///       // ...
///     };
/// 
static NSString *const kFIRParameterStartDate = @"start_date"; /// Tax amount (double as NSNumber). ///
///     NSDictionary *params = @{
///       kFIRParameterTax : @(1.0),
///       kFIRParameterCurrency : @"USD",  // e.g. $1.00 USD
///       // ...
///     };
/// 
static NSString *const kFIRParameterTax = @"tax"; /// A single ID for a ecommerce group transaction (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterTransactionID : @"ab7236dd9823",
///       // ...
///     };
/// 
static NSString *const kFIRParameterTransactionID = @"transaction_id"; /// Travel class (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterTravelClass : @"business",
///       // ...
///     };
/// 
static NSString *const kFIRParameterTravelClass = @"travel_class"; /// A context-specific numeric value which is accumulated automatically for each event type. This is /// a general purpose parameter that is useful for accumulating a key metric that pertains to an /// event. Examples include revenue, distance, time and points. Value should be specified as signed /// 64-bit integer or double as NSNumber. Notes: Currency-related values should be supplied using /// double as NSNumber and must be accompanied by a {@link kFIRParameterCurrency} parameter. The /// valid range of accumulated values is [-9,223,372,036,854.77, 9,223,372,036,854.77]. ///
///     NSDictionary *params = @{
///       kFIRParameterValue : @(3.99),
///       kFIRParameterCurrency : @"USD",  // e.g. $3.99 USD
///       // ...
///     };
/// 
static NSString *const kFIRParameterValue = @"value"; /// Name of virtual currency type (NSString). ///
///     NSDictionary *params = @{
///       kFIRParameterVirtualCurrencyName : @"virtual_currency_name",
///       // ...
///     };
/// 
static NSString *const kFIRParameterVirtualCurrencyName = @"virtual_currency_name"; ================================================ FILE: Pods/FirebaseAnalytics/Frameworks/frameworks/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h ================================================ /// @file FIRUserPropertyNames.h /// /// Predefined user property names. /// /// A UserProperty is an attribute that describes the app-user. By supplying UserProperties, you can /// later analyze different behaviors of various segments of your userbase. You may supply up to 25 /// unique UserProperties per app, and you can use the name and value of your choosing for each one. /// UserProperty names can be up to 24 characters long, may only contain alphanumeric characters and /// underscores ("_"), and must start with an alphabetic character. UserProperty values can be up to /// 36 characters long. The "firebase_" prefix is reserved and should not be used. /// The method used to sign in. For example, "google", "facebook" or "twitter". static NSString *const kFIRUserPropertySignUpMethod = @"sign_up_method"; ================================================ FILE: Pods/FirebaseAnalytics/Frameworks/frameworks/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h ================================================ // Generated umbrella header for FirebaseAnalytics. #import "FIRAnalytics+AppDelegate.h" #import "FIRAnalytics.h" #import "FIRAnalyticsConfiguration.h" #import "FIRApp.h" #import "FIRConfiguration.h" #import "FIREventNames.h" #import "FIROptions.h" #import "FIRParameterNames.h" #import "FIRUserPropertyNames.h" ================================================ FILE: Pods/FirebaseAnalytics/Frameworks/frameworks/FirebaseAnalytics.framework/Modules/module.modulemap ================================================ framework module FirebaseAnalytics { export * umbrella header "FirebaseAnalytics.h" header "FIRAnalytics+AppDelegate.h" header "FIRAnalytics.h" header "FIRAnalyticsConfiguration.h" header "FIRApp.h" header "FIRConfiguration.h" header "FIREventNames.h" header "FIROptions.h" header "FIRParameterNames.h" header "FIRUserPropertyNames.h" link framework "AddressBook" link framework "StoreKit" link "c++" link "sqlite3" link "z" } ================================================ FILE: Pods/FirebaseAuth/CHANGELOG.md ================================================ # 2016-09-14 -- v3.0.5 - Works around a keychain issue in iOS 10 simulator. - Reports the correct error for invalid email when signing with email and password. # 2016-07-18 -- v3.0.4 - Fixes a race condition bug that could crash the app with an exception from NSURLSession on iOS 9. # 2016-06-20 -- v3.0.3 - Adds documentation for all possible errors returned by each method. - Improves error handling and messages for a variety of error conditions. - Whether or not an user is considered anonymous is now consistent with other platforms. - A saved signed in user is now siloed between different Firebase projects within the same app. # 2016-05-18 -- v3.0.2 - Initial public release. ================================================ FILE: Pods/FirebaseAuth/Frameworks/frameworks/FirebaseAuth.framework/Headers/FIRAuth.h ================================================ /** @file FIRAuth.h @brief Firebase Auth SDK @copyright Copyright 2015 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ #import #import @class FIRApp; @class FIRAuth; @class FIRAuthCredential; @class FIRUser; @protocol FIRAuthStateListener; NS_ASSUME_NONNULL_BEGIN /** @typedef FIRAuthStateDidChangeListenerHandle @brief The type of handle returned by @c FIRAuth.addAuthStateDidChangeListener:. */ typedef id FIRAuthStateDidChangeListenerHandle; /** @typedef FIRAuthStateDidChangeListenerBlock @brief The type of block which can be registered as a listener for auth state did change events. @param auth The @c FIRAuth object on which state changes occurred. @param user Optionally; the current signed in user, if any. */ typedef void(^FIRAuthStateDidChangeListenerBlock)(FIRAuth *auth, FIRUser *_Nullable user); /** @var FIRAuthStateDidChangeNotification @brief The name of the @c NSNotificationCenter notification which is posted when the auth state changes (for example, a new token has been produced, a user signs in or signs out). The object parameter of the notification is the sender @c FIRAuth instance. */ extern NSString *const FIRAuthStateDidChangeNotification; /** @typedef FIRAuthResultCallback @brief The type of block invoked when sign-in related events complete. @param user Optionally; the signed in user, if any. @param error Optionally; if an error occurs, this is the NSError object that describes the problem. Set to nil otherwise. */ typedef void (^FIRAuthResultCallback)(FIRUser *_Nullable user, NSError *_Nullable error); /** @typedef FIRProviderQueryCallback @brief The type of block invoked when a list of identity providers for a given email address is requested. @param providers Optionally; a list of provider identifiers, if any. @see FIRGoogleAuthProviderID etc. @param error Optionally; if an error occurs, this is the NSError object that describes the problem. Set to nil otherwise. */ typedef void (^FIRProviderQueryCallback)(NSArray *_Nullable providers, NSError *_Nullable error); /** @typedef FIRSendPasswordResetCallback @brief The type of block invoked when initiating a password reset. @param error Optionally; if an error occurs, this is the NSError object that describes the problem. Set to nil otherwise. */ typedef void (^FIRSendPasswordResetCallback)(NSError *_Nullable error); /** @class FIRAuth @brief Manages authentication for Firebase apps. @remarks This class is thread-safe. */ @interface FIRAuth : NSObject /** @fn auth @brief Gets the auth object for the default Firebase app. @remarks Thread safe. */ + (nullable FIRAuth *)auth NS_SWIFT_NAME(auth()); /** @fn authWithApp: @brief Gets the auth object for a @c FIRApp. @param app The @c FIRApp for which to retrieve the associated @c FIRAuth instance. @return The @c FIRAuth instance associated with the given @c FIRApp. */ + (nullable FIRAuth *)authWithApp:(FIRApp *)app; /** @property app @brief Gets the @c FIRApp object that this auth object is connected to. */ @property(nonatomic, weak, readonly, nullable) FIRApp *app; /** @property currentUser @brief Synchronously gets the cached current user, or null if there is none. */ @property(nonatomic, strong, readonly, nullable) FIRUser *currentUser; /** @fn init @brief Please access auth instances using @c FIRAuth.auth and @c FIRAuth.authForApp:. */ - (nullable instancetype)init NS_UNAVAILABLE; /** @fn fetchProvidersForEmail:completion: @brief Fetches the list of IdPs that can be used for signing in with the provided email address. Useful for an "identifier-first" sign-in flow. @param email The email address for which to obtain a list of identity providers. @param completion Optionally; a block which is invoked when the list of providers for the specified email address is ready or an error was encountered. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: - @c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed. - See @c FIRAuthErrors for a list of error codes that are common to all API methods. */ - (void)fetchProvidersForEmail:(NSString *)email completion:(nullable FIRProviderQueryCallback)completion; /** @fn signInWithEmail:password:completion: @brief Signs in using an email address and password. @param email The user's email address. @param password The user's password. @param completion Optionally; a block which is invoked when the sign in flow finishes, or is canceled. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: - @c FIRAuthErrorCodeOperationNotAllowed Indicates that email and password accounts are not enabled. Enable them in the Auth section of the Firebase console. - @c FIRAuthErrorCodeUserDisabled Indicates the user's account is disabled. - @c FIRAuthErrorCodeWrongPassword Indicates the user attempted sign in with an incorrect password. - @c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed. - See @c FIRAuthErrors for a list of error codes that are common to all API methods. */ - (void)signInWithEmail:(NSString *)email password:(NSString *)password completion:(nullable FIRAuthResultCallback)completion; /** @fn signInWithCredential:completion: @brief Asynchronously signs in to Firebase with the given 3rd-party credentials (e.g. a Facebook login Access Token, a Google ID Token/Access Token pair, etc.) @param credential The credential supplied by the IdP. @param completion Optionally; a block which is invoked when the sign in flow finishes, or is canceled. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: - @c FIRAuthErrorCodeInvalidCredential Indicates the supplied credential is invalid. This could happen if it has expired or it is malformed. - @c FIRAuthErrorCodeOperationNotAllowed Indicates that accounts with the identity provider represented by the credential are not enabled. Enable them in the Auth section of the Firebase console. - @c FIRAuthErrorCodeEmailAlreadyInUse Indicates the email asserted by the credential (e.g. the email in a Facebook access token) is already in use by an existing account, that cannot be authenticated with this sign-in method. Call fetchProvidersForEmail for this user’s email and then prompt them to sign in with any of the sign-in providers returned. This error will only be thrown if the “One account per email address” setting is enabled in the Firebase console, under Auth settings. - Please note that the error code raised in this specific situation may not be the same on Web and Android. - @c FIRAuthErrorCodeUserDisabled Indicates the user's account is disabled. - @c FIRAuthErrorCodeWrongPassword Indicates the user attempted sign in with a incorrect password, if credential is of the type EmailPasswordAuthCredential. - @c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed. - See @c FIRAuthErrors for a list of error codes that are common to all API methods. */ - (void)signInWithCredential:(FIRAuthCredential *)credential completion:(nullable FIRAuthResultCallback)completion; /** @fn signInAnonymouslyWithCompletion: @brief Asynchronously creates and becomes an anonymous user. @param completion Optionally; a block which is invoked when the sign in finishes, or is canceled. Invoked asynchronously on the main thread in the future. @remarks If there is already an anonymous user signed in, that user will be returned instead. If there is any other existing user signed in, that user will be signed out. @remarks Possible error codes: - @c FIRAuthErrorCodeOperationNotAllowed Indicates that anonymous accounts are not enabled. Enable them in the Auth section of the Firebase console. - See @c FIRAuthErrors for a list of error codes that are common to all API methods. */ - (void)signInAnonymouslyWithCompletion:(nullable FIRAuthResultCallback)completion; /** @fn signInWithCustomToken:completion: @brief Asynchronously signs in to Firebase with the given Auth token. @param token A self-signed custom auth token. @param completion Optionally; a block which is invoked when the sign in finishes, or is canceled. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: - @c FIRAuthErrorCodeInvalidCustomToken Indicates a validation error with the custom token. - @c FIRAuthErrorCodeCustomTokenMismatch Indicates the service account and the API key belong to different projects. - See @c FIRAuthErrors for a list of error codes that are common to all API methods. */ - (void)signInWithCustomToken:(NSString *)token completion:(nullable FIRAuthResultCallback)completion; /** @fn createUserWithEmail:password:completion: @brief Creates and, on success, signs in a user with the given email address and password. @param email The user's email address. @param password The user's desired password. @param completion Optionally; a block which is invoked when the sign up flow finishes, or is canceled. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: - @c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed. - @c FIRAuthErrorCodeEmailAlreadyInUse Indicates the email used to attempt sign up already exists. Call fetchProvidersForEmail to check which sign-in mechanisms the user used, and prompt the user to sign in with one of those. - @c FIRAuthErrorCodeOperationNotAllowed Indicates that email and password accounts are not enabled. Enable them in the Auth section of the Firebase console. - @c FIRAuthErrorCodeWeakPassword Indicates an attempt to set a password that is considered too weak. The NSLocalizedFailureReasonErrorKey field in the NSError.userInfo dictionary object will contain more detailed explanation that can be shown to the user. - See @c FIRAuthErrors for a list of error codes that are common to all API methods. */ - (void)createUserWithEmail:(NSString *)email password:(NSString *)password completion:(nullable FIRAuthResultCallback)completion; /** @fn sendPasswordResetWithEmail:completion: @brief Initiates a password reset for the given email address. @param email The email address of the user. @param completion Optionally; a block which is invoked when the request finishes. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: - See @c FIRAuthErrors for a list of error codes that are common to all API methods. */ - (void)sendPasswordResetWithEmail:(NSString *)email completion:(nullable FIRSendPasswordResetCallback)completion; /** @fn signOut: @brief Signs out the current user. @param error Optionally; if an error occurs, upon return contains an NSError object that describes the problem; is nil otherwise. @return @YES when the sign out request was successful. @NO otherwise. @remarks Possible error codes: - @c FIRAuthErrorCodeKeychainError Indicates an error occurred when accessing the keychain. The @c NSLocalizedFailureReasonErrorKey field in the @c NSError.userInfo dictionary will contain more information about the error encountered. */ - (BOOL)signOut:(NSError *_Nullable *_Nullable)error; /** @fn addAuthStateDidChangeListener: @brief Registers a block as an "auth state did change" listener. To be invoked when: - The block is registered as a listener, - The current user changes, or, - The current user's access token changes. @param listener The block to be invoked. The block is always invoked asynchronously on the main thread, even for it's initial invocation after having been added as a listener. @remarks The block is invoked immediately after adding it according to it's standard invocation semantics, asynchronously on the main thread. Users should pay special attention to making sure the block does not inadvertently retain objects which should not be retained by the long-lived block. The block itself will be retained by @c FIRAuth until it is unregistered or until the @c FIRAuth instance is otherwise deallocated. @return A handle useful for manually unregistering the block as a listener. */ - (FIRAuthStateDidChangeListenerHandle)addAuthStateDidChangeListener: (FIRAuthStateDidChangeListenerBlock)listener; /** @fn removeAuthStateDidChangeListener: @brief Unregisters a block as an "auth state did change" listener. @param listenerHandle The handle for the listener. */ - (void)removeAuthStateDidChangeListener:(FIRAuthStateDidChangeListenerHandle)listenerHandle; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseAuth/Frameworks/frameworks/FirebaseAuth.framework/Headers/FIRAuthCredential.h ================================================ /** @file FIRAuthCredential.h @brief Firebase Auth SDK @copyright Copyright 2015 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ #import NS_ASSUME_NONNULL_BEGIN /** @class FIRAuthCredential @brief Represents a credential. */ @interface FIRAuthCredential : NSObject /** @property provider @brief Gets the name of the identity provider for the credential. */ @property(nonatomic, copy, readonly) NSString *provider; /** @fn init @brief This is an abstract base class. Concrete instances should be created via factory methods available in the various authentication provider libraries (like the Facebook provider or the Google provider libraries.) */ - (nullable instancetype)init NS_UNAVAILABLE; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseAuth/Frameworks/frameworks/FirebaseAuth.framework/Headers/FIRAuthErrors.h ================================================ /** @file FIRAuthErrors.h @brief Firebase Auth SDK @copyright Copyright 2015 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ #import /** @class FIRAuthErrors @remarks Error Codes common to all API Methods: - FIRAuthErrorCodeNetworkError - Indicates a network error occurred during the operation. - FIRAuthErrorCodeUserNotFound - Indicates the user account was not found. This could happen if the user account has been deleted. - FIRAuthErrorCodeUserTokenExpired - Indicates the current user’s token has expired, for example, the user may have changed account password on another device. You must prompt the user to sign in again on this device. - FIRAuthErrorCodeTooManyRequests - Indicates that the request has been blocked after an abnormal number of requests have been made from the caller device to the Firebase Auth servers. Retry again after some time. - FIRAuthErrorCodeInvalidAPIKey - Indicates the application has been configured with an invalid API key. - FIRAuthErrorCodeAppNotAuthorized - Indicates the App is not authorized to use Firebase Authentication with the provided API Key. Go to the Google API Console and check under the credentials tab that the API key you are using has your application’s bundle ID whitelisted. - FIRAuthErrorCodeKeychainError - Indicates an error occurred while accessing the keychain. The NSLocalizedFailureReasonErrorKey and NSUnderlyingErrorKey fields in the NSError.userInfo dictionary will contain more information about the error encountered. - FIRAuthErrorCodeInternalError - Indicates an internal error occurred. Please report the error back to us with the entire NSError object. @remarks Common error codes for FIRUser operations: - FIRAuthErrorCodeInvalidUserToken - Indicates that the signed-in user's refresh token, that holds session information, is invalid. You must prompt the user to sign in again on this device. - FIRAuthErrorCodeUserDisabled - Indicates the user's account is disabled and can no longer be used until enabled again from within the Users panel in the Firebase console. */ @interface FIRAuthErrors /** @var FIRAuthErrorDomain @brief The Firebase Auth error domain. */ extern NSString *const FIRAuthErrorDomain; /** @var FIRAuthErrorNameKey @brief The name of the key for the "error_name" string in the NSError userinfo dictionary. */ extern NSString *const FIRAuthErrorNameKey; /** @enum FIRAuthErrorCode @brief Error codes used by Firebase Auth. */ typedef NS_ENUM(NSInteger, FIRAuthErrorCode) { /** Indicates a validation error with the custom token. */ FIRAuthErrorCodeInvalidCustomToken = 17000, /** Indicates the service account and the API key belong to different projects. */ FIRAuthErrorCodeCustomTokenMismatch = 17002, /** Indicates the IDP token or requestUri is invalid. */ FIRAuthErrorCodeInvalidCredential = 17004, /** Indicates the user's account is disabled on the server. */ FIRAuthErrorCodeUserDisabled = 17005, /** Indicates the administrator disabled sign in with the specified identity provider. */ FIRAuthErrorCodeOperationNotAllowed = 17006, /** Indicates the email used to attempt a sign up is already in use. */ FIRAuthErrorCodeEmailAlreadyInUse = 17007, /** Indicates the email is invalid. */ FIRAuthErrorCodeInvalidEmail = 17008, /** Indicates the user attempted sign in with a wrong password. */ FIRAuthErrorCodeWrongPassword = 17009, /** Indicates that too many requests were made to a server method. */ FIRAuthErrorCodeTooManyRequests = 17010, /** Indicates the user account was not found. */ FIRAuthErrorCodeUserNotFound = 17011, /** Indicates account linking is required. */ FIRAuthErrorCodeAccountExistsWithDifferentCredential = 17012, /** Same enum as @c FIRAuthErrorCodeAccountExistsWithDifferentCredential , but with incorrect spelling. Only exists for backwards compatiblity. */ FIRAuthErrrorCodeAccountExistsWithDifferentCredential = 17012, /** Indicates the user has attemped to change email or password more than 5 minutes after signing in. */ FIRAuthErrorCodeRequiresRecentLogin = 17014, /** Indicates an attempt to link a provider to which the account is already linked. */ FIRAuthErrorCodeProviderAlreadyLinked = 17015, /** Indicates an attempt to unlink a provider that is not linked. */ FIRAuthErrorCodeNoSuchProvider = 17016, /** Indicates user's saved auth credential is invalid, the user needs to sign in again. */ FIRAuthErrorCodeInvalidUserToken = 17017, /** Indicates a network error occurred (such as a timeout, interrupted connection, or unreachable host). These types of errors are often recoverable with a retry. The @c NSUnderlyingError field in the @c NSError.userInfo dictionary will contain the error encountered. */ FIRAuthErrorCodeNetworkError = 17020, /** Indicates the saved token has expired, for example, the user may have changed account password on another device. The user needs to sign in again on the device that made this request. */ FIRAuthErrorCodeUserTokenExpired = 17021, /** Indicates an invalid API key was supplied in the request. */ FIRAuthErrorCodeInvalidAPIKey = 17023, /** Indicates that an attempt was made to reauthenticate with a user which is not the current user. */ FIRAuthErrorCodeUserMismatch = 17024, /** Indicates an attempt to link with a credential that has already been linked with a different Firebase account */ FIRAuthErrorCodeCredentialAlreadyInUse = 17025, /** Indicates an attempt to set a password that is considered too weak. */ FIRAuthErrorCodeWeakPassword = 17026, /** Indicates the App is not authorized to use Firebase Authentication with the provided API Key. */ FIRAuthErrorCodeAppNotAuthorized = 17028, /** Indicates an error occurred while attempting to access the keychain. */ FIRAuthErrorCodeKeychainError = 17995, /** Indicates an internal error occurred. */ FIRAuthErrorCodeInternalError = 17999, }; @end ================================================ FILE: Pods/FirebaseAuth/Frameworks/frameworks/FirebaseAuth.framework/Headers/FIREmailPasswordAuthProvider.h ================================================ /** @file FIREmailPasswordAuthProvider.h @brief Firebase Auth SDK @copyright Copyright 2016 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ #import @class FIRAuthCredential; NS_ASSUME_NONNULL_BEGIN /** @var FIREmailPasswordAuthProviderID @brief A string constant identifying the email & password identity provider. */ extern NSString *const FIREmailPasswordAuthProviderID; /** @class FIREmailPasswordAuthProvider @brief A concrete implementation of @c FIRAuthProvider for Email & Password Sign In. */ @interface FIREmailPasswordAuthProvider : NSObject /** @fn credentialWithEmail:password: @brief Creates an @c FIRAuthCredential for an email & password sign in. @param email The user's email address. @param password The user's password. @return A @c FIRAuthCredential containing the email & password credential. */ + (FIRAuthCredential *)credentialWithEmail:(NSString *)email password:(NSString *)password; /** @fn init @brief This class is not meant to be initialized. */ - (nullable instancetype)init NS_UNAVAILABLE; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseAuth/Frameworks/frameworks/FirebaseAuth.framework/Headers/FIRFacebookAuthProvider.h ================================================ /** @file FIRFacebookAuthProvider.h @brief Firebase Auth SDK @copyright Copyright 2016 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ #import @class FIRAuthCredential; NS_ASSUME_NONNULL_BEGIN /** @var FIRFacebookAuthProviderID @brief A string constant identifying the Facebook identity provider. */ extern NSString *const FIRFacebookAuthProviderID; /** @class FIRFacebookAuthProvider @brief Utility class for constructing Facebook credentials. */ @interface FIRFacebookAuthProvider : NSObject /** @fn credentialWithAccessToken: @brief Creates an @c FIRAuthCredential for a Facebook sign in. @param accessToken The Access Token from Facebook. @return A @c FIRAuthCredential containing the Facebook credentials. */ + (FIRAuthCredential *)credentialWithAccessToken:(NSString *)accessToken; /** @fn init @brief This class should not be initialized. */ - (nullable instancetype)init NS_UNAVAILABLE; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseAuth/Frameworks/frameworks/FirebaseAuth.framework/Headers/FIRGitHubAuthProvider.h ================================================ /** @file FIRGitHubAuthProvider.h @brief Firebase Auth SDK @copyright Copyright 2016 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ #import @class FIRAuthCredential; NS_ASSUME_NONNULL_BEGIN /** @var FIRGitHubAuthProviderID @brief A string constant identifying the GitHub identity provider. */ extern NSString *const FIRGitHubAuthProviderID; /** @class FIRGitHubAuthProvider @brief Utility class for constructing GitHub credentials. */ @interface FIRGitHubAuthProvider : NSObject /** @fn credentialWithToken: @brief Creates an @c FIRAuthCredential for a GitHub sign in. @param token The GitHub OAuth access token. @return A @c FIRAuthCredential containing the GitHub credential. */ + (FIRAuthCredential *)credentialWithToken:(NSString *)token; /** @fn init @brief This class is not meant to be initialized. */ - (nullable instancetype)init NS_UNAVAILABLE; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseAuth/Frameworks/frameworks/FirebaseAuth.framework/Headers/FIRGoogleAuthProvider.h ================================================ /** @file FIRGoogleAuthProvider.h @brief Firebase Auth SDK @copyright Copyright 2016 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ #import @class FIRAuthCredential; NS_ASSUME_NONNULL_BEGIN /** @var FIRGoogleAuthProviderID @brief A string constant identifying the Google identity provider. */ extern NSString *const FIRGoogleAuthProviderID; /** @class FIRGoogleAuthProvider @brief Utility class for constructing Google Sign In credentials. */ @interface FIRGoogleAuthProvider : NSObject /** @fn credentialWithIDToken:accessToken: @brief Creates an @c FIRAuthCredential for a Google sign in. @param IDToken The ID Token from Google. @param accessToken The Access Token from Google. @return A @c FIRAuthCredential containing the Google credentials. */ + (FIRAuthCredential *)credentialWithIDToken:(NSString *)IDToken accessToken:(NSString *)accessToken; /** @fn init @brief This class should not be initialized. */ - (nullable instancetype)init NS_UNAVAILABLE; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseAuth/Frameworks/frameworks/FirebaseAuth.framework/Headers/FIRTwitterAuthProvider.h ================================================ /** @file FIRTwitterAuthProvider.h @brief Firebase Auth SDK @copyright Copyright 2016 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ #import @class FIRAuthCredential; NS_ASSUME_NONNULL_BEGIN /** @var FIRTwitterAuthProviderID @brief A string constant identifying the Twitter identity provider. */ extern NSString *const FIRTwitterAuthProviderID; /** @class FIRTwitterAuthProvider @brief Utility class for constructing Twitter credentials. */ @interface FIRTwitterAuthProvider : NSObject /** @fn credentialWithToken:secret: @brief Creates an @c FIRAuthCredential for a Twitter sign in. @param token The Twitter OAuth token. @param secret The Twitter OAuth secret. @return A @c FIRAuthCredential containing the Twitter credential. */ + (FIRAuthCredential *)credentialWithToken:(NSString *)token secret:(NSString *)secret; /** @fn init @brief This class is not meant to be initialized. */ - (nullable instancetype)init NS_UNAVAILABLE; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseAuth/Frameworks/frameworks/FirebaseAuth.framework/Headers/FIRUser.h ================================================ /** @file FIRUser.h @brief Firebase Auth SDK @copyright Copyright 2015 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ #import #import #import @class FIRUserProfileChangeRequest; NS_ASSUME_NONNULL_BEGIN /** @typedef FIRAuthTokenCallback @brief The type of block called when a token is ready for use. @see FIRUser.getTokenWithCompletion: @see FIRUser.getTokenForcingRefresh:withCompletion: @param token Optionally; an access token if the request was successful. @param error Optionally; the error which occurred - or nil if the request was successful. @remarks One of: @c token or @c error will always be non-nil. */ typedef void (^FIRAuthTokenCallback)(NSString *_Nullable token, NSError *_Nullable error); /** @typedef FIRUserProfileChangeCallback @brief The type of block called when a user profile change has finished. @param error Optionally; the error which occurred - or nil if the request was successful. */ typedef void (^FIRUserProfileChangeCallback)(NSError *_Nullable error); /** @typedef FIRSendEmailVerificationCallback @brief The type of block called when a request to send an email verification has finished. @param error Optionally; the error which occurred - or nil if the request was successful. */ typedef void (^FIRSendEmailVerificationCallback)(NSError *_Nullable error); /** @class FIRUser @brief Represents a user. @remarks This class is thread-safe. */ @interface FIRUser : NSObject /** @property anonymous @brief Indicates the user represents an anonymous user. */ @property(nonatomic, readonly, getter=isAnonymous) BOOL anonymous; /** @property emailVerified @brief Indicates the email address associated with this user has been verified. */ @property(nonatomic, readonly, getter=isEmailVerified) BOOL emailVerified; /** @property refreshToken @brief A refresh token; useful for obtaining new access tokens independently. @remarks This property should only be used for advanced scenarios, and is not typically needed. */ @property(nonatomic, readonly, nullable) NSString *refreshToken; /** @property providerData @brief Profile data for each identity provider, if any. @remarks This data is cached on sign-in and updated when linking or unlinking. */ @property(nonatomic, readonly, nonnull) NSArray> *providerData; /** @fn init @brief This class should not be instantiated. @remarks To retrieve the current user, use @c FIRAuth.currentUser. To sign a user in or out, use the methods on @c FIRAuth. */ - (nullable instancetype)init NS_UNAVAILABLE; /** @fn updateEmail:completion: @brief Updates the email address for the user. On success, the cached user profile data is updated. @remarks May fail if there is already an account with this email address that was created using email and password authentication. @param email The email address for the user. @param completion Optionally; the block invoked when the user profile change has finished. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: - @c FIRAuthErrorCodeEmailAlreadyInUse - Indicates the email is already in use by another account. - @c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed. - @c FIRAuthErrorCodeRequiresRecentLogin - Updating a user’s email is a security sensitive operation that requires a recent login from the user. This error indicates the user has not signed in recently enough. To resolve, reauthenticate the user by invoking reauthenticateWithCredential:completion: on FIRUser. - See @c FIRAuthErrors for a list of error codes that are common to all FIRUser operations. */ - (void)updateEmail:(NSString *)email completion:(nullable FIRUserProfileChangeCallback)completion; /** @fn updatePassword:completion: @brief Updates the password for the user. On success, the cached user profile data is updated. @param password The new password for the user. @param completion Optionally; the block invoked when the user profile change has finished. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: - @c FIRAuthErrorCodeOperationNotAllowed - Indicates the administrator disabled sign in with the specified identity provider. - @c FIRAuthErrorCodeRequiresRecentLogin - Updating a user’s password is a security sensitive operation that requires a recent login from the user. This error indicates the user has not signed in recently enough. To resolve, reauthenticate the user by invoking reauthenticateWithCredential:completion: on FIRUser. - @c FIRAuthErrorCodeWeakPassword - Indicates an attempt to set a password that is considered too weak. The NSLocalizedFailureReasonErrorKey field in the NSError.userInfo dictionary object will contain more detailed explanation that can be shown to the user. - See @c FIRAuthErrors for a list of error codes that are common to all FIRUser operations. */ - (void)updatePassword:(NSString *)password completion:(nullable FIRUserProfileChangeCallback)completion; /** @fn profileChangeRequest @brief Creates an object which may be used to change the user's profile data. @remarks Set the properties of the returned object, then call @c FIRUserProfileChangeRequest.commitChangesWithCallback: to perform the updates atomically. @return An object which may be used to change the user's profile data atomically. */ - (FIRUserProfileChangeRequest *)profileChangeRequest; /** @fn reloadWithCompletion: @brief Reloads the user's profile data from the server. @param completion Optionally; the block invoked when the reload has finished. Invoked asynchronously on the main thread in the future. @remarks May fail with a @c FIRAuthErrorCodeCredentialTooOld error code. In this case you should call @c FIRUser.reauthenticateWithCredential:completion: before re-invoking @c FIRUser.updateEmail:completion:. @remarks Possible error codes: - See @c FIRAuthErrors for a list of error codes that are common to all API methods. */ - (void)reloadWithCompletion:(nullable FIRUserProfileChangeCallback)completion; /** @fn reauthenticateWithCredential:completion: @brief Renews the user's authentication tokens by validating a fresh set of credentials supplied by the user. @param credential A user-supplied credential, which will be validated by the server. This can be a successful third-party identity provider sign-in, or an email address and password. @param completion Optionally; the block invoked when the re-authentication operation has finished. Invoked asynchronously on the main thread in the future. @remarks If the user associated with the supplied credential is different from the current user, or if the validation of the supplied credentials fails; an error is returned and the current user remains signed in. @remarks Possible error codes: - @c FIRAuthErrorCodeInvalidCredential Indicates the supplied credential is invalid. This could happen if it has expired or it is malformed. - @c FIRAuthErrorCodeOperationNotAllowed Indicates that accounts with the identity provider represented by the credential are not enabled. Enable them in the Auth section of the Firebase console. - @c FIRAuthErrorCodeEmailAlreadyInUse Indicates the email asserted by the credential (e.g. the email in a Facebook access token) is already in use by an existing account, that cannot be authenticated with this method. Call fetchProvidersForEmail for this user’s email and then prompt them to sign in with any of the sign-in providers returned. This error will only be thrown if the “One account per email address” setting is enabled in the Firebase console, under Auth settings. - Please note that the error code raised in this specific situation may not be the same on Web and Android. - @c FIRAuthErrorCodeUserDisabled Indicates the user's account is disabled. - @c FIRAuthErrorCodeWrongPassword Indicates the user attempted reauthentication with an incorrect password, if credential is of the type EmailPasswordAuthCredential. - @c FIRAuthErrorCodeUserMismatch Indicates that an attempt was made to reauthenticate with a user which is not the current user. - @c FIRAuthErrorCodeInvalidEmail - Indicates the email address is malformed. - See @c FIRAuthErrors for a list of error codes that are common to all API methods. */ - (void)reauthenticateWithCredential:(FIRAuthCredential *)credential completion:(nullable FIRUserProfileChangeCallback)completion; /** @fn getTokenWithCompletion: @brief Retrieves the Firebase authentication token, possibly refreshing it if it has expired. @param completion Optionally; the block invoked when the token is available. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: - See @c FIRAuthErrors for a list of error codes that are common to all API methods. */ - (void)getTokenWithCompletion:(nullable FIRAuthTokenCallback)completion; /** @fn getTokenForcingRefresh:completion: @brief Retrieves the Firebase authentication token, possibly refreshing it if it has expired. @param forceRefresh Forces a token refresh. Useful if the token becomes invalid for some reason other than an expiration. @param completion Optionally; the block invoked when the token is available. Invoked asynchronously on the main thread in the future. @remarks The authentication token will be refreshed (by making a network request) if it has expired, or if @c forceRefresh is YES. @remarks Possible error codes: - See @c FIRAuthErrors for a list of error codes that are common to all API methods. */ - (void)getTokenForcingRefresh:(BOOL)forceRefresh completion:(nullable FIRAuthTokenCallback)completion; /** @fn linkWithCredential:completion: @brief Associates a user account from a third-party identity provider with this user. @param credential The credential for the identity provider. @param completion Optionally; the block invoked when the unlinking is complete, or fails. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: - @c FIRAuthErrorCodeProviderAlreadyLinked - Indicates an attempt to link a provider of a type already linked to this account. - @c FIRAuthErrorCodeCredentialAlreadyInUse - Indicates an attempt to link with a credential that has already been linked with a different Firebase account. - @c FIRAuthErrorCodeOperationNotAllowed - Indicates that accounts with the identity provider represented by the credential are not enabled. Enable them in the Auth section of the Firebase console. - This method may also return error codes associated with updateEmail:completion: and updatePassword:completion: on FIRUser. - See @c FIRAuthErrors for a list of error codes that are common to all FIRUser operations. */ - (void)linkWithCredential:(FIRAuthCredential *)credential completion:(nullable FIRAuthResultCallback)completion; /** @fn unlinkFromProvider:completion: @brief Disassociates a user account from a third-party identity provider with this user. @param provider The provider ID of the provider to unlink. @param completion Optionally; the block invoked when the unlinking is complete, or fails. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: - @c FIRAuthErrorCodeNoSuchProvider - Indicates an attempt to unlink a provider that is not linked to the account. - @c FIRAuthErrorCodeRequiresRecentLogin - Updating email is a security sensitive operation that requires a recent login from the user. This error indicates the user has not signed in recently enough. To resolve, reauthenticate the user by invoking reauthenticateWithCredential:completion: on FIRUser. - See @c FIRAuthErrors for a list of error codes that are common to all FIRUser operations. */ - (void)unlinkFromProvider:(NSString *)provider completion:(nullable FIRAuthResultCallback)completion; /** @fn sendEmailVerificationWithCompletion: @brief Initiates email verification for the user. @param completion Optionally; the block invoked when the request to send an email verification is complete, or fails. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: - @c FIRAuthErrorCodeUserNotFound - Indicates the user account was not found. - See @c FIRAuthErrors for a list of error codes that are common to all FIRUser operations. */ - (void)sendEmailVerificationWithCompletion:(nullable FIRSendEmailVerificationCallback)completion; /** @fn deleteWithCompletion: @brief Deletes the user account (also signs out the user, if this was the current user). @param completion Optionally; the block invoked when the request to delete the account is complete, or fails. Invoked asynchronously on the main thread in the future. @remarks Possible error codes: - @c FIRAuthErrorCodeRequiresRecentLogin - Updating email is a security sensitive operation that requires a recent login from the user. This error indicates the user has not signed in recently enough. To resolve, reauthenticate the user by invoking reauthenticateWithCredential:completion: on FIRUser. - See @c FIRAuthErrors for a list of error codes that are common to all FIRUser operations. */ - (void)deleteWithCompletion:(nullable FIRUserProfileChangeCallback)completion; @end /** @class FIRUserProfileChangeRequest @brief Represents an object capable of updating a user's profile data. @remarks Properties are marked as being part of a profile update when they are set. Setting a property value to nil is not the same as leaving the property unassigned. */ @interface FIRUserProfileChangeRequest : NSObject /** @fn init @brief Please use @c FIRUser.profileChangeRequest */ - (nullable instancetype)init NS_UNAVAILABLE; /** @property displayName @brief The user's display name. @remarks It is an error to set this property after calling @c FIRUserProfileChangeRequest.commitChangesWithCallback: */ @property(nonatomic, copy, nullable) NSString *displayName; /** @property photoURL @brief The user's photo URL. @remarks It is an error to set this property after calling @c FIRUserProfileChangeRequest.commitChangesWithCallback: */ @property(nonatomic, copy, nullable) NSURL *photoURL; /** @fn commitChangesWithCompletion: @brief Commits any pending changes. @remarks This method should only be called once. Once called, property values should not be changed. @param completion Optionally; the block invoked when the user profile change has been applied. Invoked asynchronously on the main thread in the future. */ - (void)commitChangesWithCompletion:(nullable FIRUserProfileChangeCallback)completion; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseAuth/Frameworks/frameworks/FirebaseAuth.framework/Headers/FIRUserInfo.h ================================================ /** @file FIRUserInfo.h @brief Firebase Auth SDK @copyright Copyright 2015 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ #import NS_ASSUME_NONNULL_BEGIN /** @protocol FIRUserInfo @brief Represents user data returned from an identity provider. */ @protocol FIRUserInfo /** @property providerID @brief The provider identifier. */ @property(nonatomic, copy, readonly) NSString *providerID; /** @property uid @brief The provider's user ID for the user. */ @property(nonatomic, copy, readonly) NSString *uid; /** @property displayName @brief The name of the user. */ @property(nonatomic, copy, readonly, nullable) NSString *displayName; /** @property photoURL @brief The URL of the user's profile photo. */ @property(nonatomic, copy, readonly, nullable) NSURL *photoURL; /** @property email @brief The user's email address. */ @property(nonatomic, copy, readonly, nullable) NSString *email; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseAuth/Frameworks/frameworks/FirebaseAuth.framework/Headers/FirebaseAuth.h ================================================ /** @file FirebaseAuth.h @brief Firebase Auth SDK @copyright Copyright 2015 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ #import #import #import #import #import #import #import #import #import #import /** @var FirebaseAuthVersionNumber @brief Version number for FirebaseAuth. */ extern const double FirebaseAuthVersionNumber; /** @var FirebaseAuthVersionString @brief Version string for FirebaseAuth. */ extern const unsigned char *const FirebaseAuthVersionString; ================================================ FILE: Pods/FirebaseAuth/Frameworks/frameworks/FirebaseAuth.framework/Modules/module.modulemap ================================================ framework module FirebaseAuth { umbrella header "FirebaseAuth.h" export * header "FIRAuth.h" header "FIRAuthCredential.h" header "FIRAuthErrors.h" header "FIREmailPasswordAuthProvider.h" header "FIRFacebookAuthProvider.h" header "FIRGitHubAuthProvider.h" header "FIRGoogleAuthProvider.h" header "FIRTwitterAuthProvider.h" header "FIRUser.h" header "FIRUserInfo.h" link framework "Security" use FirebaseAnalytics use GoogleUtilities use GoogleNetworkingUtilities } ================================================ FILE: Pods/FirebaseAuth/README.md ================================================ # Firebase Auth for iOS Firebase Auth enables apps to easily support multiple authentication options for their end users. Please visit [our developer site](https://developers.google.com/) for integration instructions, documentation, support information, and terms of service. ================================================ FILE: Pods/FirebaseCore/Frameworks/frameworks/FirebaseCore.framework/Headers/FIRAnalyticsConfiguration.h ================================================ #import /** * This class provides configuration fields for Firebase Analytics. */ @interface FIRAnalyticsConfiguration : NSObject /** * Returns the shared instance of FIRAnalyticsConfiguration. */ + (FIRAnalyticsConfiguration *)sharedInstance; /** * Sets the minimum engagement time in seconds required to start a new session. The default value * is 10 seconds. */ - (void)setMinimumSessionInterval:(NSTimeInterval)minimumSessionInterval; /** * Sets the interval of inactivity in seconds that terminates the current session. The default * value is 1800 seconds (30 minutes). */ - (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval; /** * Sets whether analytics collection is enabled for this app on this device. This setting is * persisted across app sessions. By default it is enabled. */ - (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled; /** * Deprecated. Sets whether measurement and reporting are enabled for this app on this device. By * default they are enabled. */ - (void)setIsEnabled:(BOOL)isEnabled DEPRECATED_MSG_ATTRIBUTE("Use setAnalyticsCollectionEnabled: instead."); @end ================================================ FILE: Pods/FirebaseCore/Frameworks/frameworks/FirebaseCore.framework/Headers/FIRApp.h ================================================ #import #import @class FIROptions; NS_ASSUME_NONNULL_BEGIN typedef void (^FIRAppVoidBoolCallback)(BOOL success); /** * The entry point of Firebase SDKs. * * Initialize and configure FIRApp using [FIRApp configure]; * Or other customized ways as shown below. * * The logging system has two modes: default mode and debug mode. In default mode, only logs with * log level Notice, Warning and Error will be sent to device. In debug mode, all logs will be sent * to device. The log levels that Firebase uses are consistent with the ASL log levels. * * Enable debug mode by passing the -FIRDebugEnabled argument to the application. You can add this * argument in the application's Xcode scheme. When debug mode is enabled via -FIRDebugEnabled, * further executions of the application will also be in debug mode. In order to return to default * mode, you must explicitly disable the debug mode with the application argument -FIRDebugDisabled. */ @interface FIRApp : NSObject /** * Configures a default Firebase app. Raises an exception if any configuration step fails. The * default app is named "__FIRAPP_DEFAULT". This method should be called after the app is launched * and before using Firebase services. This method is thread safe. */ + (void)configure; /** * Configures the default Firebase app with the provided options. The default app is named * "__FIRAPP_DEFAULT". Raises an exception if any configuration step fails. This method is thread * safe. * * @param options The Firebase application options used to configure the service. */ + (void)configureWithOptions:(FIROptions *)options; /** * Configures a Firebase app with the given name and options. Raises an exception if any * configuration step fails. This method is thread safe. * * @param name The application's name given by the developer. The name should should only contain Letters, Numbers and Underscore. * @param options The Firebase application options used to configure the services. */ + (void)configureWithName:(NSString *)name options:(FIROptions *)options; /** * Returns the default app, or nil if the default app does not exist. */ + (nullable FIRApp *)defaultApp NS_SWIFT_NAME(defaultApp()); /** * Returns a previously created FIRApp instance with the given name, or nil if no such app exists. * This method is thread safe. */ + (nullable FIRApp *)appNamed:(NSString *)name; /** * Returns the set of all extant FIRApp instances, or nil if there is no FIRApp instance. This * method is thread safe. */ + (nullable NSDictionary *)allApps; /** * Cleans up the current FIRApp, freeing associated data and returning its name to the pool for * future use. This method is thread safe in class level. */ - (void)deleteApp:(FIRAppVoidBoolCallback)completion; /** * FIRFirebaseApp instances should not be initialized directly. Call |FIRApp configure|, or * |FIRApp configureWithOptions:|, or |FIRApp configureWithNames:options| directly. */ - (nullable instancetype)init NS_UNAVAILABLE; /** * Gets the name of this app. */ @property(nonatomic, copy, readonly) NSString *name; /** * Gets the options for this app. */ @property(nonatomic, readonly) FIROptions *options; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseCore/Frameworks/frameworks/FirebaseCore.framework/Headers/FIRConfiguration.h ================================================ #import #import "FIRAnalyticsConfiguration.h" /** * The log levels used by FIRConfiguration. */ typedef NS_ENUM(NSInteger, FIRLogLevel) { kFIRLogLevelError __deprecated = 0, kFIRLogLevelWarning __deprecated, kFIRLogLevelInfo __deprecated, kFIRLogLevelDebug __deprecated, kFIRLogLevelAssert __deprecated, kFIRLogLevelMax __deprecated = kFIRLogLevelAssert } DEPRECATED_MSG_ATTRIBUTE( "Use -FIRDebugEnabled and -FIRDebugDisabled. See FIRApp.h for more details."); /** * This interface provides global level properties that the developer can tweak, and the singleton * of the Firebase Analytics configuration class. */ @interface FIRConfiguration : NSObject + (FIRConfiguration *)sharedInstance; // The configuration class for Firebase Analytics. @property(nonatomic, readwrite) FIRAnalyticsConfiguration *analyticsConfiguration; // Global log level. Defaults to kFIRLogLevelError. @property(nonatomic, readwrite, assign) FIRLogLevel logLevel DEPRECATED_MSG_ATTRIBUTE( "Use -FIRDebugEnabled and -FIRDebugDisabled. See FIRApp.h for more details."); @end ================================================ FILE: Pods/FirebaseCore/Frameworks/frameworks/FirebaseCore.framework/Headers/FIROptions.h ================================================ #import /** * This class provides constant fields of Google APIs. */ @interface FIROptions : NSObject /** * Returns the default options. */ + (FIROptions *)defaultOptions; /** * An iOS API key used for authenticating requests from your app, e.g. * @"AIzaSyDdVgKwhZl0sTTTLZ7iTmt1r3N2cJLnaDk", used to identify your app to Google servers. */ @property(nonatomic, readonly, copy) NSString *APIKey; /** * The OAuth2 client ID for iOS application used to authenticate Google users, for example * @"12345.apps.googleusercontent.com", used for signing in with Google. */ @property(nonatomic, readonly, copy) NSString *clientID; /** * The tracking ID for Google Analytics, e.g. @"UA-12345678-1", used to configure Google Analytics. */ @property(nonatomic, readonly, copy) NSString *trackingID; /** * The Project Number from the Google Developer's console, for example @"012345678901", used to * configure Google Cloud Messaging. */ @property(nonatomic, readonly, copy) NSString *GCMSenderID; /** * The Android client ID used in Google AppInvite when an iOS app has its Android version, for * example @"12345.apps.googleusercontent.com". */ @property(nonatomic, readonly, copy) NSString *androidClientID; /** * The Google App ID that is used to uniquely identify an instance of an app. */ @property(nonatomic, readonly, copy) NSString *googleAppID; /** * The database root URL, e.g. @"http://abc-xyz-123.firebaseio.com". */ @property(nonatomic, readonly, copy) NSString *databaseURL; /** * The URL scheme used to set up Durable Deep Link service. */ @property(nonatomic, readwrite, copy) NSString *deepLinkURLScheme; /** * The Google Cloud Storage bucket name, e.g. @"abc-xyz-123.storage.firebase.com". */ @property(nonatomic, readonly, copy) NSString *storageBucket; /** * Initializes a customized instance of FIROptions with keys. googleAppID, bundleID and GCMSenderID * are required. Other keys may required for configuring specific services. */ - (instancetype)initWithGoogleAppID:(NSString *)googleAppID bundleID:(NSString *)bundleID GCMSenderID:(NSString *)GCMSenderID APIKey:(NSString *)APIKey clientID:(NSString *)clientID trackingID:(NSString *)trackingID androidClientID:(NSString *)androidClientID databaseURL:(NSString *)databaseURL storageBucket:(NSString *)storageBucket deepLinkURLScheme:(NSString *)deepLinkURLScheme; /** * Initializes a customized instance of FIROptions from the file at the given plist file path. * For example, * NSString *filePath = * [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"]; * FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath]; * Returns nil if the plist file does not exist or is invalid. */ - (instancetype)initWithContentsOfFile:(NSString *)plistPath; @end ================================================ FILE: Pods/FirebaseCore/Frameworks/frameworks/FirebaseCore.framework/Headers/FirebaseCore.h ================================================ // Generated umbrella header for FirebaseCore. #import "FIRAnalyticsConfiguration.h" #import "FIRApp.h" #import "FIRConfiguration.h" #import "FIROptions.h" ================================================ FILE: Pods/FirebaseCore/Frameworks/frameworks/FirebaseCore.framework/Modules/module.modulemap ================================================ framework module FirebaseCore { export * umbrella header "FirebaseCore.h" header "FIRAnalyticsConfiguration.h" header "FIRApp.h" header "FIRConfiguration.h" header "FIROptions.h" link framework "SystemConfiguration" link "c++" } ================================================ FILE: Pods/FirebaseDatabase/Frameworks/FirebaseDatabase.framework/FirebaseDatabase ================================================ [File too large to display: 35.2 MB] ================================================ FILE: Pods/FirebaseDatabase/Frameworks/FirebaseDatabase.framework/Headers/FIRDataEventType.h ================================================ /* * Firebase iOS Client Library * * Copyright © 2013 Firebase - All Rights Reserved * https://www.firebase.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binaryform must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef Firebase_FIRDataEventType_h #define Firebase_FIRDataEventType_h /** * This enum is the set of events that you can observe at a Firebase Database location. */ typedef NS_ENUM(NSInteger, FIRDataEventType) { FIRDataEventTypeChildAdded, // 0, fired when a new child node is added to a location FIRDataEventTypeChildRemoved, // 1, fired when a child node is removed from a location FIRDataEventTypeChildChanged, // 2, fired when a child node at a location changes FIRDataEventTypeChildMoved, // 3, fired when a child node moves relative to the other child nodes at a location FIRDataEventTypeValue // 4, fired when any data changes at a location and, recursively, any children }; #endif ================================================ FILE: Pods/FirebaseDatabase/Frameworks/FirebaseDatabase.framework/Headers/FIRDataSnapshot.h ================================================ /* * Firebase iOS Client Library * * Copyright © 2013 Firebase - All Rights Reserved * https://www.firebase.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binaryform must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import NS_ASSUME_NONNULL_BEGIN @class FIRDatabaseReference; /** * A FIRDataSnapshot contains data from a Firebase Database location. Any time you read * Firebase data, you receive the data as a FIRDataSnapshot. * * FIRDataSnapshots are passed to the blocks you attach with observeEventType:withBlock: or observeSingleEvent:withBlock:. * They are efficiently-generated immutable copies of the data at a Firebase Database location. * They can't be modified and will never change. To modify data at a location, * use a FIRDatabaseReference (e.g. with setValue:). */ @interface FIRDataSnapshot : NSObject /** @name Navigating and inspecting a snapshot */ /** * Gets a FIRDataSnapshot for the location at the specified relative path. * The relative path can either be a simple child key (e.g. 'fred') * or a deeper slash-separated path (e.g. 'fred/name/first'). If the child * location has no data, an empty FIRDataSnapshot is returned. * * @param childPathString A relative path to the location of child data. * @return The FIRDataSnapshot for the child location. */ - (FIRDataSnapshot *)childSnapshotForPath:(NSString *)childPathString; /** * Return YES if the specified child exists. * * @param childPathString A relative path to the location of a potential child. * @return YES if data exists at the specified childPathString, else NO. */ - (BOOL) hasChild:(NSString *)childPathString; /** * Return YES if the DataSnapshot has any children. * * @return YES if this snapshot has any children, else NO. */ - (BOOL) hasChildren; /** * Return YES if the DataSnapshot contains a non-null value. * * @return YES if this snapshot contains a non-null value, else NO. */ - (BOOL) exists; /** @name Data export */ /** * Returns the raw value at this location, coupled with any metadata, such as priority. * * Priorities, where they exist, are accessible under the ".priority" key in instances of NSDictionary. * For leaf locations with priorities, the value will be under the ".value" key. */ - (id __nullable) valueInExportFormat; /** @name Properties */ /** * Returns the contents of this data snapshot as native types. * * Data types returned: * * NSDictionary * * NSArray * * NSNumber (also includes booleans) * * NSString * * @return The data as a native object. */ @property (strong, readonly, nonatomic, nullable) id value; /** * Gets the number of children for this DataSnapshot. * * @return An integer indicating the number of children. */ @property (readonly, nonatomic) NSUInteger childrenCount; /** * Gets a FIRDatabaseReference for the location that this data came from * * @return A FIRDatabaseReference instance for the location of this data */ @property (nonatomic, readonly, strong) FIRDatabaseReference * ref; /** * The key of the location that generated this FIRDataSnapshot. * * @return An NSString containing the key for the location of this FIRDataSnapshot. */ @property (strong, readonly, nonatomic) NSString* key; /** * An iterator for snapshots of the child nodes in this snapshot. * You can use the native for..in syntax: * * for (FIRDataSnapshot* child in snapshot.children) { * ... * } * * @return An NSEnumerator of the children */ @property (strong, readonly, nonatomic) NSEnumerator* children; /** * The priority of the data in this FIRDataSnapshot. * * @return The priority as a string, or nil if no priority was set. */ @property (strong, readonly, nonatomic, nullable) id priority; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseDatabase/Frameworks/FirebaseDatabase.framework/Headers/FIRDatabase.h ================================================ /* * Firebase iOS Client Library * * Copyright © 2013 Firebase - All Rights Reserved * https://www.firebase.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binaryform must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import #import "FIRDatabaseReference.h" @class FIRApp; NS_ASSUME_NONNULL_BEGIN /** * The entry point for accessing a Firebase Database. You can get an instance by calling * [FIRDatabase database]. To access a location in the database and read or write data, * use [FIRDatabase reference]. */ @interface FIRDatabase : NSObject /** * Gets the instance of FIRDatabase for the default FIRApp. * * @return A FIRDatabase instance. */ + (FIRDatabase *) database NS_SWIFT_NAME(database()); /** * Gets an instance of FIRDatabase for a specific FIRApp. * * @param app The FIRApp to get a FIRDatabase for. * @return A FIRDatabase instance. */ + (FIRDatabase *) databaseForApp:(FIRApp*)app NS_SWIFT_NAME(database(app:)); /** The FIRApp instance to which this FIRDatabase belongs. */ @property (weak, readonly, nonatomic) FIRApp *app; /** * Gets a FIRDatabaseReference for the root of your Firebase Database. */ - (FIRDatabaseReference *) reference; /** * Gets a FIRDatabaseReference for the provided path. * * @param path Path to a location in your Firebase Database. * @return A FIRDatabaseReference pointing to the specified path. */ - (FIRDatabaseReference *) referenceWithPath:(NSString *)path; /** * Gets a FIRDatabaseReference for the provided URL. The URL must be a URL to a path * within this Firebase Database. To create a FIRDatabaseReference to a different database, * create a FIRApp} with a FIROptions object configured with the appropriate database URL. * * @param url A URL to a path within your database. * @return A FIRDatabaseReference for the provided URL. */ - (FIRDatabaseReference *) referenceFromURL:(NSString *)databaseUrl; /** * The Firebase Database client automatically queues writes and sends them to the server at the earliest opportunity, * depending on network connectivity. In some cases (e.g. offline usage) there may be a large number of writes * waiting to be sent. Calling this method will purge all outstanding writes so they are abandoned. * * All writes will be purged, including transactions and onDisconnect writes. The writes will * be rolled back locally, perhaps triggering events for affected event listeners, and the client will not * (re-)send them to the Firebase Database backend. */ - (void)purgeOutstandingWrites; /** * Shuts down our connection to the Firebase Database backend until goOnline is called. */ - (void)goOffline; /** * Resumes our connection to the Firebase Database backend after a previous goOffline call. */ - (void)goOnline; /** * The Firebase Database client will cache synchronized data and keep track of all writes you've * initiated while your application is running. It seamlessly handles intermittent network * connections and re-sends write operations when the network connection is restored. * * However by default your write operations and cached data are only stored in-memory and will * be lost when your app restarts. By setting this value to `YES`, the data will be persisted * to on-device (disk) storage and will thus be available again when the app is restarted * (even when there is no network connectivity at that time). Note that this property must be * set before creating your first Database reference and only needs to be called once per * application. * */ @property (nonatomic) BOOL persistenceEnabled; /** * Sets the dispatch queue on which all events are raised. The default queue is the main queue. * * Note that this must be set before creating your first Database reference. */ @property (nonatomic, strong) dispatch_queue_t callbackQueue; /** * Enables verbose diagnostic logging. * @param enabled YES to enable logging, NO to disable. */ + (void) setLoggingEnabled:(BOOL)enabled; /** Retrieve the Firebase Database SDK version. */ + (NSString *) sdkVersion; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseDatabase/Frameworks/FirebaseDatabase.framework/Headers/FIRDatabaseQuery.h ================================================ /* * Firebase iOS Client Library * * Copyright © 2013 Firebase - All Rights Reserved * https://www.firebase.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binaryform must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import #import "FIRDataEventType.h" #import "FIRDataSnapshot.h" NS_ASSUME_NONNULL_BEGIN typedef NSUInteger FIRDatabaseHandle; /** * A FIRDatabaseQuery instance represents a query over the data at a particular location. * * You create one by calling one of the query methods (queryOrderedByChild:, queryStartingAtValue:, etc.) * on a FIRDatabaseReference. The query methods can be chained to further specify the data you are interested in * observing */ @interface FIRDatabaseQuery : NSObject /** @name Attach observers to read data */ /** * observeEventType:withBlock: is used to listen for data changes at a particular location. * This is the primary way to read data from the Firebase Database. Your block will be triggered * for the initial data and again whenever the data changes. * * Use removeObserverWithHandle: to stop receiving updates. * @param eventType The type of event to listen for. * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot. * @return A handle used to unregister this block later using removeObserverWithHandle: */ - (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block; /** * observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location. * This is the primary way to read data from the Firebase Database. Your block will be triggered * for the initial data and again whenever the data changes. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. * * Use removeObserverWithHandle: to stop receiving updates. * * @param eventType The type of event to listen for. * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot * and the previous child's key. * @return A handle used to unregister this block later using removeObserverWithHandle: */ - (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block; /** * observeEventType:withBlock: is used to listen for data changes at a particular location. * This is the primary way to read data from the Firebase Database. Your block will be triggered * for the initial data and again whenever the data changes. * * The cancelBlock will be called if you will no longer receive new events due to no longer having permission. * * Use removeObserverWithHandle: to stop receiving updates. * * @param eventType The type of event to listen for. * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot. * @param cancelBlock The block that should be called if this client no longer has permission to receive these events * @return A handle used to unregister this block later using removeObserverWithHandle: */ - (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; /** * observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location. * This is the primary way to read data from the Firebase Database. Your block will be triggered * for the initial data and again whenever the data changes. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. * * The cancelBlock will be called if you will no longer receive new events due to no longer having permission. * * Use removeObserverWithHandle: to stop receiving updates. * * @param eventType The type of event to listen for. * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot * and the previous child's key. * @param cancelBlock The block that should be called if this client no longer has permission to receive these events * @return A handle used to unregister this block later using removeObserverWithHandle: */ - (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; /** * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. * * @param eventType The type of event to listen for. * @param block The block that should be called. It is passed the data as a FIRDataSnapshot. */ - (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block; /** * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. * * @param eventType The type of event to listen for. * @param block The block that should be called. It is passed the data as a FIRDataSnapshot and the previous child's key. */ - (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block; /** * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. * * The cancelBlock will be called if you do not have permission to read data at this location. * * @param eventType The type of event to listen for. * @param block The block that should be called. It is passed the data as a FIRDataSnapshot. * @param cancelBlock The block that will be called if you don't have permission to access this data */ - (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; /** * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. * * The cancelBlock will be called if you do not have permission to read data at this location. * * @param eventType The type of event to listen for. * @param block The block that should be called. It is passed the data as a FIRDataSnapshot and the previous child's key. * @param cancelBlock The block that will be called if you don't have permission to access this data */ - (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; /** @name Detaching observers */ /** * Detach a block previously attached with observeEventType:withBlock:. * * @param handle The handle returned by the call to observeEventType:withBlock: which we are trying to remove. */ - (void) removeObserverWithHandle:(FIRDatabaseHandle)handle; /** * Detach all blocks previously attached to this Firebase Database location with observeEventType:withBlock: */ - (void) removeAllObservers; /** * By calling `keepSynced:YES` on a location, the data for that location will automatically be downloaded and * kept in sync, even when no listeners are attached for that location. Additionally, while a location is kept * synced, it will not be evicted from the persistent disk cache. * * @param keepSynced Pass YES to keep this location synchronized, pass NO to stop synchronization. */ - (void) keepSynced:(BOOL)keepSynced; /** @name Querying and limiting */ /** * queryLimitedToFirst: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryLimitedToFirst: will respond to at most the first limit child nodes. * * @param limit The upper bound, inclusive, for the number of child nodes to receive events for * @return A FIRDatabaseQuery instance, limited to at most limit child nodes. */ - (FIRDatabaseQuery *)queryLimitedToFirst:(NSUInteger)limit; /** * queryLimitedToLast: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryLimitedToLast: will respond to at most the last limit child nodes. * * @param limit The upper bound, inclusive, for the number of child nodes to receive events for * @return A FIRDatabaseQuery instance, limited to at most limit child nodes. */ - (FIRDatabaseQuery *)queryLimitedToLast:(NSUInteger)limit; /** * queryOrderBy: is used to generate a reference to a view of the data that's been sorted by the values of * a particular child key. This method is intended to be used in combination with queryStartingAtValue:, * queryEndingAtValue:, or queryEqualToValue:. * * @param key The child key to use in ordering data visible to the returned FIRDatabaseQuery * @return A FIRDatabaseQuery instance, ordered by the values of the specified child key. */ - (FIRDatabaseQuery *)queryOrderedByChild:(NSString *)key; /** * queryOrderedByKey: is used to generate a reference to a view of the data that's been sorted by child key. * This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:, * or queryEqualToValue:. * * @return A FIRDatabaseQuery instance, ordered by child keys. */ - (FIRDatabaseQuery *) queryOrderedByKey; /** * queryOrderedByValue: is used to generate a reference to a view of the data that's been sorted by child value. * This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:, * or queryEqualToValue:. * * @return A FIRDatabaseQuery instance, ordered by child value. */ - (FIRDatabaseQuery *) queryOrderedByValue; /** * queryOrderedByPriority: is used to generate a reference to a view of the data that's been sorted by child * priority. This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:, * or queryEqualToValue:. * * @return A FIRDatabaseQuery instance, ordered by child priorities. */ - (FIRDatabaseQuery *) queryOrderedByPriority; /** * queryStartingAtValue: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryStartingAtValue: will respond to events at nodes with a value * greater than or equal to startValue. * * @param startValue The lower bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery * @return A FIRDatabaseQuery instance, limited to data with value greater than or equal to startValue */ - (FIRDatabaseQuery *)queryStartingAtValue:(nullable id)startValue; /** * queryStartingAtValue:childKey: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryStartingAtValue:childKey will respond to events at nodes with a value * greater than startValue, or equal to startValue and with a key greater than or equal to childKey. * * @param startValue The lower bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery * @param childKey The lower bound, inclusive, for the key of nodes with value equal to startValue * @return A FIRDatabaseQuery instance, limited to data with value greater than or equal to startValue */ - (FIRDatabaseQuery *)queryStartingAtValue:(nullable id)startValue childKey:(nullable NSString *)childKey; /** * queryEndingAtValue: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryEndingAtValue: will respond to events at nodes with a value * less than or equal to endValue. * * @param endValue The upper bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery * @return A FIRDatabaseQuery instance, limited to data with value less than or equal to endValue */ - (FIRDatabaseQuery *)queryEndingAtValue:(nullable id)endValue; /** * queryEndingAtValue:childKey: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryEndingAtValue:childKey will respond to events at nodes with a value * less than endValue, or equal to endValue and with a key less than or equal to childKey. * * @param endValue The upper bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery * @param childKey The upper bound, inclusive, for the key of nodes with value equal to endValue * @return A FIRDatabaseQuery instance, limited to data with value less than or equal to endValue */ - (FIRDatabaseQuery *)queryEndingAtValue:(nullable id)endValue childKey:(nullable NSString *)childKey; /** * queryEqualToValue: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryEqualToValue: will respond to events at nodes with a value equal * to the supplied argument. * * @param value The value that the data returned by this FIRDatabaseQuery will have * @return A FIRDatabaseQuery instance, limited to data with the supplied value. */ - (FIRDatabaseQuery *)queryEqualToValue:(nullable id)value; /** * queryEqualToValue:childKey: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryEqualToValue:childKey will respond to events at nodes with a value * equal to the supplied argument with a name equal to childKey. There will be at most one node that matches because * child keys are unique. * * @param value The value that the data returned by this FIRDatabaseQuery will have * @param childKey The name of nodes with the right value * @return A FIRDatabaseQuery instance, limited to data with the supplied value and the key. */ - (FIRDatabaseQuery *)queryEqualToValue:(nullable id)value childKey:(nullable NSString *)childKey; /** @name Properties */ /** * Gets a FIRDatabaseReference for the location of this query. * * @return A FIRDatabaseReference for the location of this query. */ @property (nonatomic, readonly, strong) FIRDatabaseReference * ref; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseDatabase/Frameworks/FirebaseDatabase.framework/Headers/FIRDatabaseReference.h ================================================ /* * Firebase iOS Client Library * * Copyright © 2013 Firebase - All Rights Reserved * https://www.firebase.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binaryform must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import #import "FIRDatabaseQuery.h" #import "FIRDatabase.h" #import "FIRDataSnapshot.h" #import "FIRMutableData.h" #import "FIRTransactionResult.h" #import "FIRServerValue.h" NS_ASSUME_NONNULL_BEGIN @class FIRDatabase; /** * A FIRDatabaseReference represents a particular location in your Firebase Database * and can be used for reading or writing data to that Firebase Database location. * * This class is the starting point for all Firebase Database operations. After you've * initialized it with initWithUrl: you can use it * to read data (ie. observeEventType:withBlock:), write data (ie. setValue:), and to create new * FIRDatabaseReferences (ie. child:). */ @interface FIRDatabaseReference : FIRDatabaseQuery /** @name Getting references to children locations */ /** * Gets a FIRDatabaseReference for the location at the specified relative path. * The relative path can either be a simple child key (e.g. 'fred') or a * deeper slash-separated path (e.g. 'fred/name/first'). * * @param pathString A relative path from this location to the desired child location. * @return A FIRDatabaseReference for the specified relative path. */ - (FIRDatabaseReference *)child:(NSString *)pathString; /** * childByAppendingPath: is deprecated, use child: instead. */ - (FIRDatabaseReference *)childByAppendingPath:(NSString *)pathString __deprecated_msg("use child: instead"); /** * childByAutoId generates a new child location using a unique key and returns a * FIRDatabaseReference to it. This is useful when the children of a Firebase Database * location represent a list of items. * * The unique key generated by childByAutoId: is prefixed with a client-generated * timestamp so that the resulting list will be chronologically-sorted. * * @return A FIRDatabaseReference for the generated location. */ - (FIRDatabaseReference *) childByAutoId; /** @name Writing data */ /** Write data to this Firebase Database location. This will overwrite any data at this location and all child locations. Data types that can be set are: - NSString -- @"Hello World" - NSNumber (also includes boolean) -- @YES, @43, @4.333 - NSDictionary -- @{@"key": @"value", @"nested": @{@"another": @"value"} } - NSArray The effect of the write will be visible immediately and the corresponding events will be triggered. Synchronization of the data to the Firebase Database servers will also be started. Passing null for the new value is equivalent to calling remove:; all data at this location or any child location will be deleted. Note that setValue: will remove any priority stored at this location, so if priority is meant to be preserved, you should use setValue:andPriority: instead. @param value The value to be written. */ - (void) setValue:(nullable id)value; /** * The same as setValue: with a block that gets triggered after the write operation has * been committed to the Firebase Database servers. * * @param value The value to be written. * @param block The block to be called after the write has been committed to the Firebase Database servers. */ - (void) setValue:(nullable id)value withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; /** * The same as setValue: with an additional priority to be attached to the data being written. * Priorities are used to order items. * * @param value The value to be written. * @param priority The priority to be attached to that data. */ - (void) setValue:(nullable id)value andPriority:(nullable id)priority; /** * The same as setValue:andPriority: with a block that gets triggered after the write operation has * been committed to the Firebase Database servers. * * @param value The value to be written. * @param priority The priority to be attached to that data. * @param block The block to be called after the write has been committed to the Firebase Database servers. */ - (void) setValue:(nullable id)value andPriority:(nullable id)priority withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; /** * Remove the data at this Firebase Database location. Any data at child locations will also be deleted. * * The effect of the delete will be visible immediately and the corresponding events * will be triggered. Synchronization of the delete to the Firebase Database servers will * also be started. * * remove: is equivalent to calling setValue:nil */ - (void) removeValue; /** * The same as remove: with a block that gets triggered after the remove operation has * been committed to the Firebase Database servers. * * @param block The block to be called after the remove has been committed to the Firebase Database servers. */ - (void) removeValueWithCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; /** * Sets a priority for the data at this Firebase Database location. * Priorities can be used to provide a custom ordering for the children at a location * (if no priorities are specified, the children are ordered by key). * * You cannot set a priority on an empty location. For this reason * setValue:andPriority: should be used when setting initial data with a specific priority * and setPriority: should be used when updating the priority of existing data. * * Children are sorted based on this priority using the following rules: * * Children with no priority come first. * Children with a number as their priority come next. They are sorted numerically by priority (small to large). * Children with a string as their priority come last. They are sorted lexicographically by priority. * Whenever two children have the same priority (including no priority), they are sorted by key. Numeric * keys come first (sorted numerically), followed by the remaining keys (sorted lexicographically). * * Note that priorities are parsed and ordered as IEEE 754 double-precision floating-point numbers. * Keys are always stored as strings and are treated as numbers only when they can be parsed as a * 32-bit integer * * @param priority The priority to set at the specified location. */ - (void) setPriority:(nullable id)priority; /** * The same as setPriority: with a block that is called once the priority has * been committed to the Firebase Database servers. * * @param priority The priority to set at the specified location. * @param block The block that is triggered after the priority has been written on the servers. */ - (void) setPriority:(nullable id)priority withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; /** * Updates the values at the specified paths in the dictionary without overwriting other * keys at this location. * * @param values A dictionary of the keys to change and their new values */ - (void) updateChildValues:(NSDictionary *)values; /** * The same as update: with a block that is called once the update has been committed to the * Firebase Database servers * * @param values A dictionary of the keys to change and their new values * @param block The block that is triggered after the update has been written on the Firebase Database servers */ - (void) updateChildValues:(NSDictionary *)values withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; /** @name Attaching observers to read data */ /** * observeEventType:withBlock: is used to listen for data changes at a particular location. * This is the primary way to read data from the Firebase Database. Your block will be triggered * for the initial data and again whenever the data changes. * * Use removeObserverWithHandle: to stop receiving updates. * @param eventType The type of event to listen for. * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot. * @return A handle used to unregister this block later using removeObserverWithHandle: */ - (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block; /** * observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location. * This is the primary way to read data from the Firebase Database. Your block will be triggered * for the initial data and again whenever the data changes. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. * * Use removeObserverWithHandle: to stop receiving updates. * * @param eventType The type of event to listen for. * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot * and the previous child's key. * @return A handle used to unregister this block later using removeObserverWithHandle: */ - (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block; /** * observeEventType:withBlock: is used to listen for data changes at a particular location. * This is the primary way to read data from the Firebase Database. Your block will be triggered * for the initial data and again whenever the data changes. * * The cancelBlock will be called if you will no longer receive new events due to no longer having permission. * * Use removeObserverWithHandle: to stop receiving updates. * * @param eventType The type of event to listen for. * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot. * @param cancelBlock The block that should be called if this client no longer has permission to receive these events * @return A handle used to unregister this block later using removeObserverWithHandle: */ - (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; /** * observeEventType:andPreviousSiblingKeyWithBlock: is used to listen for data changes at a particular location. * This is the primary way to read data from the Firebase Database. Your block will be triggered * for the initial data and again whenever the data changes. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. * * The cancelBlock will be called if you will no longer receive new events due to no longer having permission. * * Use removeObserverWithHandle: to stop receiving updates. * * @param eventType The type of event to listen for. * @param block The block that should be called with initial data and updates. It is passed the data as a FIRDataSnapshot * and the previous child's key. * @param cancelBlock The block that should be called if this client no longer has permission to receive these events * @return A handle used to unregister this block later using removeObserverWithHandle: */ - (FIRDatabaseHandle)observeEventType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; /** * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. * * @param eventType The type of event to listen for. * @param block The block that should be called. It is passed the data as a FIRDataSnapshot. */ - (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block; /** * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. * * @param eventType The type of event to listen for. * @param block The block that should be called. It is passed the data as a FIRDataSnapshot and the previous child's key. */ - (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block; /** * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. * * The cancelBlock will be called if you do not have permission to read data at this location. * * @param eventType The type of event to listen for. * @param block The block that should be called. It is passed the data as a FIRDataSnapshot. * @param cancelBlock The block that will be called if you don't have permission to access this data */ - (void)observeSingleEventOfType:(FIRDataEventType)eventType withBlock:(void (^)(FIRDataSnapshot *snapshot))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; /** * This is equivalent to observeEventType:withBlock:, except the block is immediately canceled after the initial data is returned. In addition, for FIRDataEventTypeChildAdded, FIRDataEventTypeChildMoved, and * FIRDataEventTypeChildChanged events, your block will be passed the key of the previous node by priority order. * * The cancelBlock will be called if you do not have permission to read data at this location. * * @param eventType The type of event to listen for. * @param block The block that should be called. It is passed the data as a FIRDataSnapshot and the previous child's key. * @param cancelBlock The block that will be called if you don't have permission to access this data */ - (void)observeSingleEventOfType:(FIRDataEventType)eventType andPreviousSiblingKeyWithBlock:(void (^)(FIRDataSnapshot *snapshot, NSString *__nullable prevKey))block withCancelBlock:(nullable void (^)(NSError* error))cancelBlock; /** @name Detaching observers */ /** * Detach a block previously attached with observeEventType:withBlock:. * * @param handle The handle returned by the call to observeEventType:withBlock: which we are trying to remove. */ - (void) removeObserverWithHandle:(FIRDatabaseHandle)handle; /** * By calling `keepSynced:YES` on a location, the data for that location will automatically be downloaded and * kept in sync, even when no listeners are attached for that location. Additionally, while a location is kept * synced, it will not be evicted from the persistent disk cache. * * @param keepSynced Pass YES to keep this location synchronized, pass NO to stop synchronization. */ - (void) keepSynced:(BOOL)keepSynced; /** * Removes all observers at the current reference, but does not remove any observers at child references. * removeAllObservers must be called again for each child reference where a listener was established to remove the observers. */ - (void) removeAllObservers; /** @name Querying and limiting */ /** * queryLimitedToFirst: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryLimitedToFirst: will respond to at most the first limit child nodes. * * @param limit The upper bound, inclusive, for the number of child nodes to receive events for * @return A FIRDatabaseQuery instance, limited to at most limit child nodes. */ - (FIRDatabaseQuery *)queryLimitedToFirst:(NSUInteger)limit; /** * queryLimitedToLast: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryLimitedToLast: will respond to at most the last limit child nodes. * * @param limit The upper bound, inclusive, for the number of child nodes to receive events for * @return A FIRDatabaseQuery instance, limited to at most limit child nodes. */ - (FIRDatabaseQuery *)queryLimitedToLast:(NSUInteger)limit; /** * queryOrderBy: is used to generate a reference to a view of the data that's been sorted by the values of * a particular child key. This method is intended to be used in combination with queryStartingAtValue:, * queryEndingAtValue:, or queryEqualToValue:. * * @param key The child key to use in ordering data visible to the returned FIRDatabaseQuery * @return A FIRDatabaseQuery instance, ordered by the values of the specified child key. */ - (FIRDatabaseQuery *)queryOrderedByChild:(NSString *)key; /** * queryOrderedByKey: is used to generate a reference to a view of the data that's been sorted by child key. * This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:, * or queryEqualToValue:. * * @return A FIRDatabaseQuery instance, ordered by child keys. */ - (FIRDatabaseQuery *) queryOrderedByKey; /** * queryOrderedByPriority: is used to generate a reference to a view of the data that's been sorted by child * priority. This method is intended to be used in combination with queryStartingAtValue:, queryEndingAtValue:, * or queryEqualToValue:. * * @return A FIRDatabaseQuery instance, ordered by child priorities. */ - (FIRDatabaseQuery *) queryOrderedByPriority; /** * queryStartingAtValue: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryStartingAtValue: will respond to events at nodes with a value * greater than or equal to startValue. * * @param startValue The lower bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery * @return A FIRDatabaseQuery instance, limited to data with value greater than or equal to startValue */ - (FIRDatabaseQuery *)queryStartingAtValue:(nullable id)startValue; /** * queryStartingAtValue:childKey: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryStartingAtValue:childKey will respond to events at nodes with a value * greater than startValue, or equal to startValue and with a key greater than or equal to childKey. * * @param startValue The lower bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery * @param childKey The lower bound, inclusive, for the key of nodes with value equal to startValue * @return A FIRDatabaseQuery instance, limited to data with value greater than or equal to startValue */ - (FIRDatabaseQuery *)queryStartingAtValue:(nullable id)startValue childKey:(nullable NSString *)childKey; /** * queryEndingAtValue: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryEndingAtValue: will respond to events at nodes with a value * less than or equal to endValue. * * @param endValue The upper bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery * @return A FIRDatabaseQuery instance, limited to data with value less than or equal to endValue */ - (FIRDatabaseQuery *)queryEndingAtValue:(nullable id)endValue; /** * queryEndingAtValue:childKey: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryEndingAtValue:childKey will respond to events at nodes with a value * less than endValue, or equal to endValue and with a key less than or equal to childKey. * * @param endValue The upper bound, inclusive, for the value of data visible to the returned FIRDatabaseQuery * @param childKey The upper bound, inclusive, for the key of nodes with value equal to endValue * @return A FIRDatabaseQuery instance, limited to data with value less than or equal to endValue */ - (FIRDatabaseQuery *)queryEndingAtValue:(nullable id)endValue childKey:(nullable NSString *)childKey; /** * queryEqualToValue: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryEqualToValue: will respond to events at nodes with a value equal * to the supplied argument. * * @param value The value that the data returned by this FIRDatabaseQuery will have * @return A FIRDatabaseQuery instance, limited to data with the supplied value. */ - (FIRDatabaseQuery *)queryEqualToValue:(nullable id)value; /** * queryEqualToValue:childKey: is used to generate a reference to a limited view of the data at this location. * The FIRDatabaseQuery instance returned by queryEqualToValue:childKey will respond to events at nodes with a value * equal to the supplied argument with a key equal to childKey. There will be at most one node that matches because * child keys are unique. * * @param value The value that the data returned by this FIRDatabaseQuery will have * @param childKey The key of nodes with the right value * @return A FIRDatabaseQuery instance, limited to data with the supplied value and the key. */ - (FIRDatabaseQuery *)queryEqualToValue:(nullable id)value childKey:(nullable NSString *)childKey; /** @name Managing presence */ /** * Ensure the data at this location is set to the specified value when * the client is disconnected (due to closing the browser, navigating * to a new page, or network issues). * * onDisconnectSetValue: is especially useful for implementing "presence" systems, * where a value should be changed or cleared when a user disconnects * so that he appears "offline" to other users. * * @param value The value to be set after the connection is lost. */ - (void) onDisconnectSetValue:(nullable id)value; /** * Ensure the data at this location is set to the specified value when * the client is disconnected (due to closing the browser, navigating * to a new page, or network issues). * * The completion block will be triggered when the operation has been successfully queued up on the Firebase Database servers * * @param value The value to be set after the connection is lost. * @param block Block to be triggered when the operation has been queued up on the Firebase Database servers */ - (void) onDisconnectSetValue:(nullable id)value withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; /** * Ensure the data at this location is set to the specified value and priority when * the client is disconnected (due to closing the browser, navigating * to a new page, or network issues). * * @param value The value to be set after the connection is lost. * @param priority The priority to be set after the connection is lost. */ - (void) onDisconnectSetValue:(nullable id)value andPriority:(id)priority; /** * Ensure the data at this location is set to the specified value and priority when * the client is disconnected (due to closing the browser, navigating * to a new page, or network issues). * * The completion block will be triggered when the operation has been successfully queued up on the Firebase Database servers * * @param value The value to be set after the connection is lost. * @param priority The priority to be set after the connection is lost. * @param block Block to be triggered when the operation has been queued up on the Firebase Database servers */ - (void) onDisconnectSetValue:(nullable id)value andPriority:(nullable id)priority withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; /** * Ensure the data at this location is removed when * the client is disconnected (due to closing the app, navigating * to a new page, or network issues). * * onDisconnectRemoveValue is especially useful for implementing "presence" systems. */ - (void) onDisconnectRemoveValue; /** * Ensure the data at this location is removed when * the client is disconnected (due to closing the app, navigating * to a new page, or network issues). * * onDisconnectRemoveValueWithCompletionBlock: is especially useful for implementing "presence" systems. * * @param block Block to be triggered when the operation has been queued up on the Firebase Database servers */ - (void) onDisconnectRemoveValueWithCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; /** * Ensure the data has the specified child values updated when * the client is disconnected (due to closing the browser, navigating * to a new page, or network issues). * * * @param values A dictionary of child node keys and the values to set them to after the connection is lost. */ - (void) onDisconnectUpdateChildValues:(NSDictionary *)values; /** * Ensure the data has the specified child values updated when * the client is disconnected (due to closing the browser, navigating * to a new page, or network issues). * * * @param values A dictionary of child node keys and the values to set them to after the connection is lost. * @param block A block that will be called once the operation has been queued up on the Firebase Database servers */ - (void) onDisconnectUpdateChildValues:(NSDictionary *)values withCompletionBlock:(void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; /** * Cancel any operations that are set to run on disconnect. If you previously called onDisconnectSetValue:, * onDisconnectRemoveValue:, or onDisconnectUpdateChildValues:, and no longer want the values updated when the * connection is lost, call cancelDisconnectOperations: */ - (void) cancelDisconnectOperations; /** * Cancel any operations that are set to run on disconnect. If you previously called onDisconnectSetValue:, * onDisconnectRemoveValue:, or onDisconnectUpdateChildValues:, and no longer want the values updated when the * connection is lost, call cancelDisconnectOperations: * * @param block A block that will be triggered once the Firebase Database servers have acknowledged the cancel request. */ - (void) cancelDisconnectOperationsWithCompletionBlock:(nullable void (^)(NSError *__nullable error, FIRDatabaseReference * ref))block; /** @name Manual Connection Management */ /** * Manually disconnect the Firebase Database client from the server and disable automatic reconnection. * * The Firebase Database client automatically maintains a persistent connection to the Firebase Database server, * which will remain active indefinitely and reconnect when disconnected. However, the goOffline( ) * and goOnline( ) methods may be used to manually control the client connection in cases where * a persistent connection is undesirable. * * While offline, the Firebase Database client will no longer receive data updates from the server. However, * all database operations performed locally will continue to immediately fire events, allowing * your application to continue behaving normally. Additionally, each operation performed locally * will automatically be queued and retried upon reconnection to the Firebase Database server. * * To reconnect to the Firebase Database server and begin receiving remote events, see goOnline( ). * Once the connection is reestablished, the Firebase Database client will transmit the appropriate data * and fire the appropriate events so that your client "catches up" automatically. * * Note: Invoking this method will impact all Firebase Database connections. */ + (void) goOffline; /** * Manually reestablish a connection to the Firebase Database server and enable automatic reconnection. * * The Firebase Database client automatically maintains a persistent connection to the Firebase Database server, * which will remain active indefinitely and reconnect when disconnected. However, the goOffline( ) * and goOnline( ) methods may be used to manually control the client connection in cases where * a persistent connection is undesirable. * * This method should be used after invoking goOffline( ) to disable the active connection. * Once reconnected, the Firebase Database client will automatically transmit the proper data and fire * the appropriate events so that your client "catches up" automatically. * * To disconnect from the Firebase Database server, see goOffline( ). * * Note: Invoking this method will impact all Firebase Database connections. */ + (void) goOnline; /** @name Transactions */ /** * Performs an optimistic-concurrency transactional update to the data at this location. Your block will be called with a FIRMutableData * instance that contains the current data at this location. Your block should update this data to the value you * wish to write to this location, and then return an instance of FIRTransactionResult with the new data. * * If, when the operation reaches the server, it turns out that this client had stale data, your block will be run * again with the latest data from the server. * * When your block is run, you may decide to abort the transaction by returning [FIRTransactionResult abort]. * * @param block This block receives the current data at this location and must return an instance of FIRTransactionResult */ - (void) runTransactionBlock:(FIRTransactionResult * (^) (FIRMutableData* currentData))block; /** * Performs an optimistic-concurrency transactional update to the data at this location. Your block will be called with a FIRMutableData * instance that contains the current data at this location. Your block should update this data to the value you * wish to write to this location, and then return an instance of FIRTransactionResult with the new data. * * If, when the operation reaches the server, it turns out that this client had stale data, your block will be run * again with the latest data from the server. * * When your block is run, you may decide to abort the transaction by returning [FIRTransactionResult abort]. * * @param block This block receives the current data at this location and must return an instance of FIRTransactionResult * @param completionBlock This block will be triggered once the transaction is complete, whether it was successful or not. It will indicate if there was an error, whether or not the data was committed, and what the current value of the data at this location is. */ - (void)runTransactionBlock:(FIRTransactionResult * (^) (FIRMutableData* currentData))block andCompletionBlock:(void (^) (NSError *__nullable error, BOOL committed, FIRDataSnapshot *__nullable snapshot))completionBlock; /** * Performs an optimistic-concurrency transactional update to the data at this location. Your block will be called with a FIRMutableData * instance that contains the current data at this location. Your block should update this data to the value you * wish to write to this location, and then return an instance of FIRTransactionResult with the new data. * * If, when the operation reaches the server, it turns out that this client had stale data, your block will be run * again with the latest data from the server. * * When your block is run, you may decide to abort the transaction by return [FIRTransactionResult abort]. * * Since your block may be run multiple times, this client could see several immediate states that don't exist on the server. You can suppress those immediate states until the server confirms the final state of the transaction. * * @param block This block receives the current data at this location and must return an instance of FIRTransactionResult * @param completionBlock This block will be triggered once the transaction is complete, whether it was successful or not. It will indicate if there was an error, whether or not the data was committed, and what the current value of the data at this location is. * @param localEvents Set this to NO to suppress events raised for intermediate states, and only get events based on the final state of the transaction. */ - (void)runTransactionBlock:(FIRTransactionResult * (^) (FIRMutableData* currentData))block andCompletionBlock:(nullable void (^) (NSError *__nullable error, BOOL committed, FIRDataSnapshot *__nullable snapshot))completionBlock withLocalEvents:(BOOL)localEvents; /** @name Retrieving String Representation */ /** * Gets the absolute URL of this Firebase Database location. * * @return The absolute URL of the referenced Firebase Database location. */ - (NSString *) description; /** @name Properties */ /** * Gets a FIRDatabaseReference for the parent location. * If this instance refers to the root of your Firebase Database, it has no parent, * and therefore parent( ) will return null. * * @return A FIRDatabaseReference for the parent location. */ @property (strong, readonly, nonatomic, nullable) FIRDatabaseReference * parent; /** * Gets a FIRDatabaseReference for the root location * * @return A new FIRDatabaseReference to root location. */ @property (strong, readonly, nonatomic) FIRDatabaseReference * root; /** * Gets the last token in a Firebase Database location (e.g. 'fred' in https://SampleChat.firebaseIO-demo.com/users/fred) * * @return The key of the location this reference points to. */ @property (strong, readonly, nonatomic) NSString* key; /** * Gets the URL for the Firebase Database location referenced by this FIRDatabaseReference. * * @return The url of the location this reference points to. */ @property (strong, readonly, nonatomic) NSString* URL; /** * Gets the FIRDatabase instance associated with this reference. * * @return The FIRDatabase object for this reference. */ @property (strong, readonly, nonatomic) FIRDatabase *database; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseDatabase/Frameworks/FirebaseDatabase.framework/Headers/FIRMutableData.h ================================================ /* * Firebase iOS Client Library * * Copyright © 2013 Firebase - All Rights Reserved * https://www.firebase.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binaryform must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import NS_ASSUME_NONNULL_BEGIN /** * A FIRMutableData instance is populated with data from a Firebase Database location. * When you are using runTransactionBlock:, you will be given an instance containing the current * data at that location. Your block will be responsible for updating that instance to the data * you wish to save at that location, and then returning using [FIRTransactionResult successWithValue:]. * * To modify the data, set its value property to any of the native types support by Firebase Database: * * NSNumber (includes BOOL) * * NSDictionary * * NSArray * * NSString * * nil / NSNull to remove the data * * Note that changes made to a child FIRMutableData instance will be visible to the parent. */ @interface FIRMutableData : NSObject /** @name Inspecting and navigating the data */ /** * Returns boolean indicating whether this mutable data has children. * * @return YES if this data contains child nodes. */ - (BOOL) hasChildren; /** * Indicates whether this mutable data has a child at the given path. * * @param path A path string, consisting either of a single segment, like 'child', or multiple segments, 'a/deeper/child' * @return YES if this data contains a child at the specified relative path */ - (BOOL) hasChildAtPath:(NSString *)path; /** * Used to obtain a FIRMutableData instance that encapsulates the data at the given relative path. * Note that changes made to the child will be visible to the parent. * * @param path A path string, consisting either of a single segment, like 'child', or multiple segments, 'a/deeper/child' * @return A FIRMutableData instance containing the data at the given path */ - (FIRMutableData *)childDataByAppendingPath:(NSString *)path; /** @name Properties */ /** * To modify the data contained by this instance of FIRMutableData, set this to any of the native types supported by Firebase Database: * * * NSNumber (includes BOOL) * * NSDictionary * * NSArray * * NSString * * nil / NSNull to remove the data * * Note that setting this value will override the priority at this location. * * @return The current data at this location as a native object */ @property (strong, nonatomic, nullable) id value; /** * Set this property to update the priority of the data at this location. Can be set to the following types: * * * NSNumber * * NSString * * nil / NSNull to remove the priority * * @return The priority of the data at this location */ @property (strong, nonatomic, nullable) id priority; /** * @return The number of child nodes at this location */ @property (readonly, nonatomic) NSUInteger childrenCount; /** * Used to iterate over the children at this location. You can use the native for .. in syntax: * * for (FIRMutableData* child in data.children) { * ... * } * * Note that this enumerator operates on an immutable copy of the child list. So, you can modify the instance * during iteration, but the new additions will not be visible until you get a new enumerator. */ @property (readonly, nonatomic, strong) NSEnumerator* children; /** * @return The key name of this node, or nil if it is the top-most location */ @property (readonly, nonatomic, strong, nullable) NSString* key; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseDatabase/Frameworks/FirebaseDatabase.framework/Headers/FIRServerValue.h ================================================ /* * Firebase iOS Client Library * * Copyright © 2013 Firebase - All Rights Reserved * https://www.firebase.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binaryform must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ NS_ASSUME_NONNULL_BEGIN /** * Placeholder values you may write into Firebase Database as a value or priority * that will automatically be populated by the Firebase Database server. */ @interface FIRServerValue : NSObject /** * Placeholder value for the number of milliseconds since the Unix epoch */ + (NSDictionary *) timestamp; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseDatabase/Frameworks/FirebaseDatabase.framework/Headers/FIRTransactionResult.h ================================================ /* * Firebase iOS Client Library * * Copyright © 2013 Firebase - All Rights Reserved * https://www.firebase.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binaryform must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import #import "FIRMutableData.h" NS_ASSUME_NONNULL_BEGIN /** * Used for runTransactionBlock:. An FIRTransactionResult instance is a container for the results of the transaction. */ @interface FIRTransactionResult : NSObject /** * Used for runTransactionBlock:. Indicates that the new value should be saved at this location * * @param value A FIRMutableData instance containing the new value to be set * @return An FIRTransactionResult instance that can be used as a return value from the block given to runTransactionBlock: */ + (FIRTransactionResult *)successWithValue:(FIRMutableData *)value; /** * Used for runTransactionBlock:. Indicates that the current transaction should no longer proceed. * * @return An FIRTransactionResult instance that can be used as a return value from the block given to runTransactionBlock: */ + (FIRTransactionResult *) abort; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseDatabase/Frameworks/FirebaseDatabase.framework/Headers/FirebaseDatabase.h ================================================ /* * Firebase iOS Client Library * * Copyright © 2016 Firebase - All Rights Reserved * https://www.firebase.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binaryform must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY FIREBASE AS IS AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL FIREBASE BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef FirebaseDatabase_h #define FirebaseDatabase_h #import "FIRDatabase.h" #import "FIRDatabaseQuery.h" #import "FIRDatabaseReference.h" #import "FIRDataEventType.h" #import "FIRDataSnapshot.h" #import "FIRMutableData.h" #import "FIRServerValue.h" #import "FIRTransactionResult.h" #endif /* FirebaseDatabase_h */ ================================================ FILE: Pods/FirebaseDatabase/Frameworks/FirebaseDatabase.framework/Modules/module.modulemap ================================================ framework module FirebaseDatabase { umbrella header "FirebaseDatabase.h" export * module * { export * } link framework "CFNetwork" link framework "Security" link framework "SystemConfiguration" link "c++" link "icucore" } ================================================ FILE: Pods/FirebaseDatabase/Frameworks/FirebaseDatabase.framework/NOTICE ================================================ Google LevelDB Copyright (c) 2011 The LevelDB Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- Square Socket Rocket 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. -- APLevelDB Created by Adam Preble on 1/23/12. Copyright (c) 2012 Adam Preble. All rights reserved. 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. ================================================ FILE: Pods/FirebaseInstanceID/Frameworks/frameworks/FirebaseInstanceID.framework/Headers/FIRInstanceID.h ================================================ #import /** * @memberof FIRInstanceID * * The scope to be used when fetching/deleting a token for Firebase Messaging. */ FOUNDATION_EXPORT NSString * __nonnull const kFIRInstanceIDScopeFirebaseMessaging; /** * Called when the system determines that tokens need to be refreshed. * This method is also called if Instance ID has been reset in which * case, tokens and FCM topic subscriptions also need to be refreshed. * * Instance ID service will throttle the refresh event across all devices * to control the rate of token updates on application servers. */ FOUNDATION_EXPORT NSString * __nonnull const kFIRInstanceIDTokenRefreshNotification; /** * @related FIRInstanceID * * The completion handler invoked when the InstanceID token returns. If * the call fails we return the appropriate `error code` as described below. * * @param token The valid token as returned by InstanceID backend. * * @param error The error describing why generating a new token * failed. See the error codes below for a more detailed * description. */ typedef void(^FIRInstanceIDTokenHandler)( NSString * __nullable token, NSError * __nullable error); /** * @related FIRInstanceID * * The completion handler invoked when the InstanceID `deleteToken` returns. If * the call fails we return the appropriate `error code` as described below * * @param error The error describing why deleting the token failed. * See the error codes below for a more detailed description. */ typedef void(^FIRInstanceIDDeleteTokenHandler)(NSError * __nullable error); /** * @related FIRInstanceID * * The completion handler invoked when the app identity is created. If the * identity wasn't created for some reason we return the appropriate error code. * * @param identity A valid identity for the app instance, nil if there was an error * while creating an identity. * @param error The error if fetching the identity fails else nil. */ typedef void(^FIRInstanceIDHandler)(NSString * __nullable identity, NSError * __nullable error); /** * @related FIRInstanceID * * The completion handler invoked when the app identity and all the tokens associated * with it are deleted. Returns a valid error object in case of failure else nil. * * @param error The error if deleting the identity and all the tokens associated with * it fails else nil. */ typedef void(^FIRInstanceIDDeleteHandler)(NSError * __nullable error); /** * @enum FIRInstanceIDError */ typedef NS_ENUM(NSUInteger, FIRInstanceIDError) { // Http related errors. /// Unknown error. FIRInstanceIDErrorUnknown = 0, /// Auth Error -- GCM couldn't validate request from this client. FIRInstanceIDErrorAuthentication = 1, /// NoAccess -- InstanceID service cannot be accessed. FIRInstanceIDErrorNoAccess = 2, /// Timeout -- Request to InstanceID backend timed out. FIRInstanceIDErrorTimeout = 3, /// Network -- No network available to reach the servers. FIRInstanceIDErrorNetwork = 4, /// OperationInProgress -- Another similar operation in progress, /// bailing this one. FIRInstanceIDErrorOperationInProgress = 5, /// InvalidRequest -- Some parameters of the request were invalid. FIRInstanceIDErrorInvalidRequest = 7, }; /** * The APNS token type for the app. If the token type is set to `UNKNOWN` * InstanceID will implicitly try to figure out what the actual token type * is from the provisioning profile. */ typedef NS_ENUM(NSInteger, FIRInstanceIDAPNSTokenType) { /// Unknown token type. FIRInstanceIDAPNSTokenTypeUnknown, /// Sandbox token type. FIRInstanceIDAPNSTokenTypeSandbox, /// Production token type. FIRInstanceIDAPNSTokenTypeProd, }; /** * Instance ID provides a unique identifier for each app instance and a mechanism * to authenticate and authorize actions (for example, sending a GCM message). * * Instance ID is long lived but, may be reset if the device is not used for * a long time or the Instance ID service detects a problem. * If Instance ID is reset, the app will be notified with a `com.firebase.iid.token-refresh` * notification. * * If the Instance ID has become invalid, the app can request a new one and * send it to the app server. * To prove ownership of Instance ID and to allow servers to access data or * services associated with the app, call * `[FIRInstanceID tokenWithAuthorizedEntity:scope:options:handler]`. */ @interface FIRInstanceID : NSObject /** * FIRInstanceID. * * @return A shared instance of FIRInstanceID. */ + (nonnull instancetype)instanceID NS_SWIFT_NAME(instanceID()); /** * Unavailable. Use +instanceID instead. */ - (nonnull instancetype)init __attribute__((unavailable("Use +instanceID instead."))); /** * Set APNS token for the application. This APNS token will be used to register * with Firebase Messaging using `token` or * `tokenWithAuthorizedEntity:scope:options:handler`. If the token type is set to * `FIRInstanceIDAPNSTokenTypeUnknown` InstanceID will read the provisioning profile * to find out the token type. * * @param token The APNS token for the application. * @param type The APNS token type for the above token. */ - (void)setAPNSToken:(nonnull NSData *)token type:(FIRInstanceIDAPNSTokenType)type; #pragma mark - Tokens /** * Returns a Firebase Messaging scoped token for the firebase app. * * @return Null Returns null if the device has not yet been registerd with * Firebase Message else returns a valid token. */ - (nullable NSString *)token; /** * Returns a token that authorizes an Entity (example: cloud service) to perform * an action on behalf of the application identified by Instance ID. * * This is similar to an OAuth2 token except, it applies to the * application instance instead of a user. * * This is an asynchronous call. If the token fetching fails for some reason * we invoke the completion callback with nil `token` and the appropriate * error. * * Note, you can only have one `token` or `deleteToken` call for a given * authorizedEntity and scope at any point of time. Making another such call with the * same authorizedEntity and scope before the last one finishes will result in an * error with code `OperationInProgress`. * * @see FIRInstanceID deleteTokenWithAuthorizedEntity:scope:handler: * * @param authorizedEntity Entity authorized by the token. * @param scope Action authorized for authorizedEntity. * @param options The extra options to be sent with your token request. The * value for the `apns_token` should be the NSData object * passed to UIApplication's * `didRegisterForRemoteNotificationsWithDeviceToken` method. * All other keys and values in the options dict need to be * instances of NSString or else they will be discarded. Bundle * keys starting with 'GCM.' and 'GOOGLE.' are reserved. * @param handler The callback handler which is invoked when the token is * successfully fetched. In case of success a valid `token` and * `nil` error are returned. In case of any error the `token` * is nil and a valid `error` is returned. The valid error * codes have been documented above. */ - (void)tokenWithAuthorizedEntity:(nonnull NSString *)authorizedEntity scope:(nonnull NSString *)scope options:(nullable NSDictionary *)options handler:(nonnull FIRInstanceIDTokenHandler)handler; /** * Revokes access to a scope (action) for an entity previously * authorized by `[FIRInstanceID tokenWithAuthorizedEntity:scope:options:handler]`. * * This is an asynchronous call. Call this on the main thread since InstanceID lib * is not thread safe. In case token deletion fails for some reason we invoke the * `handler` callback passed in with the appropriate error code. * * Note, you can only have one `token` or `deleteToken` call for a given * authorizedEntity and scope at a point of time. Making another such call with the * same authorizedEntity and scope before the last one finishes will result in an error * with code `OperationInProgress`. * * @param authorizedEntity Entity that must no longer have access. * @param scope Action that entity is no longer authorized to perform. * @param handler The handler that is invoked once the unsubscribe call ends. * In case of error an appropriate error object is returned * else error is nil. */ - (void)deleteTokenWithAuthorizedEntity:(nonnull NSString *)authorizedEntity scope:(nonnull NSString *)scope handler:(nonnull FIRInstanceIDDeleteTokenHandler)handler; #pragma mark - Identity /** * Asynchronously fetch a stable identifier that uniquely identifies the app * instance. If the identifier has been revoked or has expired, this method will * return a new identifier. * * * @param handler The handler to invoke once the identifier has been fetched. * In case of error an appropriate error object is returned else * a valid identifier is returned and a valid identifier for the * application instance. */ - (void)getIDWithHandler:(nonnull FIRInstanceIDHandler)handler; /** * Resets Instance ID and revokes all tokens. */ - (void)deleteIDWithHandler:(nonnull FIRInstanceIDDeleteHandler)handler; @end ================================================ FILE: Pods/FirebaseInstanceID/Frameworks/frameworks/FirebaseInstanceID.framework/Headers/FirebaseInstanceID.h ================================================ #import "FIRInstanceID.h" ================================================ FILE: Pods/FirebaseInstanceID/Frameworks/frameworks/FirebaseInstanceID.framework/Modules/module.modulemap ================================================ framework module FirebaseInstanceID { export * umbrella header "FirebaseInstanceID.h" header "FIRInstanceID.h" } ================================================ FILE: Pods/FirebaseInstanceID/Sources/FIRInstanceID.h ================================================ #import /** * @memberof FIRInstanceID * * The scope to be used when fetching/deleting a token for Firebase Messaging. */ FOUNDATION_EXPORT NSString * __nonnull const kFIRInstanceIDScopeFirebaseMessaging; /** * Called when the system determines that tokens need to be refreshed. * This method is also called if Instance ID has been reset in which * case, tokens and FCM topic subscriptions also need to be refreshed. * * Instance ID service will throttle the refresh event across all devices * to control the rate of token updates on application servers. */ FOUNDATION_EXPORT NSString * __nonnull const kFIRInstanceIDTokenRefreshNotification; /** * @related FIRInstanceID * * The completion handler invoked when the InstanceID token returns. If * the call fails we return the appropriate `error code` as described below. * * @param token The valid token as returned by InstanceID backend. * * @param error The error describing why generating a new token * failed. See the error codes below for a more detailed * description. */ typedef void(^FIRInstanceIDTokenHandler)(NSString * __nullable token, NSError * __nullable error); /** * @related FIRInstanceID * * The completion handler invoked when the InstanceID `deleteToken` returns. If * the call fails we return the appropriate `error code` as described below * * @param error The error describing why deleting the token failed. * See the error codes below for a more detailed description. */ typedef void(^FIRInstanceIDDeleteTokenHandler)(NSError * __nullable error); /** * @related FIRInstanceID * * The completion handler invoked when the app identity is created. If the * identity wasn't created for some reason we return the appropriate error code. * * @param identity A valid identity for the app instance, nil if there was an error * while creating an identity. * @param error The error if fetching the identity fails else nil. */ typedef void(^FIRInstanceIDHandler)(NSString * __nullable identity, NSError * __nullable error); /** * @related FIRInstanceID * * The completion handler invoked when the app identity and all the tokens associated * with it are deleted. Returns a valid error object in case of failure else nil. * * @param error The error if deleting the identity and all the tokens associated with * it fails else nil. */ typedef void(^FIRInstanceIDDeleteHandler)(NSError * __nullable error); /** * @enum FIRInstanceIDError */ typedef NS_ENUM(NSUInteger, FIRInstanceIDError) { /// Unknown error. FIRInstanceIDErrorUnknown = 0, /// Auth Error -- FCM couldn't validate request from this client. FIRInstanceIDErrorAuthentication = 1, /// NoAccess -- InstanceID service cannot be accessed. FIRInstanceIDErrorNoAccess = 2, /// Timeout -- Request to InstanceID backend timed out. FIRInstanceIDErrorTimeout = 3, /// Network -- No network available to reach the servers. FIRInstanceIDErrorNetwork = 4, /// OperationInProgress -- Another similar operation in progress, /// bailing this one. FIRInstanceIDErrorOperationInProgress = 5, /// InvalidRequest -- Some parameters of the request were invalid. FIRInstanceIDErrorInvalidRequest = 7, }; /** * The APNS token type for the app. If the token type is set to `UNKNOWN` * InstanceID will implicitly try to figure out what the actual token type * is from the provisioning profile. */ typedef NS_ENUM(NSInteger, FIRInstanceIDAPNSTokenType) { /// Unknown token type. FIRInstanceIDAPNSTokenTypeUnknown, /// Sandbox token type. FIRInstanceIDAPNSTokenTypeSandbox, /// Production token type. FIRInstanceIDAPNSTokenTypeProd, }; /** * Instance ID provides a unique identifier for each app instance and a mechanism * to authenticate and authorize actions (for example, sending a GCM message). * * Instance ID is long lived but, may be reset if the device is not used for * a long time or the Instance ID service detects a problem. * If Instance ID is reset, the app will be notified with a `com.firebase.iid.token-refresh` * notification. * * If the Instance ID has become invalid, the app can request a new one and * send it to the app server. * To prove ownership of Instance ID and to allow servers to access data or * services associated with the app, call * `[FIRInstanceID tokenWithAuthorizedEntity:scope:options:handler]`. */ @interface FIRInstanceID : NSObject /** * FIRInstanceID. * * @return A shared instance of FIRInstanceID. */ + (nonnull instancetype)instanceID; /** * Set APNS token for the application. This APNS token will be used to register * with Firebase Messaging using `token` or * `tokenWithAuthorizedEntity:scope:options:handler`. If the token type is set to * `FIRInstanceIDAPNSTokenTypeUnknown` InstanceID will read the provisioning profile * to find out the token type. * * @param token The APNS token for the application. * @param type The APNS token type for the above token. */ - (void)setAPNSToken:(nonnull NSData *)token type:(FIRInstanceIDAPNSTokenType)type; #pragma mark - Tokens /** * Returns a Firebase Messaging scoped token for the firebase app. * * @return Null Returns null if the device has not yet been registerd with * Firebase Message else returns a valid token. */ - (nullable NSString *)token; /** * Returns a token that authorizes an Entity (example: cloud service) to perform * an action on behalf of the application identified by Instance ID. * * This is similar to an OAuth2 token except, it applies to the * application instance instead of a user. * * This is an asynchronous call. If the token fetching fails for some reason * we invoke the completion callback with nil `token` and the appropriate * error. * * Note, you can only have one `token` or `deleteToken` call for a given * authorizedEntity and scope at any point of time. Making another such call with the * same authorizedEntity and scope before the last one finishes will result in an * error with code `OperationInProgress`. * * @see FIRInstanceID deleteTokenWithAuthorizedEntity:scope:handler: * * @param authorizedEntity Entity authorized by the token. * @param scope Action authorized for authorizedEntity. * @param options The extra options to be sent with your token request. The * value for the `apns_token` should be the NSData object * passed to UIApplication's * `didRegisterForRemoteNotificationsWithDeviceToken` method. * All other keys and values in the options dict need to be * instances of NSString or else they will be discarded. Bundle * keys starting with 'GCM.' and 'GOOGLE.' are reserved. * @param handler The callback handler which is invoked when the token is * successfully fetched. In case of success a valid `token` and * `nil` error are returned. In case of any error the `token` * is nil and a valid `error` is returned. The valid error * codes have been documented above. */ - (void)tokenWithAuthorizedEntity:(nonnull NSString *)authorizedEntity scope:(nonnull NSString *)scope options:(nonnull NSDictionary *)options handler:(nonnull FIRInstanceIDTokenHandler)handler; /** * Revokes access to a scope (action) for an entity previously * authorized by `[FIRInstanceID tokenWithAuthorizedEntity:scope:options:handler]`. * * This is an asynchronous call. Call this on the main thread since InstanceID lib * is not thread safe. In case token deletion fails for some reason we invoke the * `handler` callback passed in with the appropriate error code. * * Note, you can only have one `token` or `deleteToken` call for a given * authorizedEntity and scope at a point of time. Making another such call with the * same authorizedEntity and scope before the last one finishes will result in an error * with code `OperationInProgress`. * * @param authorizedEntity Entity that must no longer have access. * @param scope Action that entity is no longer authorized to perform. * @param handler The handler that is invoked once the unsubscribe call ends. * In case of error an appropriate error object is returned * else error is nil. */ - (void)deleteTokenWithAuthorizedEntity:(nonnull NSString *)authorizedEntity scope:(nonnull NSString *)scope handler:(nonnull FIRInstanceIDDeleteTokenHandler)handler; #pragma mark - Identity /** * Asynchronously fetch a stable identifier that uniquely identifies the app * instance. If the identifier has been revoked or has expired, this method will * return a new identifier. * * * @param handler The handler to invoke once the identifier has been fetched. * In case of error an appropriate error object is returned else * a valid identifier is returned and a valid identifier for the * application instance. */ - (void)getIDWithHandler:(nonnull FIRInstanceIDHandler)handler; /** * Resets Instance ID and revokes all tokens. */ - (void)deleteIDWithHandler:(nonnull FIRInstanceIDDeleteHandler)handler; @end ================================================ FILE: Pods/FirebaseStorage/Frameworks/frameworks/FirebaseStorage.framework/Headers/FIRStorage.h ================================================ // clang-format off /** @file FIRStorage.h @brief Firebase SDK @copyright Copyright 2016 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ // clang-format on #import #import "FIRStorageConstants.h" @class FIRApp; @class FIRStorageReference; NS_ASSUME_NONNULL_BEGIN /** * FirebaseStorage is a service that supports uploading and downloading binary objects, * such as images, videos, and other files to Google Cloud Storage. * * If you call [FIRStorage storage], the instance will initialize with the default FIRApp, * [FIRApp defaultApp], and the storage location will come from the provided * GoogleService-Info.plist. * * If you call [FIRStorage storageForApp:] and provide a custom instance of FIRApp, * the storage location will be specified via the FIROptions#storageBucket property. */ @interface FIRStorage : NSObject /** * Creates an instance of FIRStorage, configured with the default FIRApp. * @return the FIRStorage instance, initialized with the default FIRApp. */ + (instancetype)storage NS_SWIFT_NAME(storage()); /** * Creates an instance of FIRStorage, configured with the custom FIRApp @a app. * @param app The custom FIRApp used for initialization. * @return the FIRStorage instance, initialized with the custom FIRApp. */ + (instancetype)storageForApp:(FIRApp *)app NS_SWIFT_NAME(storage(app:)); /** * The Firebase App associated with this Firebase Storage instance. */ @property(strong, nonatomic, readonly) FIRApp *app; /** * Maximum time in seconds to retry an upload if a failure occurs. * Defaults to 10 minutes (600 seconds). */ @property NSTimeInterval maxUploadRetryTime; /** * Maximum time in seconds to retry a download if a failure occurs. * Defaults to 10 minutes (600 seconds). */ @property NSTimeInterval maxDownloadRetryTime; /** * Maximum time in seconds to retry operations other than upload and download if a failure occurs. * Defaults to 2 minutes (120 seconds). */ @property NSTimeInterval maxOperationRetryTime; /** * Queue that all developer callbacks are fired on. Defaults to the main queue. */ @property(strong, nonatomic) dispatch_queue_t callbackQueue; /** * Creates a FIRStorageReference initialized at the root Firebase Storage location. * @return An instance of FIRStorageReference initialized at the root. */ - (FIRStorageReference *)reference; /** * Creates a FIRStorageReference given a gs:// or https:// URL pointing to a Firebase Storage * location. For example, you can pass in an https:// download URL retrieved from * [FIRStorageReference getDownloadURL] or the gs:// URI from [FIRStorageReference description]. * @param string A gs:// or https:// URL to initialize the reference with. * @return An instance of FIRStorageReference at the given child path. * @throws Throws an exception if passed in URL is not associated with the FIRApp used to initialize * this FIRStorage. */ - (FIRStorageReference *)referenceForURL:(NSString *)string; /** * Creates a FIRStorageReference initialized at a child Firebase Storage location. * @param string A relative path from the root to initialize the reference with, * for instance @"path/to/object". * @return An instance of FIRStorageReference at the given child path. */ - (FIRStorageReference *)referenceWithPath:(NSString *)string; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseStorage/Frameworks/frameworks/FirebaseStorage.framework/Headers/FIRStorageConstants.h ================================================ // clang-format off /** @file FIRStorageConstants.h @brief Firebase SDK @copyright Copyright 2016 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ // clang-format on #import @class FIRStorageDownloadTask; @class FIRStorageMetadata; @class FIRStorageTaskSnapshot; @class FIRStorageUploadTask; NS_ASSUME_NONNULL_BEGIN /** * NSString typedef representing a task listener handle. */ typedef NSString *FIRStorageHandle; /** * Block typedef typically used when downloading data. * @param data The data returned by the download, or nil if no data available or download failed. * @param error The error describing failure, if one occurred. */ typedef void (^FIRStorageVoidDataError)(NSData *_Nullable data, NSError *_Nullable error); /** * Block typedef typically used when performing "binary" async operations such as delete, * where the operation either succeeds without an error or fails with an error. * @param error The error describing failure, if one occurred. */ typedef void (^FIRStorageVoidError)(NSError *_Nullable error); /** * Block typedef typically used when retrieving metadata. * @param metadata The metadata returned by the operation, if metadata exists. */ typedef void (^FIRStorageVoidMetadata)(FIRStorageMetadata *_Nullable metadata); /** * Block typedef typically used when retrieving metadata with the possibility of an error. * @param metadata The metadata returned by the operation, if metadata exists. * @param error The error describing failure, if one occurred. */ typedef void (^FIRStorageVoidMetadataError)(FIRStorageMetadata *_Nullable metadata, NSError *_Nullable error); /** * Block typedef typically used when getting or updating metadata with the possibility of an error. * @param metadata The metadata returned by the operation, if metadata exists. * @param error The error describing failure, if one occurred. */ typedef void (^FIRStorageVoidSnapshot)(FIRStorageTaskSnapshot *snapshot); /** * Block typedef typically used when retrieving a download URL. * @param URL The download URL associated with the operation. * @param error The error describing failure, if one occurred. */ typedef void (^FIRStorageVoidURLError)(NSURL *_Nullable URL, NSError *_Nullable error); /** * Enum representing the upload and download task status. */ typedef NS_ENUM(NSInteger, FIRStorageTaskStatus) { /** * Unknown task status. */ FIRStorageTaskStatusUnknown, /** * Task is being resumed. */ FIRStorageTaskStatusResume, /** * Task reported a progress event. */ FIRStorageTaskStatusProgress, /** * Task is paused. */ FIRStorageTaskStatusPause, /** * Task has completed successfully. */ FIRStorageTaskStatusSuccess, /** * Task has failed and is unrecoverable. */ FIRStorageTaskStatusFailure }; /** * Firebase Storage error domain. */ FOUNDATION_EXPORT NSString *const FIRStorageErrorDomain; /** * Enum representing the errors raised by Firebase Storage. */ typedef NS_ENUM(NSInteger, FIRStorageErrorCode) { FIRStorageErrorCodeUnknown = -13000, FIRStorageErrorCodeObjectNotFound = -13010, FIRStorageErrorCodeBucketNotFound = -13011, FIRStorageErrorCodeProjectNotFound = -13012, FIRStorageErrorCodeQuotaExceeded = -13013, FIRStorageErrorCodeUnauthenticated = -13020, FIRStorageErrorCodeUnauthorized = -13021, FIRStorageErrorCodeRetryLimitExceeded = -13030, FIRStorageErrorCodeNonMatchingChecksum = -13031, FIRStorageErrorCodeDownloadSizeExceeded = -13032, FIRStorageErrorCodeCancelled = -13040 }; NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseStorage/Frameworks/frameworks/FirebaseStorage.framework/Headers/FIRStorageDownloadTask.h ================================================ // clang-format off /** @file FIRStorageDownloadTask.h @brief Firebase SDK @copyright Copyright 2016 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ // clang-format on #import #import "FIRStorageObservableTask.h" NS_ASSUME_NONNULL_BEGIN /** * FIRStorageDownloadTask implements resumable downloads from an object in Firebase Storage. * Downloads can be returned on completion with a completion handler, and can be monitored * by attaching observers, or controlled by calling FIRStorageTask#pause, FIRStorageTask#resume, * or FIRStorageTask#cancel. * Downloads can currently be returned as NSData in memory, or as an NSURL to a file on disk. * Downloads are performed on a background queue, and callbacks are raised on the developer * specified callbackQueue in FIRStorage, or the main queue if left unspecified. * Currently all uploads must be initiated and managed on the main queue. */ @interface FIRStorageDownloadTask : FIRStorageObservableTask @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseStorage/Frameworks/frameworks/FirebaseStorage.framework/Headers/FIRStorageMetadata.h ================================================ // clang-format off /** @file FIRStorageMetadata.h @brief Firebase SDK @copyright Copyright 2016 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ // clang-format on #import @class FIRStorageReference; NS_ASSUME_NONNULL_BEGIN /** * Class which represents the metadata on an object in Firebase Storage. This metadata is * returned on successful operations, and can be used to retrieve download URLs, content types, * and a FIRStorage reference to the object in question. Full documentation can be found at the GCS * Objects#resource docs. * @see https://cloud.google.com/storage/docs/json_api/v1/objects#resource */ @interface FIRStorageMetadata : NSObject /** * The name of the bucket containing this object. */ @property(copy, nonatomic, readonly) NSString *bucket; /** * Cache-Control directive for the object data. */ @property(copy, nonatomic, nullable) NSString *cacheControl; /** * Content-Disposition of the object data. */ @property(copy, nonatomic, nullable) NSString *contentDisposition; /** * Content-Encoding of the object data. */ @property(copy, nonatomic, nullable) NSString *contentEncoding; /** * Content-Language of the object data. */ @property(copy, nonatomic, nullable) NSString *contentLanguage; /** * Content-Type of the object data. */ @property(copy, nonatomic, nullable) NSString *contentType; /** * The content generation of this object. Used for object versioning. */ @property(readonly) int64_t generation; /** * User-provided metadata, in key/value pairs. */ @property(copy, nonatomic, nullable) NSDictionary *customMetadata; /** * The version of the metadata for this object at this generation. Used * for preconditions and for detecting changes in metadata. A metageneration number is only * meaningful in the context of a particular generation of a particular object. */ @property(readonly) int64_t metageneration; /** * The name of this object, in gs://bucket/path/to/object.txt, this is object.txt. */ @property(copy, nonatomic, readonly, nullable) NSString *name; /** * The full path of this object, in gs://bucket/path/to/object.txt, this is path/to/object.txt. */ @property(copy, nonatomic, readonly, nullable) NSString *path; /** * Content-Length of the data in bytes. */ @property(readonly) int64_t size; /** * The creation time of the object in RFC 3339 format. */ @property(copy, nonatomic, readonly, nullable) NSDate *timeCreated; /** * The modification time of the object metadata in RFC 3339 format. */ @property(copy, nonatomic, readonly, nullable) NSDate *updated; /** * A reference to the object in Firebase Storage. */ @property(strong, nonatomic, readonly, nullable) FIRStorageReference *storageReference; /** * An array containing all download URLs available for the object. */ @property(strong, nonatomic, readonly, nullable) NSArray *downloadURLs; /** * Creates an instanece of FIRStorageMetadata from the contents of a dictionary. * @return An instance of FIRStorageMetadata that represents the contents of a dictionary. */ - (nullable instancetype)initWithDictionary:(NSDictionary *)dictionary NS_DESIGNATED_INITIALIZER; /** * Creates an NSDictionary from the contents of the metadata. * @return An NSDictionary that represents the contents of the metadata. */ - (NSDictionary *)dictionaryRepresentation; /** * Determines if the current metadata represents a "file". */ @property(readonly, getter=isFile) BOOL file; /** * Determines if the current metadata represents a "folder". */ @property(readonly, getter=isFolder) BOOL folder; /** * Retrieves a download URL for the given object, or nil if none exist. * Note that if there are many valid download tokens, this will always return the first * valid token created. */ - (nullable NSURL *)downloadURL; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseStorage/Frameworks/frameworks/FirebaseStorage.framework/Headers/FIRStorageObservableTask.h ================================================ // clang-format off /** @file FIRStorageObservableTask.h @brief Firebase SDK @copyright Copyright 2016 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ // clang-format on #import "FIRStorageTask.h" NS_ASSUME_NONNULL_BEGIN @class FIRStorageReference; @class FIRStorageTaskSnapshot; /** * Extends FIRStorageTask to provide observable semantics such as adding and removing observers. * Observers produce a FIRStorageHandle, which is used to keep track of and remove specific * observers at a later date. * This class is currently not thread safe and can only be called on the main thread. */ @interface FIRStorageObservableTask : FIRStorageTask /** * Observes changes in the upload status: Resume, Pause, Progress, Success, and Failure. * @param status The FIRStorageTaskStatus change to observe. * @param handler A callback that fires every time the status event occurs, * returns a FIRStorageTaskSnapshot containing the state of the task. * @return A task handle that can be used to remove the observer at a later date. */ - (FIRStorageHandle)observeStatus:(FIRStorageTaskStatus)status handler:(void (^)(FIRStorageTaskSnapshot *snapshot))handler; /** * Removes the single observer with the provided handle. * @param handle The handle of the task to remove. */ - (void)removeObserverWithHandle:(FIRStorageHandle)handle; /** * Removes all observers for a single status. * @param status A FIRStorageTaskStatus to remove listeners for. */ - (void)removeAllObserversForStatus:(FIRStorageTaskStatus)status; /** * Removes all observers. */ - (void)removeAllObservers; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseStorage/Frameworks/frameworks/FirebaseStorage.framework/Headers/FIRStorageReference.h ================================================ // clang-format off /** @file FIRStorageReference.h @brief Firebase SDK @copyright Copyright 2016 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ // clang-format on #import #import "FIRStorage.h" #import "FIRStorageConstants.h" #import "FIRStorageDownloadTask.h" #import "FIRStorageMetadata.h" #import "FIRStorageTask.h" #import "FIRStorageUploadTask.h" NS_ASSUME_NONNULL_BEGIN /** * FIRStorageReference represents a reference to a Google Cloud Storage object. Developers can * upload and download objects, as well as get/set object metadata, and delete an object at the * path. * @see https://cloud.google.com/storage/ */ @interface FIRStorageReference : NSObject /** * The FIRStorage service object which created this reference. */ @property(nonatomic, readonly) FIRStorage *storage; /** * The name of the Google Cloud Storage bucket associated with this reference, * in gs://bucket/path/to/object.txt, the bucket would be: 'bucket' */ @property(nonatomic, readonly) NSString *bucket; /** * The full path to this object, not including the Google Cloud Storage bucket. * In gs://bucket/path/to/object.txt, the full path would be: 'path/to/object.txt' */ @property(nonatomic, readonly) NSString *fullPath; /** * The short name of the object associated with this reference, * in gs://bucket/path/to/object.txt, the name of the object would be: 'object.txt' */ @property(nonatomic, readonly) NSString *name; #pragma mark - Path Operations /** * Creates a new FIRStorageReference pointing to the root object. * @return A new FIRStorageReference pointing to the root object. */ - (FIRStorageReference *)root; /** * Creates a new FIRStorageReference pointing to the parent of the current reference * or nil if this instance references the root location. * For example: * path = foo/bar/baz parent = foo/bar * path = foo parent = (root) * path = (root) parent = nil * @return A new FIRStorageReference pointing to the parent of the current reference. */ - (nullable FIRStorageReference *)parent; /** * Creates a new FIRStorageReference pointing to a child object of the current reference. * path = foo child = bar newPath = foo/bar * path = foo/bar child = baz newPath = foo/bar/baz * All leading and trailing slashes will be removed, and consecutive slashes will be * compressed to single slashes. For example: * child = /foo/bar newPath = foo/bar * child = foo/bar/ newPath = foo/bar * child = foo///bar newPath = foo/bar * @param path Path to append to the current path. * @return A new FIRStorageReference pointing to a child location of the current reference. */ - (FIRStorageReference *)child:(NSString *)path; #pragma mark - Uploads /** * Asynchronously uploads data to the currently specified FIRStorageReference, * without additional metadata. * This is not recommended for large files, and one should instead upload a file from disk. * @param uploadData The NSData to upload. * @return An instance of FIRStorageUploadTask, which can be used to monitor or manage the upload. */ - (FIRStorageUploadTask *)putData:(NSData *)uploadData; /** * Asynchronously uploads data to the currently specified FIRStorageReference. * This is not recommended for large files, and one should instead upload a file from disk. * @param uploadData The NSData to upload. * @param metadata FIRStorageMetadata containing additional information (MIME type, etc.) * about the object being uploaded. * @return An instance of FIRStorageUploadTask, which can be used to monitor or manage the upload. */ - (FIRStorageUploadTask *)putData:(NSData *)uploadData metadata:(nullable FIRStorageMetadata *)metadata; /** * Asynchronously uploads data to the currently specified FIRStorageReference. * This is not recommended for large files, and one should instead upload a file from disk. * @param uploadData The NSData to upload. * @param metadata FIRStorageMetadata containing additional information (MIME type, etc.) * about the object being uploaded. * @param completion A completion block that either returns the object metadata on success, * or an error on failure. * @return An instance of FIRStorageUploadTask, which can be used to monitor or manage the upload. */ - (FIRStorageUploadTask *)putData:(NSData *)uploadData metadata:(nullable FIRStorageMetadata *)metadata completion:(nullable void (^)(FIRStorageMetadata *_Nullable metadata, NSError *_Nullable error))completion; /** * Asynchronously uploads a file to the currently specified FIRStorageReference, * without additional metadata. * @param fileURL A URL representing the system file path of the object to be uploaded. * @return An instance of FIRStorageUploadTask, which can be used to monitor or manage the upload. */ - (FIRStorageUploadTask *)putFile:(NSURL *)fileURL; /** * Asynchronously uploads a file to the currently specified FIRStorageReference. * @param fileURL A URL representing the system file path of the object to be uploaded. * @param metadata FIRStorageMetadata containing additional information (MIME type, etc.) * about the object being uploaded. * @return An instance of FIRStorageUploadTask, which can be used to monitor or manage the upload. */ - (FIRStorageUploadTask *)putFile:(NSURL *)fileURL metadata:(nullable FIRStorageMetadata *)metadata; /** * Asynchronously uploads a file to the currently specified FIRStorageReference. * @param fileURL A URL representing the system file path of the object to be uploaded. * @param metadata FIRStorageMetadata containing additional information (MIME type, etc.) * about the object being uploaded. * @param completion A completion block that either returns the object metadata on success, * or an error on failure. * @return An instance of FIRStorageUploadTask, which can be used to monitor or manage the upload. */ - (FIRStorageUploadTask *)putFile:(NSURL *)fileURL metadata:(nullable FIRStorageMetadata *)metadata completion:(nullable void (^)(FIRStorageMetadata *_Nullable metadata, NSError *_Nullable error))completion; #pragma mark - Downloads /** * Asynchronously downloads the object at the FIRStorageReference to an NSData object in memory. * An NSData of the provided max size will be allocated, so ensure that the device has enough free * memory to complete the download. For downloading large files, writeToFile may be a better option. * @param size The maximum size in bytes to download. If the download exceeds this size * the task will be cancelled and an error will be returned. * @param completion A completion block that either returns the object data on success, * or an error on failure. * @return An FIRStorageDownloadTask that can be used to monitor or manage the download. */ - (FIRStorageDownloadTask *)dataWithMaxSize:(int64_t)size completion:(void (^)(NSData *_Nullable data, NSError *_Nullable error))completion; /** * Asynchronously retrieves a long lived download URL with a revokable token. * This can be used to share the file with others, but can be revoked by a developer * in the Firebase Console if desired. * @param completion A completion block that either returns the URL on success, * or an error on failure. */ - (void)downloadURLWithCompletion:(void (^)(NSURL *_Nullable URL, NSError *_Nullable error))completion; /** * Asynchronously downloads the object at the current path to a specified system filepath. * @param fileURL A file system URL representing the path the object should be downloaded to. * @return An FIRStorageDownloadTask that can be used to monitor or manage the download. */ - (FIRStorageDownloadTask *)writeToFile:(NSURL *)fileURL; /** * Asynchronously downloads the object at the current path to a specified system filepath. * @param fileURL A file system URL representing the path the object should be downloaded to. * @param completion A completion block that fires when the file download completes. * Returns an NSURL pointing to the file path of the downloaded file on success, * or an error on failure. * @return An FIRStorageDownloadTask that can be used to monitor or manage the download. */ - (FIRStorageDownloadTask *)writeToFile:(NSURL *)fileURL completion:(nullable void (^)(NSURL *_Nullable URL, NSError *_Nullable error))completion; #pragma mark - Metadata Operations /** * Retrieves metadata associated with an object at the current path. * @param completion A completion block which returns the object metadata on success, * or an error on failure. */ - (void)metadataWithCompletion:(void (^)(FIRStorageMetadata *_Nullable metadata, NSError *_Nullable error))completion; /** * Updates the metadata associated with an object at the current path. * @param metadata An FIRStorageMetadata object with the metadata to update. * @param completion A completion block which returns the FIRStorageMetadata on success, * or an error on failure. */ - (void)updateMetadata:(FIRStorageMetadata *)metadata completion:(nullable void (^)(FIRStorageMetadata *_Nullable metadata, NSError *_Nullable error))completion; #pragma mark - Delete /** * Deletes the object at the current path. * @param completion A completion block which returns nil on success, or an error on failure. */ - (void)deleteWithCompletion:(nullable void (^)(NSError *_Nullable error))completion; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseStorage/Frameworks/frameworks/FirebaseStorage.framework/Headers/FIRStorageTask.h ================================================ // clang-format off /** @file FIRStorageTask.h @brief Firebase SDK @copyright Copyright 2016 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ // clang-format on #import #import "FIRStorageConstants.h" #import "FIRStorageMetadata.h" NS_ASSUME_NONNULL_BEGIN /** * A superclass to all FIRStorage*Tasks, including FIRStorageUploadTask * and FIRStorageDownloadTask, to provide state transitions, event raising, and common storage * or metadata and errors. * Callbacks are always fired on the developer specified callback queue. * If no queue is specified by the developer, it defaults to the main queue. * Currently not thread safe, so only call methods on the main thread. */ @interface FIRStorageTask : NSObject /** * An immutable view of the task and associated metadata, progress, error, etc. */ @property(strong, readonly, nonatomic, nonnull) FIRStorageTaskSnapshot *snapshot; @end /** * Defines task operations such as pause, resume, cancel, and enqueue for all tasks. * All tasks are required to implement enqueue, which begins the task, and may optionally * implement pause, resume, and cancel, which operate on the task to pause, resume, and cancel * operations. */ @protocol FIRStorageTaskManagement @required /** * Prepares a task and begins execution. */ - (void)enqueue; @optional /** * Pauses a task currently in progress. */ - (void)pause; /** * Cancels a task currently in progress. */ - (void)cancel; /** * Resumes a task that is paused. */ - (void)resume; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseStorage/Frameworks/frameworks/FirebaseStorage.framework/Headers/FIRStorageTaskSnapshot.h ================================================ // clang-format off /** @file FIRStorageTaskSnapshot.h @brief Firebase SDK @copyright Copyright 2016 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ // clang-format on #import #import "FIRStorageConstants.h" NS_ASSUME_NONNULL_BEGIN @class FIRStorageMetadata; @class FIRStorageReference; @class FIRStorageTask; /** * FIRStorageTaskSnapshot represents an immutable view of a task. * A Snapshot contains a task, storage reference, metadata (if it exists), * progress, and an error (if one occurred). */ @interface FIRStorageTaskSnapshot : NSObject /** * Subclass of FIRStorageTask this snapshot represents. */ @property(readonly, copy, nonatomic) __kindof FIRStorageTask *task; /** * Metadata returned by the task, or nil if no metadata returned. */ @property(readonly, copy, nonatomic, nullable) FIRStorageMetadata *metadata; /** * FIRStorageReference this task is operates on. */ @property(readonly, copy, nonatomic) FIRStorageReference *reference; /** * NSProgress object which tracks the progess of an upload or download. */ @property(readonly, strong, nonatomic, nullable) NSProgress *progress; /** * Error during task execution, or nil if no error occurred. */ @property(readonly, copy, nonatomic, nullable) NSError *error; /** * Status of the task. */ @property(readonly, nonatomic) FIRStorageTaskStatus status; @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseStorage/Frameworks/frameworks/FirebaseStorage.framework/Headers/FIRStorageUploadTask.h ================================================ // clang-format off /** @file FIRStorageUploadTask.h @brief Firebase SDK @copyright Copyright 2016 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ // clang-format on #import #import "FIRStorageObservableTask.h" NS_ASSUME_NONNULL_BEGIN /** * FIRStorageUploadTask implements resumable uploads to a file in Firebase Storage. * Uploads can be returned on completion with a completion callback, and can be monitored * by attaching observers, or controlled by calling FIRStorageTask#pause, FIRStorageTask#resume, * or FIRStorageTask#cancel. * Uploads can take NSData in memory, or an NSURL to a file on disk. * Uploads are performed on a background queue, and callbacks are raised on the developer * specified callbackQueue in FIRStorage, or the main queue if left unspecified. * Currently all uploads must be initiated and managed on the main queue. */ @interface FIRStorageUploadTask : FIRStorageObservableTask @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/FirebaseStorage/Frameworks/frameworks/FirebaseStorage.framework/Headers/FirebaseStorage.h ================================================ // clang-format off /** @file FirebaseStorage.m @brief Firebase SDK @copyright Copyright 2016 Google Inc. @remarks Use of this SDK is subject to the Google APIs Terms of Service: https://developers.google.com/terms/ */ // clang-format on #import "FIRStorage.h" #import "FIRStorageConstants.h" #import "FIRStorageDownloadTask.h" #import "FIRStorageMetadata.h" #import "FIRStorageObservableTask.h" #import "FIRStorageReference.h" #import "FIRStorageTask.h" #import "FIRStorageTaskSnapshot.h" #import "FIRStorageUploadTask.h" //! Project version string for FirebaseStorage. FOUNDATION_EXPORT const unsigned char *const FirebaseStorageVersionString; ================================================ FILE: Pods/FirebaseStorage/Frameworks/frameworks/FirebaseStorage.framework/Modules/module.modulemap ================================================ framework module FirebaseStorage { export * umbrella header "FirebaseStorage.h" header "FIRStorage.h" header "FIRStorageConstants.h" header "FIRStorageDownloadTask.h" header "FIRStorageMetadata.h" header "FIRStorageObservableTask.h" header "FIRStorageReference.h" header "FIRStorageTask.h" header "FIRStorageTaskSnapshot.h" header "FIRStorageUploadTask.h" link framework "MobileCoreServices" } ================================================ FILE: Pods/MBProgressHUD/LICENSE ================================================ Copyright © 2009-2016 Matej Bukovinski 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. ================================================ FILE: Pods/MBProgressHUD/MBProgressHUD.h ================================================ // // MBProgressHUD.h // Version 1.0.0 // Created by Matej Bukovinski on 2.4.09. // // This code is distributed under the terms and conditions of the MIT license. // Copyright © 2009-2016 Matej Bukovinski // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import #import #import @class MBBackgroundView; @protocol MBProgressHUDDelegate; extern CGFloat const MBProgressMaxOffset; typedef NS_ENUM(NSInteger, MBProgressHUDMode) { /// UIActivityIndicatorView. MBProgressHUDModeIndeterminate, /// A round, pie-chart like, progress view. MBProgressHUDModeDeterminate, /// Horizontal progress bar. MBProgressHUDModeDeterminateHorizontalBar, /// Ring-shaped progress view. MBProgressHUDModeAnnularDeterminate, /// Shows a custom view. MBProgressHUDModeCustomView, /// Shows only labels. MBProgressHUDModeText }; typedef NS_ENUM(NSInteger, MBProgressHUDAnimation) { /// Opacity animation MBProgressHUDAnimationFade, /// Opacity + scale animation (zoom in when appearing zoom out when disappearing) MBProgressHUDAnimationZoom, /// Opacity + scale animation (zoom out style) MBProgressHUDAnimationZoomOut, /// Opacity + scale animation (zoom in style) MBProgressHUDAnimationZoomIn }; typedef NS_ENUM(NSInteger, MBProgressHUDBackgroundStyle) { /// Solid color background MBProgressHUDBackgroundStyleSolidColor, /// UIVisualEffectView or UIToolbar.layer background view MBProgressHUDBackgroundStyleBlur }; typedef void (^MBProgressHUDCompletionBlock)(); NS_ASSUME_NONNULL_BEGIN /** * Displays a simple HUD window containing a progress indicator and two optional labels for short messages. * * This is a simple drop-in class for displaying a progress HUD view similar to Apple's private UIProgressHUD class. * The MBProgressHUD window spans over the entire space given to it by the initWithFrame: constructor and catches all * user input on this region, thereby preventing the user operations on components below the view. * * @note To still allow touches to pass through the HUD, you can set hud.userInteractionEnabled = NO. * @attention MBProgressHUD is a UI class and should therefore only be accessed on the main thread. */ @interface MBProgressHUD : UIView /** * Creates a new HUD, adds it to provided view and shows it. The counterpart to this method is hideHUDForView:animated:. * * @note This method sets removeFromSuperViewOnHide. The HUD will automatically be removed from the view hierarchy when hidden. * * @param view The view that the HUD will be added to * @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use * animations while appearing. * @return A reference to the created HUD. * * @see hideHUDForView:animated: * @see animationType */ + (instancetype)showHUDAddedTo:(UIView *)view animated:(BOOL)animated; /// @name Showing and hiding /** * Finds the top-most HUD subview and hides it. The counterpart to this method is showHUDAddedTo:animated:. * * @note This method sets removeFromSuperViewOnHide. The HUD will automatically be removed from the view hierarchy when hidden. * * @param view The view that is going to be searched for a HUD subview. * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use * animations while disappearing. * @return YES if a HUD was found and removed, NO otherwise. * * @see showHUDAddedTo:animated: * @see animationType */ + (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated; /** * Finds the top-most HUD subview and returns it. * * @param view The view that is going to be searched. * @return A reference to the last HUD subview discovered. */ + (nullable MBProgressHUD *)HUDForView:(UIView *)view; /** * A convenience constructor that initializes the HUD with the view's bounds. Calls the designated constructor with * view.bounds as the parameter. * * @param view The view instance that will provide the bounds for the HUD. Should be the same instance as * the HUD's superview (i.e., the view that the HUD will be added to). */ - (instancetype)initWithView:(UIView *)view; /** * Displays the HUD. * * @note You need to make sure that the main thread completes its run loop soon after this method call so that * the user interface can be updated. Call this method when your task is already set up to be executed in a new thread * (e.g., when using something like NSOperation or making an asynchronous call like NSURLRequest). * * @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use * animations while appearing. * * @see animationType */ - (void)showAnimated:(BOOL)animated; /** * Hides the HUD. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to * hide the HUD when your task completes. * * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use * animations while disappearing. * * @see animationType */ - (void)hideAnimated:(BOOL)animated; /** * Hides the HUD after a delay. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to * hide the HUD when your task completes. * * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use * animations while disappearing. * @param delay Delay in seconds until the HUD is hidden. * * @see animationType */ - (void)hideAnimated:(BOOL)animated afterDelay:(NSTimeInterval)delay; /** * The HUD delegate object. Receives HUD state notifications. */ @property (weak, nonatomic) id delegate; /** * Called after the HUD is hiden. */ @property (copy, nullable) MBProgressHUDCompletionBlock completionBlock; /* * Grace period is the time (in seconds) that the invoked method may be run without * showing the HUD. If the task finishes before the grace time runs out, the HUD will * not be shown at all. * This may be used to prevent HUD display for very short tasks. * Defaults to 0 (no grace time). */ @property (assign, nonatomic) NSTimeInterval graceTime; /** * The minimum time (in seconds) that the HUD is shown. * This avoids the problem of the HUD being shown and than instantly hidden. * Defaults to 0 (no minimum show time). */ @property (assign, nonatomic) NSTimeInterval minShowTime; /** * Removes the HUD from its parent view when hidden. * Defaults to NO. */ @property (assign, nonatomic) BOOL removeFromSuperViewOnHide; /// @name Appearance /** * MBProgressHUD operation mode. The default is MBProgressHUDModeIndeterminate. */ @property (assign, nonatomic) MBProgressHUDMode mode; /** * A color that gets forwarded to all labels and supported indicators. Also sets the tintColor * for custom views on iOS 7+. Set to nil to manage color individually. * Defaults to semi-translucent black on iOS 7 and later and white on earlier iOS versions. */ @property (strong, nonatomic, nullable) UIColor *contentColor UI_APPEARANCE_SELECTOR; /** * The animation type that should be used when the HUD is shown and hidden. */ @property (assign, nonatomic) MBProgressHUDAnimation animationType UI_APPEARANCE_SELECTOR; /** * The bezel offset relative to the center of the view. You can use MBProgressMaxOffset * and -MBProgressMaxOffset to move the HUD all the way to the screen edge in each direction. * E.g., CGPointMake(0.f, MBProgressMaxOffset) would position the HUD centered on the bottom edge. */ @property (assign, nonatomic) CGPoint offset UI_APPEARANCE_SELECTOR; /** * The amount of space between the HUD edge and the HUD elements (labels, indicators or custom views). * This also represents the minimum bezel distance to the edge of the HUD view. * Defaults to 20.f */ @property (assign, nonatomic) CGFloat margin UI_APPEARANCE_SELECTOR; /** * The minimum size of the HUD bezel. Defaults to CGSizeZero (no minimum size). */ @property (assign, nonatomic) CGSize minSize UI_APPEARANCE_SELECTOR; /** * Force the HUD dimensions to be equal if possible. */ @property (assign, nonatomic, getter = isSquare) BOOL square UI_APPEARANCE_SELECTOR; /** * When enabled, the bezel center gets slightly affected by the device accelerometer data. * Has no effect on iOS < 7.0. Defaults to YES. */ @property (assign, nonatomic, getter=areDefaultMotionEffectsEnabled) BOOL defaultMotionEffectsEnabled UI_APPEARANCE_SELECTOR; /// @name Progress /** * The progress of the progress indicator, from 0.0 to 1.0. Defaults to 0.0. */ @property (assign, nonatomic) float progress; /// @name ProgressObject /** * The NSProgress object feeding the progress information to the progress indicator. */ @property (strong, nonatomic, nullable) NSProgress *progressObject; /// @name Views /** * The view containing the labels and indicator (or customView). */ @property (strong, nonatomic, readonly) MBBackgroundView *bezelView; /** * View covering the entire HUD area, placed behind bezelView. */ @property (strong, nonatomic, readonly) MBBackgroundView *backgroundView; /** * The UIView (e.g., a UIImageView) to be shown when the HUD is in MBProgressHUDModeCustomView. * The view should implement intrinsicContentSize for proper sizing. For best results use approximately 37 by 37 pixels. */ @property (strong, nonatomic, nullable) UIView *customView; /** * A label that holds an optional short message to be displayed below the activity indicator. The HUD is automatically resized to fit * the entire text. */ @property (strong, nonatomic, readonly) UILabel *label; /** * A label that holds an optional details message displayed below the labelText message. The details text can span multiple lines. */ @property (strong, nonatomic, readonly) UILabel *detailsLabel; /** * A button that is placed below the labels. Visible only if a target / action is added. */ @property (strong, nonatomic, readonly) UIButton *button; @end @protocol MBProgressHUDDelegate @optional /** * Called after the HUD was fully hidden from the screen. */ - (void)hudWasHidden:(MBProgressHUD *)hud; @end /** * A progress view for showing definite progress by filling up a circle (pie chart). */ @interface MBRoundProgressView : UIView /** * Progress (0.0 to 1.0) */ @property (nonatomic, assign) float progress; /** * Indicator progress color. * Defaults to white [UIColor whiteColor]. */ @property (nonatomic, strong) UIColor *progressTintColor; /** * Indicator background (non-progress) color. * Only applicable on iOS versions older than iOS 7. * Defaults to translucent white (alpha 0.1). */ @property (nonatomic, strong) UIColor *backgroundTintColor; /* * Display mode - NO = round or YES = annular. Defaults to round. */ @property (nonatomic, assign, getter = isAnnular) BOOL annular; @end /** * A flat bar progress view. */ @interface MBBarProgressView : UIView /** * Progress (0.0 to 1.0) */ @property (nonatomic, assign) float progress; /** * Bar border line color. * Defaults to white [UIColor whiteColor]. */ @property (nonatomic, strong) UIColor *lineColor; /** * Bar background color. * Defaults to clear [UIColor clearColor]; */ @property (nonatomic, strong) UIColor *progressRemainingColor; /** * Bar progress color. * Defaults to white [UIColor whiteColor]. */ @property (nonatomic, strong) UIColor *progressColor; @end @interface MBBackgroundView : UIView /** * The background style. * Defaults to MBProgressHUDBackgroundStyleBlur on iOS 7 or later and MBProgressHUDBackgroundStyleSolidColor otherwise. * @note Due to iOS 7 not supporting UIVisualEffectView, the blur effect differs slightly between iOS 7 and later versions. */ @property (nonatomic) MBProgressHUDBackgroundStyle style; /** * The background color or the blur tint color. * @note Due to iOS 7 not supporting UIVisualEffectView, the blur effect differs slightly between iOS 7 and later versions. */ @property (nonatomic, strong) UIColor *color; @end @interface MBProgressHUD (Deprecated) + (NSArray *)allHUDsForView:(UIView *)view __attribute__((deprecated("Store references when using more than one HUD per view."))); + (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated __attribute__((deprecated("Store references when using more than one HUD per view."))); - (id)initWithWindow:(UIWindow *)window __attribute__((deprecated("Use initWithView: instead."))); - (void)show:(BOOL)animated __attribute__((deprecated("Use showAnimated: instead."))); - (void)hide:(BOOL)animated __attribute__((deprecated("Use hideAnimated: instead."))); - (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay __attribute__((deprecated("Use hideAnimated:afterDelay: instead."))); - (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated __attribute__((deprecated("Use GCD directly."))); - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block __attribute__((deprecated("Use GCD directly."))); - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block completionBlock:(nullable MBProgressHUDCompletionBlock)completion __attribute__((deprecated("Use GCD directly."))); - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue __attribute__((deprecated("Use GCD directly."))); - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue completionBlock:(nullable MBProgressHUDCompletionBlock)completion __attribute__((deprecated("Use GCD directly."))); @property (assign) BOOL taskInProgress __attribute__((deprecated("No longer needed."))); @property (nonatomic, copy) NSString *labelText __attribute__((deprecated("Use label.text instead."))); @property (nonatomic, strong) UIFont *labelFont __attribute__((deprecated("Use label.font instead."))); @property (nonatomic, strong) UIColor *labelColor __attribute__((deprecated("Use label.textColor instead."))); @property (nonatomic, copy) NSString *detailsLabelText __attribute__((deprecated("Use detailsLabel.text instead."))); @property (nonatomic, strong) UIFont *detailsLabelFont __attribute__((deprecated("Use detailsLabel.font instead."))); @property (nonatomic, strong) UIColor *detailsLabelColor __attribute__((deprecated("Use detailsLabel.textColor instead."))); @property (assign, nonatomic) CGFloat opacity __attribute__((deprecated("Customize bezelView properties instead."))); @property (strong, nonatomic) UIColor *color __attribute__((deprecated("Customize the bezelView color instead."))); @property (assign, nonatomic) CGFloat xOffset __attribute__((deprecated("Set offset.x instead."))); @property (assign, nonatomic) CGFloat yOffset __attribute__((deprecated("Set offset.y instead."))); @property (assign, nonatomic) CGFloat cornerRadius __attribute__((deprecated("Set bezelView.layer.cornerRadius instead."))); @property (assign, nonatomic) BOOL dimBackground __attribute__((deprecated("Customize HUD background properties instead."))); @property (strong, nonatomic) UIColor *activityIndicatorColor __attribute__((deprecated("Use UIAppearance to customize UIActivityIndicatorView. E.g.: [UIActivityIndicatorView appearanceWhenContainedIn:[MBProgressHUD class], nil].color = [UIColor redColor];"))); @property (atomic, assign, readonly) CGSize size __attribute__((deprecated("Get the bezelView.frame.size instead."))); @end NS_ASSUME_NONNULL_END ================================================ FILE: Pods/MBProgressHUD/MBProgressHUD.m ================================================ // // MBProgressHUD.m // Version 1.0.0 // Created by Matej Bukovinski on 2.4.09. // #import "MBProgressHUD.h" #import #ifndef kCFCoreFoundationVersionNumber_iOS_7_0 #define kCFCoreFoundationVersionNumber_iOS_7_0 847.20 #endif #ifndef kCFCoreFoundationVersionNumber_iOS_8_0 #define kCFCoreFoundationVersionNumber_iOS_8_0 1129.15 #endif #define MBMainThreadAssert() NSAssert([NSThread isMainThread], @"MBProgressHUD needs to be accessed on the main thread."); CGFloat const MBProgressMaxOffset = 1000000.f; static const CGFloat MBDefaultPadding = 4.f; static const CGFloat MBDefaultLabelFontSize = 16.f; static const CGFloat MBDefaultDetailsLabelFontSize = 12.f; @interface MBProgressHUD () { // Deprecated UIColor *_activityIndicatorColor; CGFloat _opacity; } @property (nonatomic, assign) BOOL useAnimation; @property (nonatomic, assign, getter=hasFinished) BOOL finished; @property (nonatomic, strong) UIView *indicator; @property (nonatomic, strong) NSDate *showStarted; @property (nonatomic, strong) NSArray *paddingConstraints; @property (nonatomic, strong) NSArray *bezelConstraints; @property (nonatomic, strong) UIView *topSpacer; @property (nonatomic, strong) UIView *bottomSpacer; @property (nonatomic, weak) NSTimer *graceTimer; @property (nonatomic, weak) NSTimer *minShowTimer; @property (nonatomic, weak) NSTimer *hideDelayTimer; @property (nonatomic, weak) CADisplayLink *progressObjectDisplayLink; // Deprecated @property (assign) BOOL taskInProgress; @end @interface MBProgressHUDRoundedButton : UIButton @end @implementation MBProgressHUD #pragma mark - Class methods + (instancetype)showHUDAddedTo:(UIView *)view animated:(BOOL)animated { MBProgressHUD *hud = [[self alloc] initWithView:view]; hud.removeFromSuperViewOnHide = YES; [view addSubview:hud]; [hud showAnimated:animated]; return hud; } + (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated { MBProgressHUD *hud = [self HUDForView:view]; if (hud != nil) { hud.removeFromSuperViewOnHide = YES; [hud hideAnimated:animated]; return YES; } return NO; } + (MBProgressHUD *)HUDForView:(UIView *)view { NSEnumerator *subviewsEnum = [view.subviews reverseObjectEnumerator]; for (UIView *subview in subviewsEnum) { if ([subview isKindOfClass:self]) { return (MBProgressHUD *)subview; } } return nil; } #pragma mark - Lifecycle - (void)commonInit { // Set default values for properties _animationType = MBProgressHUDAnimationFade; _mode = MBProgressHUDModeIndeterminate; _margin = 20.0f; _opacity = 1.f; _defaultMotionEffectsEnabled = YES; // Default color, depending on the current iOS version BOOL isLegacy = kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_7_0; _contentColor = isLegacy ? [UIColor whiteColor] : [UIColor colorWithWhite:0.f alpha:0.7f]; // Transparent background self.opaque = NO; self.backgroundColor = [UIColor clearColor]; // Make it invisible for now self.alpha = 0.0f; self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.layer.allowsGroupOpacity = NO; [self setupViews]; [self updateIndicators]; [self registerForNotifications]; } - (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { [self commonInit]; } return self; } - (instancetype)initWithCoder:(NSCoder *)aDecoder { if ((self = [super initWithCoder:aDecoder])) { [self commonInit]; } return self; } - (id)initWithView:(UIView *)view { NSAssert(view, @"View must not be nil."); return [self initWithFrame:view.bounds]; } - (void)dealloc { [self unregisterFromNotifications]; } #pragma mark - Show & hide - (void)showAnimated:(BOOL)animated { MBMainThreadAssert(); [self.minShowTimer invalidate]; self.useAnimation = animated; self.finished = NO; // If the grace time is set, postpone the HUD display if (self.graceTime > 0.0) { NSTimer *timer = [NSTimer timerWithTimeInterval:self.graceTime target:self selector:@selector(handleGraceTimer:) userInfo:nil repeats:NO]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; self.graceTimer = timer; } // ... otherwise show the HUD immediately else { [self showUsingAnimation:self.useAnimation]; } } - (void)hideAnimated:(BOOL)animated { MBMainThreadAssert(); [self.graceTimer invalidate]; self.useAnimation = animated; self.finished = YES; // If the minShow time is set, calculate how long the HUD was shown, // and postpone the hiding operation if necessary if (self.minShowTime > 0.0 && self.showStarted) { NSTimeInterval interv = [[NSDate date] timeIntervalSinceDate:self.showStarted]; if (interv < self.minShowTime) { NSTimer *timer = [NSTimer timerWithTimeInterval:(self.minShowTime - interv) target:self selector:@selector(handleMinShowTimer:) userInfo:nil repeats:NO]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; self.minShowTimer = timer; return; } } // ... otherwise hide the HUD immediately [self hideUsingAnimation:self.useAnimation]; } - (void)hideAnimated:(BOOL)animated afterDelay:(NSTimeInterval)delay { NSTimer *timer = [NSTimer timerWithTimeInterval:delay target:self selector:@selector(handleHideTimer:) userInfo:@(animated) repeats:NO]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; self.hideDelayTimer = timer; } #pragma mark - Timer callbacks - (void)handleGraceTimer:(NSTimer *)theTimer { // Show the HUD only if the task is still running if (!self.hasFinished) { [self showUsingAnimation:self.useAnimation]; } } - (void)handleMinShowTimer:(NSTimer *)theTimer { [self hideUsingAnimation:self.useAnimation]; } - (void)handleHideTimer:(NSTimer *)timer { [self hideAnimated:[timer.userInfo boolValue]]; } #pragma mark - View Hierrarchy - (void)didMoveToSuperview { [self updateForCurrentOrientationAnimated:NO]; } #pragma mark - Internal show & hide operations - (void)showUsingAnimation:(BOOL)animated { // Cancel any previous animations [self.bezelView.layer removeAllAnimations]; [self.backgroundView.layer removeAllAnimations]; // Cancel any scheduled hideDelayed: calls [self.hideDelayTimer invalidate]; self.showStarted = [NSDate date]; self.alpha = 1.f; // Needed in case we hide and re-show with the same NSProgress object attached. [self setNSProgressDisplayLinkEnabled:YES]; if (animated) { [self animateIn:YES withType:self.animationType completion:NULL]; } else { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" self.bezelView.alpha = self.opacity; #pragma clang diagnostic pop self.backgroundView.alpha = 1.f; } } - (void)hideUsingAnimation:(BOOL)animated { if (animated && self.showStarted) { self.showStarted = nil; [self animateIn:NO withType:self.animationType completion:^(BOOL finished) { [self done]; }]; } else { self.showStarted = nil; self.bezelView.alpha = 0.f; self.backgroundView.alpha = 1.f; [self done]; } } - (void)animateIn:(BOOL)animatingIn withType:(MBProgressHUDAnimation)type completion:(void(^)(BOOL finished))completion { // Automatically determine the correct zoom animation type if (type == MBProgressHUDAnimationZoom) { type = animatingIn ? MBProgressHUDAnimationZoomIn : MBProgressHUDAnimationZoomOut; } CGAffineTransform small = CGAffineTransformMakeScale(0.5f, 0.5f); CGAffineTransform large = CGAffineTransformMakeScale(1.5f, 1.5f); // Set starting state UIView *bezelView = self.bezelView; if (animatingIn && bezelView.alpha == 0.f && type == MBProgressHUDAnimationZoomIn) { bezelView.transform = small; } else if (animatingIn && bezelView.alpha == 0.f && type == MBProgressHUDAnimationZoomOut) { bezelView.transform = large; } // Perform animations dispatch_block_t animations = ^{ if (animatingIn) { bezelView.transform = CGAffineTransformIdentity; } else if (!animatingIn && type == MBProgressHUDAnimationZoomIn) { bezelView.transform = large; } else if (!animatingIn && type == MBProgressHUDAnimationZoomOut) { bezelView.transform = small; } #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" bezelView.alpha = animatingIn ? self.opacity : 0.f; #pragma clang diagnostic pop self.backgroundView.alpha = animatingIn ? 1.f : 0.f; }; // Spring animations are nicer, but only available on iOS 7+ #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 || TARGET_OS_TV if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_7_0) { [UIView animateWithDuration:0.3 delay:0. usingSpringWithDamping:1.f initialSpringVelocity:0.f options:UIViewAnimationOptionBeginFromCurrentState animations:animations completion:completion]; return; } #endif [UIView animateWithDuration:0.3 delay:0. options:UIViewAnimationOptionBeginFromCurrentState animations:animations completion:completion]; } - (void)done { // Cancel any scheduled hideDelayed: calls [self.hideDelayTimer invalidate]; [self setNSProgressDisplayLinkEnabled:NO]; if (self.hasFinished) { self.alpha = 0.0f; if (self.removeFromSuperViewOnHide) { [self removeFromSuperview]; } } MBProgressHUDCompletionBlock completionBlock = self.completionBlock; if (completionBlock) { completionBlock(); } id delegate = self.delegate; if ([delegate respondsToSelector:@selector(hudWasHidden:)]) { [delegate performSelector:@selector(hudWasHidden:) withObject:self]; } } #pragma mark - UI - (void)setupViews { UIColor *defaultColor = self.contentColor; MBBackgroundView *backgroundView = [[MBBackgroundView alloc] initWithFrame:self.bounds]; backgroundView.style = MBProgressHUDBackgroundStyleSolidColor; backgroundView.backgroundColor = [UIColor clearColor]; backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; backgroundView.alpha = 0.f; [self addSubview:backgroundView]; _backgroundView = backgroundView; MBBackgroundView *bezelView = [MBBackgroundView new]; bezelView.translatesAutoresizingMaskIntoConstraints = NO; bezelView.layer.cornerRadius = 5.f; bezelView.alpha = 0.f; [self addSubview:bezelView]; _bezelView = bezelView; [self updateBezelMotionEffects]; UILabel *label = [UILabel new]; label.adjustsFontSizeToFitWidth = NO; label.textAlignment = NSTextAlignmentCenter; label.textColor = defaultColor; label.font = [UIFont boldSystemFontOfSize:MBDefaultLabelFontSize]; label.opaque = NO; label.backgroundColor = [UIColor clearColor]; _label = label; UILabel *detailsLabel = [UILabel new]; detailsLabel.adjustsFontSizeToFitWidth = NO; detailsLabel.textAlignment = NSTextAlignmentCenter; detailsLabel.textColor = defaultColor; detailsLabel.numberOfLines = 0; detailsLabel.font = [UIFont boldSystemFontOfSize:MBDefaultDetailsLabelFontSize]; detailsLabel.opaque = NO; detailsLabel.backgroundColor = [UIColor clearColor]; _detailsLabel = detailsLabel; UIButton *button = [MBProgressHUDRoundedButton buttonWithType:UIButtonTypeCustom]; button.titleLabel.textAlignment = NSTextAlignmentCenter; button.titleLabel.font = [UIFont boldSystemFontOfSize:MBDefaultDetailsLabelFontSize]; [button setTitleColor:defaultColor forState:UIControlStateNormal]; _button = button; for (UIView *view in @[label, detailsLabel, button]) { view.translatesAutoresizingMaskIntoConstraints = NO; [view setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisHorizontal]; [view setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisVertical]; [bezelView addSubview:view]; } UIView *topSpacer = [UIView new]; topSpacer.translatesAutoresizingMaskIntoConstraints = NO; topSpacer.hidden = YES; [bezelView addSubview:topSpacer]; _topSpacer = topSpacer; UIView *bottomSpacer = [UIView new]; bottomSpacer.translatesAutoresizingMaskIntoConstraints = NO; bottomSpacer.hidden = YES; [bezelView addSubview:bottomSpacer]; _bottomSpacer = bottomSpacer; } - (void)updateIndicators { UIView *indicator = self.indicator; BOOL isActivityIndicator = [indicator isKindOfClass:[UIActivityIndicatorView class]]; BOOL isRoundIndicator = [indicator isKindOfClass:[MBRoundProgressView class]]; MBProgressHUDMode mode = self.mode; if (mode == MBProgressHUDModeIndeterminate) { if (!isActivityIndicator) { // Update to indeterminate indicator [indicator removeFromSuperview]; indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; [(UIActivityIndicatorView *)indicator startAnimating]; [self.bezelView addSubview:indicator]; } } else if (mode == MBProgressHUDModeDeterminateHorizontalBar) { // Update to bar determinate indicator [indicator removeFromSuperview]; indicator = [[MBBarProgressView alloc] init]; [self.bezelView addSubview:indicator]; } else if (mode == MBProgressHUDModeDeterminate || mode == MBProgressHUDModeAnnularDeterminate) { if (!isRoundIndicator) { // Update to determinante indicator [indicator removeFromSuperview]; indicator = [[MBRoundProgressView alloc] init]; [self.bezelView addSubview:indicator]; } if (mode == MBProgressHUDModeAnnularDeterminate) { [(MBRoundProgressView *)indicator setAnnular:YES]; } } else if (mode == MBProgressHUDModeCustomView && self.customView != indicator) { // Update custom view indicator [indicator removeFromSuperview]; indicator = self.customView; [self.bezelView addSubview:indicator]; } else if (mode == MBProgressHUDModeText) { [indicator removeFromSuperview]; indicator = nil; } indicator.translatesAutoresizingMaskIntoConstraints = NO; self.indicator = indicator; if ([indicator respondsToSelector:@selector(setProgress:)]) { [(id)indicator setValue:@(self.progress) forKey:@"progress"]; } [indicator setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisHorizontal]; [indicator setContentCompressionResistancePriority:998.f forAxis:UILayoutConstraintAxisVertical]; [self updateViewsForColor:self.contentColor]; [self setNeedsUpdateConstraints]; } - (void)updateViewsForColor:(UIColor *)color { if (!color) return; self.label.textColor = color; self.detailsLabel.textColor = color; [self.button setTitleColor:color forState:UIControlStateNormal]; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" if (self.activityIndicatorColor) { color = self.activityIndicatorColor; } #pragma clang diagnostic pop // UIAppearance settings are prioritized. If they are preset the set color is ignored. UIView *indicator = self.indicator; if ([indicator isKindOfClass:[UIActivityIndicatorView class]]) { UIActivityIndicatorView *appearance = nil; #if __IPHONE_OS_VERSION_MIN_REQUIRED < 90000 appearance = [UIActivityIndicatorView appearanceWhenContainedIn:[MBProgressHUD class], nil]; #else // For iOS 9+ appearance = [UIActivityIndicatorView appearanceWhenContainedInInstancesOfClasses:@[[MBProgressHUD class]]]; #endif if (appearance.color == nil) { ((UIActivityIndicatorView *)indicator).color = color; } } else if ([indicator isKindOfClass:[MBRoundProgressView class]]) { MBRoundProgressView *appearance = nil; #if __IPHONE_OS_VERSION_MIN_REQUIRED < 90000 appearance = [MBRoundProgressView appearanceWhenContainedIn:[MBProgressHUD class], nil]; #else appearance = [MBRoundProgressView appearanceWhenContainedInInstancesOfClasses:@[[MBProgressHUD class]]]; #endif if (appearance.progressTintColor == nil) { ((MBRoundProgressView *)indicator).progressTintColor = color; } if (appearance.backgroundTintColor == nil) { ((MBRoundProgressView *)indicator).backgroundTintColor = [color colorWithAlphaComponent:0.1]; } } else if ([indicator isKindOfClass:[MBBarProgressView class]]) { MBBarProgressView *appearance = nil; #if __IPHONE_OS_VERSION_MIN_REQUIRED < 90000 appearance = [MBBarProgressView appearanceWhenContainedIn:[MBProgressHUD class], nil]; #else appearance = [MBBarProgressView appearanceWhenContainedInInstancesOfClasses:@[[MBProgressHUD class]]]; #endif if (appearance.progressColor == nil) { ((MBBarProgressView *)indicator).progressColor = color; } if (appearance.lineColor == nil) { ((MBBarProgressView *)indicator).lineColor = color; } } else { #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 || TARGET_OS_TV if ([indicator respondsToSelector:@selector(setTintColor:)]) { [indicator setTintColor:color]; } #endif } } - (void)updateBezelMotionEffects { #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 || TARGET_OS_TV MBBackgroundView *bezelView = self.bezelView; if (![bezelView respondsToSelector:@selector(addMotionEffect:)]) return; if (self.defaultMotionEffectsEnabled) { CGFloat effectOffset = 10.f; UIInterpolatingMotionEffect *effectX = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; effectX.maximumRelativeValue = @(effectOffset); effectX.minimumRelativeValue = @(-effectOffset); UIInterpolatingMotionEffect *effectY = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis]; effectY.maximumRelativeValue = @(effectOffset); effectY.minimumRelativeValue = @(-effectOffset); UIMotionEffectGroup *group = [[UIMotionEffectGroup alloc] init]; group.motionEffects = @[effectX, effectY]; [bezelView addMotionEffect:group]; } else { NSArray *effects = [bezelView motionEffects]; for (UIMotionEffect *effect in effects) { [bezelView removeMotionEffect:effect]; } } #endif } #pragma mark - Layout - (void)updateConstraints { UIView *bezel = self.bezelView; UIView *topSpacer = self.topSpacer; UIView *bottomSpacer = self.bottomSpacer; CGFloat margin = self.margin; NSMutableArray *bezelConstraints = [NSMutableArray array]; NSDictionary *metrics = @{@"margin": @(margin)}; NSMutableArray *subviews = [NSMutableArray arrayWithObjects:self.topSpacer, self.label, self.detailsLabel, self.button, self.bottomSpacer, nil]; if (self.indicator) [subviews insertObject:self.indicator atIndex:1]; // Remove existing constraints [self removeConstraints:self.constraints]; [topSpacer removeConstraints:topSpacer.constraints]; [bottomSpacer removeConstraints:bottomSpacer.constraints]; if (self.bezelConstraints) { [bezel removeConstraints:self.bezelConstraints]; self.bezelConstraints = nil; } // Center bezel in container (self), applying the offset if set CGPoint offset = self.offset; NSMutableArray *centeringConstraints = [NSMutableArray array]; [centeringConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.f constant:offset.x]]; [centeringConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.f constant:offset.y]]; [self applyPriority:998.f toConstraints:centeringConstraints]; [self addConstraints:centeringConstraints]; // Ensure minimum side margin is kept NSMutableArray *sideConstraints = [NSMutableArray array]; [sideConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"|-(>=margin)-[bezel]-(>=margin)-|" options:0 metrics:metrics views:NSDictionaryOfVariableBindings(bezel)]]; [sideConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(>=margin)-[bezel]-(>=margin)-|" options:0 metrics:metrics views:NSDictionaryOfVariableBindings(bezel)]]; [self applyPriority:999.f toConstraints:sideConstraints]; [self addConstraints:sideConstraints]; // Minimum bezel size, if set CGSize minimumSize = self.minSize; if (!CGSizeEqualToSize(minimumSize, CGSizeZero)) { NSMutableArray *minSizeConstraints = [NSMutableArray array]; [minSizeConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:minimumSize.width]]; [minSizeConstraints addObject:[NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:minimumSize.height]]; [self applyPriority:997.f toConstraints:minSizeConstraints]; [bezelConstraints addObjectsFromArray:minSizeConstraints]; } // Square aspect ratio, if set if (self.square) { NSLayoutConstraint *square = [NSLayoutConstraint constraintWithItem:bezel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeWidth multiplier:1.f constant:0]; square.priority = 997.f; [bezelConstraints addObject:square]; } // Top and bottom spacing [topSpacer addConstraint:[NSLayoutConstraint constraintWithItem:topSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:margin]]; [bottomSpacer addConstraint:[NSLayoutConstraint constraintWithItem:bottomSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:margin]]; // Top and bottom spaces should be equal [bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:topSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:bottomSpacer attribute:NSLayoutAttributeHeight multiplier:1.f constant:0.f]]; // Layout subviews in bezel NSMutableArray *paddingConstraints = [NSMutableArray new]; [subviews enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL *stop) { // Center in bezel [bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeCenterX multiplier:1.f constant:0.f]]; // Ensure the minimum edge margin is kept [bezelConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"|-(>=margin)-[view]-(>=margin)-|" options:0 metrics:metrics views:NSDictionaryOfVariableBindings(view)]]; // Element spacing if (idx == 0) { // First, ensure spacing to bezel edge [bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeTop multiplier:1.f constant:0.f]]; } else if (idx == subviews.count - 1) { // Last, ensure spacing to bezel edge [bezelConstraints addObject:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:bezel attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f]]; } if (idx > 0) { // Has previous NSLayoutConstraint *padding = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:subviews[idx - 1] attribute:NSLayoutAttributeBottom multiplier:1.f constant:0.f]; [bezelConstraints addObject:padding]; [paddingConstraints addObject:padding]; } }]; [bezel addConstraints:bezelConstraints]; self.bezelConstraints = bezelConstraints; self.paddingConstraints = [paddingConstraints copy]; [self updatePaddingConstraints]; [super updateConstraints]; } - (void)layoutSubviews { // There is no need to update constraints if they are going to // be recreated in [super layoutSubviews] due to needsUpdateConstraints being set. // This also avoids an issue on iOS 8, where updatePaddingConstraints // would trigger a zombie object access. if (!self.needsUpdateConstraints) { [self updatePaddingConstraints]; } [super layoutSubviews]; } - (void)updatePaddingConstraints { // Set padding dynamically, depending on whether the view is visible or not __block BOOL hasVisibleAncestors = NO; [self.paddingConstraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *padding, NSUInteger idx, BOOL *stop) { UIView *firstView = (UIView *)padding.firstItem; UIView *secondView = (UIView *)padding.secondItem; BOOL firstVisible = !firstView.hidden && !CGSizeEqualToSize(firstView.intrinsicContentSize, CGSizeZero); BOOL secondVisible = !secondView.hidden && !CGSizeEqualToSize(secondView.intrinsicContentSize, CGSizeZero); // Set if both views are visible or if there's a visible view on top that doesn't have padding // added relative to the current view yet padding.constant = (firstVisible && (secondVisible || hasVisibleAncestors)) ? MBDefaultPadding : 0.f; hasVisibleAncestors |= secondVisible; }]; } - (void)applyPriority:(UILayoutPriority)priority toConstraints:(NSArray *)constraints { for (NSLayoutConstraint *constraint in constraints) { constraint.priority = priority; } } #pragma mark - Properties - (void)setMode:(MBProgressHUDMode)mode { if (mode != _mode) { _mode = mode; [self updateIndicators]; } } - (void)setCustomView:(UIView *)customView { if (customView != _customView) { _customView = customView; if (self.mode == MBProgressHUDModeCustomView) { [self updateIndicators]; } } } - (void)setOffset:(CGPoint)offset { if (!CGPointEqualToPoint(offset, _offset)) { _offset = offset; [self setNeedsUpdateConstraints]; } } - (void)setMargin:(CGFloat)margin { if (margin != _margin) { _margin = margin; [self setNeedsUpdateConstraints]; } } - (void)setMinSize:(CGSize)minSize { if (!CGSizeEqualToSize(minSize, _minSize)) { _minSize = minSize; [self setNeedsUpdateConstraints]; } } - (void)setSquare:(BOOL)square { if (square != _square) { _square = square; [self setNeedsUpdateConstraints]; } } - (void)setProgressObjectDisplayLink:(CADisplayLink *)progressObjectDisplayLink { if (progressObjectDisplayLink != _progressObjectDisplayLink) { [_progressObjectDisplayLink invalidate]; _progressObjectDisplayLink = progressObjectDisplayLink; [_progressObjectDisplayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; } } - (void)setProgressObject:(NSProgress *)progressObject { if (progressObject != _progressObject) { _progressObject = progressObject; [self setNSProgressDisplayLinkEnabled:YES]; } } - (void)setProgress:(float)progress { if (progress != _progress) { _progress = progress; UIView *indicator = self.indicator; if ([indicator respondsToSelector:@selector(setProgress:)]) { [(id)indicator setValue:@(self.progress) forKey:@"progress"]; } } } - (void)setContentColor:(UIColor *)contentColor { if (contentColor != _contentColor && ![contentColor isEqual:_contentColor]) { _contentColor = contentColor; [self updateViewsForColor:contentColor]; } } - (void)setDefaultMotionEffectsEnabled:(BOOL)defaultMotionEffectsEnabled { if (defaultMotionEffectsEnabled != _defaultMotionEffectsEnabled) { _defaultMotionEffectsEnabled = defaultMotionEffectsEnabled; [self updateBezelMotionEffects]; } } #pragma mark - NSProgress - (void)setNSProgressDisplayLinkEnabled:(BOOL)enabled { // We're using CADisplayLink, because NSProgress can change very quickly and observing it may starve the main thread, // so we're refreshing the progress only every frame draw if (enabled && self.progressObject) { // Only create if not already active. if (!self.progressObjectDisplayLink) { self.progressObjectDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateProgressFromProgressObject)]; } } else { self.progressObjectDisplayLink = nil; } } - (void)updateProgressFromProgressObject { self.progress = self.progressObject.fractionCompleted; } #pragma mark - Notifications - (void)registerForNotifications { #if !TARGET_OS_TV NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(statusBarOrientationDidChange:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; #endif } - (void)unregisterFromNotifications { #if !TARGET_OS_TV NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; #endif } #if !TARGET_OS_TV - (void)statusBarOrientationDidChange:(NSNotification *)notification { UIView *superview = self.superview; if (!superview) { return; } else { [self updateForCurrentOrientationAnimated:YES]; } } #endif - (void)updateForCurrentOrientationAnimated:(BOOL)animated { // Stay in sync with the superview in any case if (self.superview) { self.bounds = self.superview.bounds; } // Not needed on iOS 8+, compile out when the deployment target allows, // to avoid sharedApplication problems on extension targets #if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 // Only needed pre iOS 8 when added to a window BOOL iOS8OrLater = kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0; if (iOS8OrLater || ![self.superview isKindOfClass:[UIWindow class]]) return; // Make extension friendly. Will not get called on extensions (iOS 8+) due to the above check. // This just ensures we don't get a warning about extension-unsafe API. Class UIApplicationClass = NSClassFromString(@"UIApplication"); if (!UIApplicationClass || ![UIApplicationClass respondsToSelector:@selector(sharedApplication)]) return; UIApplication *application = [UIApplication performSelector:@selector(sharedApplication)]; UIInterfaceOrientation orientation = application.statusBarOrientation; CGFloat radians = 0; if (UIInterfaceOrientationIsLandscape(orientation)) { radians = orientation == UIInterfaceOrientationLandscapeLeft ? -(CGFloat)M_PI_2 : (CGFloat)M_PI_2; // Window coordinates differ! self.bounds = CGRectMake(0, 0, self.bounds.size.height, self.bounds.size.width); } else { radians = orientation == UIInterfaceOrientationPortraitUpsideDown ? (CGFloat)M_PI : 0.f; } if (animated) { [UIView animateWithDuration:0.3 animations:^{ self.transform = CGAffineTransformMakeRotation(radians); }]; } else { self.transform = CGAffineTransformMakeRotation(radians); } #endif } @end @implementation MBRoundProgressView #pragma mark - Lifecycle - (id)init { return [self initWithFrame:CGRectMake(0.f, 0.f, 37.f, 37.f)]; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor clearColor]; self.opaque = NO; _progress = 0.f; _annular = NO; _progressTintColor = [[UIColor alloc] initWithWhite:1.f alpha:1.f]; _backgroundTintColor = [[UIColor alloc] initWithWhite:1.f alpha:.1f]; } return self; } #pragma mark - Layout - (CGSize)intrinsicContentSize { return CGSizeMake(37.f, 37.f); } #pragma mark - Properties - (void)setProgress:(float)progress { if (progress != _progress) { _progress = progress; [self setNeedsDisplay]; } } - (void)setProgressTintColor:(UIColor *)progressTintColor { NSAssert(progressTintColor, @"The color should not be nil."); if (progressTintColor != _progressTintColor && ![progressTintColor isEqual:_progressTintColor]) { _progressTintColor = progressTintColor; [self setNeedsDisplay]; } } - (void)setBackgroundTintColor:(UIColor *)backgroundTintColor { NSAssert(backgroundTintColor, @"The color should not be nil."); if (backgroundTintColor != _backgroundTintColor && ![backgroundTintColor isEqual:_backgroundTintColor]) { _backgroundTintColor = backgroundTintColor; [self setNeedsDisplay]; } } #pragma mark - Drawing - (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); BOOL isPreiOS7 = kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_7_0; if (_annular) { // Draw background CGFloat lineWidth = isPreiOS7 ? 5.f : 2.f; UIBezierPath *processBackgroundPath = [UIBezierPath bezierPath]; processBackgroundPath.lineWidth = lineWidth; processBackgroundPath.lineCapStyle = kCGLineCapButt; CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); CGFloat radius = (self.bounds.size.width - lineWidth)/2; CGFloat startAngle = - ((float)M_PI / 2); // 90 degrees CGFloat endAngle = (2 * (float)M_PI) + startAngle; [processBackgroundPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES]; [_backgroundTintColor set]; [processBackgroundPath stroke]; // Draw progress UIBezierPath *processPath = [UIBezierPath bezierPath]; processPath.lineCapStyle = isPreiOS7 ? kCGLineCapRound : kCGLineCapSquare; processPath.lineWidth = lineWidth; endAngle = (self.progress * 2 * (float)M_PI) + startAngle; [processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES]; [_progressTintColor set]; [processPath stroke]; } else { // Draw background CGFloat lineWidth = 2.f; CGRect allRect = self.bounds; CGRect circleRect = CGRectInset(allRect, lineWidth/2.f, lineWidth/2.f); CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); [_progressTintColor setStroke]; [_backgroundTintColor setFill]; CGContextSetLineWidth(context, lineWidth); if (isPreiOS7) { CGContextFillEllipseInRect(context, circleRect); } CGContextStrokeEllipseInRect(context, circleRect); // 90 degrees CGFloat startAngle = - ((float)M_PI / 2.f); // Draw progress if (isPreiOS7) { CGFloat radius = (CGRectGetWidth(self.bounds) / 2.f) - lineWidth; CGFloat endAngle = (self.progress * 2.f * (float)M_PI) + startAngle; [_progressTintColor setFill]; CGContextMoveToPoint(context, center.x, center.y); CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, 0); CGContextClosePath(context); CGContextFillPath(context); } else { UIBezierPath *processPath = [UIBezierPath bezierPath]; processPath.lineCapStyle = kCGLineCapButt; processPath.lineWidth = lineWidth * 2.f; CGFloat radius = (CGRectGetWidth(self.bounds) / 2.f) - (processPath.lineWidth / 2.f); CGFloat endAngle = (self.progress * 2.f * (float)M_PI) + startAngle; [processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES]; // Ensure that we don't get color overlaping when _progressTintColor alpha < 1.f. CGContextSetBlendMode(context, kCGBlendModeCopy); [_progressTintColor set]; [processPath stroke]; } } } @end @implementation MBBarProgressView #pragma mark - Lifecycle - (id)init { return [self initWithFrame:CGRectMake(.0f, .0f, 120.0f, 20.0f)]; } - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { _progress = 0.f; _lineColor = [UIColor whiteColor]; _progressColor = [UIColor whiteColor]; _progressRemainingColor = [UIColor clearColor]; self.backgroundColor = [UIColor clearColor]; self.opaque = NO; } return self; } #pragma mark - Layout - (CGSize)intrinsicContentSize { BOOL isPreiOS7 = kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_7_0; return CGSizeMake(120.f, isPreiOS7 ? 20.f : 10.f); } #pragma mark - Properties - (void)setProgress:(float)progress { if (progress != _progress) { _progress = progress; [self setNeedsDisplay]; } } - (void)setProgressColor:(UIColor *)progressColor { NSAssert(progressColor, @"The color should not be nil."); if (progressColor != _progressColor && ![progressColor isEqual:_progressColor]) { _progressColor = progressColor; [self setNeedsDisplay]; } } - (void)setProgressRemainingColor:(UIColor *)progressRemainingColor { NSAssert(progressRemainingColor, @"The color should not be nil."); if (progressRemainingColor != _progressRemainingColor && ![progressRemainingColor isEqual:_progressRemainingColor]) { _progressRemainingColor = progressRemainingColor; [self setNeedsDisplay]; } } #pragma mark - Drawing - (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetLineWidth(context, 2); CGContextSetStrokeColorWithColor(context,[_lineColor CGColor]); CGContextSetFillColorWithColor(context, [_progressRemainingColor CGColor]); // Draw background CGFloat radius = (rect.size.height / 2) - 2; CGContextMoveToPoint(context, 2, rect.size.height/2); CGContextAddArcToPoint(context, 2, 2, radius + 2, 2, radius); CGContextAddLineToPoint(context, rect.size.width - radius - 2, 2); CGContextAddArcToPoint(context, rect.size.width - 2, 2, rect.size.width - 2, rect.size.height / 2, radius); CGContextAddArcToPoint(context, rect.size.width - 2, rect.size.height - 2, rect.size.width - radius - 2, rect.size.height - 2, radius); CGContextAddLineToPoint(context, radius + 2, rect.size.height - 2); CGContextAddArcToPoint(context, 2, rect.size.height - 2, 2, rect.size.height/2, radius); CGContextFillPath(context); // Draw border CGContextMoveToPoint(context, 2, rect.size.height/2); CGContextAddArcToPoint(context, 2, 2, radius + 2, 2, radius); CGContextAddLineToPoint(context, rect.size.width - radius - 2, 2); CGContextAddArcToPoint(context, rect.size.width - 2, 2, rect.size.width - 2, rect.size.height / 2, radius); CGContextAddArcToPoint(context, rect.size.width - 2, rect.size.height - 2, rect.size.width - radius - 2, rect.size.height - 2, radius); CGContextAddLineToPoint(context, radius + 2, rect.size.height - 2); CGContextAddArcToPoint(context, 2, rect.size.height - 2, 2, rect.size.height/2, radius); CGContextStrokePath(context); CGContextSetFillColorWithColor(context, [_progressColor CGColor]); radius = radius - 2; CGFloat amount = self.progress * rect.size.width; // Progress in the middle area if (amount >= radius + 4 && amount <= (rect.size.width - radius - 4)) { CGContextMoveToPoint(context, 4, rect.size.height/2); CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius); CGContextAddLineToPoint(context, amount, 4); CGContextAddLineToPoint(context, amount, radius + 4); CGContextMoveToPoint(context, 4, rect.size.height/2); CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius); CGContextAddLineToPoint(context, amount, rect.size.height - 4); CGContextAddLineToPoint(context, amount, radius + 4); CGContextFillPath(context); } // Progress in the right arc else if (amount > radius + 4) { CGFloat x = amount - (rect.size.width - radius - 4); CGContextMoveToPoint(context, 4, rect.size.height/2); CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius); CGContextAddLineToPoint(context, rect.size.width - radius - 4, 4); CGFloat angle = -acos(x/radius); if (isnan(angle)) angle = 0; CGContextAddArc(context, rect.size.width - radius - 4, rect.size.height/2, radius, M_PI, angle, 0); CGContextAddLineToPoint(context, amount, rect.size.height/2); CGContextMoveToPoint(context, 4, rect.size.height/2); CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius); CGContextAddLineToPoint(context, rect.size.width - radius - 4, rect.size.height - 4); angle = acos(x/radius); if (isnan(angle)) angle = 0; CGContextAddArc(context, rect.size.width - radius - 4, rect.size.height/2, radius, -M_PI, angle, 1); CGContextAddLineToPoint(context, amount, rect.size.height/2); CGContextFillPath(context); } // Progress is in the left arc else if (amount < radius + 4 && amount > 0) { CGContextMoveToPoint(context, 4, rect.size.height/2); CGContextAddArcToPoint(context, 4, 4, radius + 4, 4, radius); CGContextAddLineToPoint(context, radius + 4, rect.size.height/2); CGContextMoveToPoint(context, 4, rect.size.height/2); CGContextAddArcToPoint(context, 4, rect.size.height - 4, radius + 4, rect.size.height - 4, radius); CGContextAddLineToPoint(context, radius + 4, rect.size.height/2); CGContextFillPath(context); } } @end @interface MBBackgroundView () #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 || TARGET_OS_TV @property UIVisualEffectView *effectView; #endif #if !TARGET_OS_TV @property UIToolbar *toolbar; #endif @end @implementation MBBackgroundView #pragma mark - Lifecycle - (instancetype)initWithFrame:(CGRect)frame { if ((self = [super initWithFrame:frame])) { if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_7_0) { _style = MBProgressHUDBackgroundStyleBlur; if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) { _color = [UIColor colorWithWhite:0.8f alpha:0.6f]; } else { _color = [UIColor colorWithWhite:0.95f alpha:0.6f]; } } else { _style = MBProgressHUDBackgroundStyleSolidColor; _color = [[UIColor blackColor] colorWithAlphaComponent:0.8]; } self.clipsToBounds = YES; [self updateForBackgroundStyle]; } return self; } #pragma mark - Layout - (CGSize)intrinsicContentSize { // Smallest size possible. Content pushes against this. return CGSizeZero; } #pragma mark - Appearance - (void)setStyle:(MBProgressHUDBackgroundStyle)style { if (style == MBProgressHUDBackgroundStyleBlur && kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_7_0) { style = MBProgressHUDBackgroundStyleSolidColor; } if (_style != style) { _style = style; [self updateForBackgroundStyle]; } } - (void)setColor:(UIColor *)color { NSAssert(color, @"The color should not be nil."); if (color != _color && ![color isEqual:_color]) { _color = color; [self updateViewsForColor:color]; } } /////////////////////////////////////////////////////////////////////////////////////////// #pragma mark - Views - (void)updateForBackgroundStyle { MBProgressHUDBackgroundStyle style = self.style; if (style == MBProgressHUDBackgroundStyleBlur) { #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 || TARGET_OS_TV if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) { UIBlurEffect *effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]; UIVisualEffectView *effectView = [[UIVisualEffectView alloc] initWithEffect:effect]; [self addSubview:effectView]; effectView.frame = self.bounds; effectView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; self.backgroundColor = self.color; self.layer.allowsGroupOpacity = NO; self.effectView = effectView; } else { #endif #if !TARGET_OS_TV UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectInset(self.bounds, -100.f, -100.f)]; toolbar.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; toolbar.barTintColor = self.color; toolbar.translucent = YES; [self addSubview:toolbar]; self.toolbar = toolbar; #endif #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 || TARGET_OS_TV } #endif } else { #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 || TARGET_OS_TV if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) { [self.effectView removeFromSuperview]; self.effectView = nil; } else { #endif #if !TARGET_OS_TV [self.toolbar removeFromSuperview]; self.toolbar = nil; #endif #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 || TARGET_OS_TV } #endif self.backgroundColor = self.color; } } - (void)updateViewsForColor:(UIColor *)color { if (self.style == MBProgressHUDBackgroundStyleBlur) { if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) { self.backgroundColor = self.color; } else { #if !TARGET_OS_TV self.toolbar.barTintColor = color; #endif } } else { self.backgroundColor = self.color; } } @end @implementation MBProgressHUD (Deprecated) #pragma mark - Class + (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated { NSArray *huds = [MBProgressHUD allHUDsForView:view]; for (MBProgressHUD *hud in huds) { hud.removeFromSuperViewOnHide = YES; [hud hideAnimated:animated]; } return [huds count]; } + (NSArray *)allHUDsForView:(UIView *)view { NSMutableArray *huds = [NSMutableArray array]; NSArray *subviews = view.subviews; for (UIView *aView in subviews) { if ([aView isKindOfClass:self]) { [huds addObject:aView]; } } return [NSArray arrayWithArray:huds]; } #pragma mark - Lifecycle - (id)initWithWindow:(UIWindow *)window { return [self initWithView:window]; } #pragma mark - Show & hide - (void)show:(BOOL)animated { [self showAnimated:animated]; } - (void)hide:(BOOL)animated { [self hideAnimated:animated]; } - (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay { [self hideAnimated:animated afterDelay:delay]; } #pragma mark - Threading - (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated { [self showAnimated:animated whileExecutingBlock:^{ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" // Start executing the requested task [target performSelector:method withObject:object]; #pragma clang diagnostic pop }]; } - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); [self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:NULL]; } - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block completionBlock:(void (^)())completion { dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); [self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:completion]; } - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue { [self showAnimated:animated whileExecutingBlock:block onQueue:queue completionBlock:NULL]; } - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue completionBlock:(nullable MBProgressHUDCompletionBlock)completion { self.taskInProgress = YES; self.completionBlock = completion; dispatch_async(queue, ^(void) { block(); dispatch_async(dispatch_get_main_queue(), ^(void) { [self cleanUp]; }); }); [self showAnimated:animated]; } - (void)cleanUp { self.taskInProgress = NO; [self hideAnimated:self.useAnimation]; } #pragma mark - Labels - (NSString *)labelText { return self.label.text; } - (void)setLabelText:(NSString *)labelText { MBMainThreadAssert(); self.label.text = labelText; } - (UIFont *)labelFont { return self.label.font; } - (void)setLabelFont:(UIFont *)labelFont { MBMainThreadAssert(); self.label.font = labelFont; } - (UIColor *)labelColor { return self.label.textColor; } - (void)setLabelColor:(UIColor *)labelColor { MBMainThreadAssert(); self.label.textColor = labelColor; } - (NSString *)detailsLabelText { return self.detailsLabel.text; } - (void)setDetailsLabelText:(NSString *)detailsLabelText { MBMainThreadAssert(); self.detailsLabel.text = detailsLabelText; } - (UIFont *)detailsLabelFont { return self.detailsLabel.font; } - (void)setDetailsLabelFont:(UIFont *)detailsLabelFont { MBMainThreadAssert(); self.detailsLabel.font = detailsLabelFont; } - (UIColor *)detailsLabelColor { return self.detailsLabel.textColor; } - (void)setDetailsLabelColor:(UIColor *)detailsLabelColor { MBMainThreadAssert(); self.detailsLabel.textColor = detailsLabelColor; } - (CGFloat)opacity { return _opacity; } - (void)setOpacity:(CGFloat)opacity { MBMainThreadAssert(); _opacity = opacity; } - (UIColor *)color { return self.bezelView.color; } - (void)setColor:(UIColor *)color { MBMainThreadAssert(); self.bezelView.color = color; } - (CGFloat)yOffset { return self.offset.y; } - (void)setYOffset:(CGFloat)yOffset { MBMainThreadAssert(); self.offset = CGPointMake(self.offset.x, yOffset); } - (CGFloat)xOffset { return self.offset.x; } - (void)setXOffset:(CGFloat)xOffset { MBMainThreadAssert(); self.offset = CGPointMake(xOffset, self.offset.y); } - (CGFloat)cornerRadius { return self.bezelView.layer.cornerRadius; } - (void)setCornerRadius:(CGFloat)cornerRadius { MBMainThreadAssert(); self.bezelView.layer.cornerRadius = cornerRadius; } - (BOOL)dimBackground { MBBackgroundView *backgroundView = self.backgroundView; UIColor *dimmedColor = [UIColor colorWithWhite:0.f alpha:.2f]; return backgroundView.style == MBProgressHUDBackgroundStyleSolidColor && [backgroundView.color isEqual:dimmedColor]; } - (void)setDimBackground:(BOOL)dimBackground { MBMainThreadAssert(); self.backgroundView.style = MBProgressHUDBackgroundStyleSolidColor; self.backgroundView.color = dimBackground ? [UIColor colorWithWhite:0.f alpha:.2f] : [UIColor clearColor]; } - (CGSize)size { return self.bezelView.frame.size; } - (UIColor *)activityIndicatorColor { return _activityIndicatorColor; } - (void)setActivityIndicatorColor:(UIColor *)activityIndicatorColor { if (activityIndicatorColor != _activityIndicatorColor) { _activityIndicatorColor = activityIndicatorColor; UIActivityIndicatorView *indicator = (UIActivityIndicatorView *)self.indicator; if ([indicator isKindOfClass:[UIActivityIndicatorView class]]) { [indicator setColor:activityIndicatorColor]; } } } @end @implementation MBProgressHUDRoundedButton #pragma mark - Lifecycle - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { CALayer *layer = self.layer; layer.borderWidth = 1.f; } return self; } #pragma mark - Layout - (void)layoutSubviews { [super layoutSubviews]; // Fully rounded corners CGFloat height = CGRectGetHeight(self.bounds); self.layer.cornerRadius = ceil(height / 2.f); } - (CGSize)intrinsicContentSize { // Only show if we have associated control events if (self.allControlEvents == 0) return CGSizeZero; CGSize size = [super intrinsicContentSize]; // Add some side padding size.width += 20.f; return size; } #pragma mark - Color - (void)setTitleColor:(UIColor *)color forState:(UIControlState)state { [super setTitleColor:color forState:state]; // Update related colors [self setHighlighted:self.highlighted]; self.layer.borderColor = color.CGColor; } - (void)setHighlighted:(BOOL)highlighted { [super setHighlighted:highlighted]; UIColor *baseColor = [self titleColorForState:UIControlStateSelected]; self.backgroundColor = highlighted ? [baseColor colorWithAlphaComponent:0.1f] : [UIColor clearColor]; } @end ================================================ FILE: Pods/MBProgressHUD/README.mdown ================================================ # MBProgressHUD [![Build Status](https://travis-ci.org/matej/MBProgressHUD.svg?branch=master)](https://travis-ci.org/matej/MBProgressHUD) [![codecov.io](https://codecov.io/github/matej/MBProgressHUD/coverage.svg?branch=master)](https://codecov.io/github/matej/MBProgressHUD?branch=master) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) [![CocoaPods compatible](https://img.shields.io/cocoapods/v/MBProgressHUD.svg?style=flat)](https://cocoapods.org/pods/MBProgressHUD) [![License: MIT](https://img.shields.io/cocoapods/l/MBProgressHUD.svg?style=flat)](http://opensource.org/licenses/MIT) `MBProgressHUD` is an iOS drop-in class that displays a translucent HUD with an indicator and/or labels while work is being done in a background thread. The HUD is meant as a replacement for the undocumented, private `UIKit` `UIProgressHUD` with some additional features. [![](http://dl.dropbox.com/u/378729/MBProgressHUD/v1/1-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/v1/1.png) [![](http://dl.dropbox.com/u/378729/MBProgressHUD/v1/2-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/v1/2.png) [![](http://dl.dropbox.com/u/378729/MBProgressHUD/v1/3-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/v1/3.png) [![](http://dl.dropbox.com/u/378729/MBProgressHUD/v1/4-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/v1/4.png) [![](http://dl.dropbox.com/u/378729/MBProgressHUD/v1/5-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/v1/5.png) [![](http://dl.dropbox.com/u/378729/MBProgressHUD/v1/6-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/v1/6.png) [![](http://dl.dropbox.com/u/378729/MBProgressHUD/v1/7-thumb.png)](http://dl.dropbox.com/u/378729/MBProgressHUD/v1/7.png) **NOTE:** The class has recently undegone a major rewrite. The old version is available in the [legacy](https://github.com/jdg/MBProgressHUD/tree/legacy) branch, should you need it. ## Requirements `MBProgressHUD` works on iOS 6+ and requires ARC to build. It depends on the following Apple frameworks, which should already be included with most Xcode templates: * Foundation.framework * UIKit.framework * CoreGraphics.framework You will need the latest developer tools in order to build `MBProgressHUD`. Old Xcode versions might work, but compatibility will not be explicitly maintained. ## Adding MBProgressHUD to your project ### CocoaPods [CocoaPods](http://cocoapods.org) is the recommended way to add MBProgressHUD to your project. 1. Add a pod entry for MBProgressHUD to your Podfile `pod 'MBProgressHUD', '~> 1.0.0'` 2. Install the pod(s) by running `pod install`. 3. Include MBProgressHUD wherever you need it with `#import "MBProgressHUD.h"`. ### Carthage 1. Add MBProgressHUD to your Cartfile. e.g., `github "jdg/MBProgressHUD" ~> 1.0.0` 2. Run `carthage update` 3. Follow the rest of the [standard Carthage installation instructions](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) to add MBProgressHUD to your project. ### Source files Alternatively you can directly add the `MBProgressHUD.h` and `MBProgressHUD.m` source files to your project. 1. Download the [latest code version](https://github.com/matej/MBProgressHUD/archive/master.zip) or add the repository as a git submodule to your git-tracked project. 2. Open your project in Xcode, then drag and drop `MBProgressHUD.h` and `MBProgressHUD.m` onto your project (use the "Product Navigator view"). Make sure to select Copy items when asked if you extracted the code archive outside of your project. 3. Include MBProgressHUD wherever you need it with `#import "MBProgressHUD.h"`. ### Static library You can also add MBProgressHUD as a static library to your project or workspace. 1. Download the [latest code version](https://github.com/matej/MBProgressHUD/downloads) or add the repository as a git submodule to your git-tracked project. 2. Open your project in Xcode, then drag and drop `MBProgressHUD.xcodeproj` onto your project or workspace (use the "Product Navigator view"). 3. Select your target and go to the Build phases tab. In the Link Binary With Libraries section select the add button. On the sheet find and add `libMBProgressHUD.a`. You might also need to add `MBProgressHUD` to the Target Dependencies list. 4. Include MBProgressHUD wherever you need it with `#import `. ## Usage The main guideline you need to follow when dealing with MBProgressHUD while running long-running tasks is keeping the main thread work-free, so the UI can be updated promptly. The recommended way of using MBProgressHUD is therefore to set it up on the main thread and then spinning the task, that you want to perform, off onto a new thread. ```objective-c [MBProgressHUD showHUDAddedTo:self.view animated:YES]; dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ // Do something... dispatch_async(dispatch_get_main_queue(), ^{ [MBProgressHUD hideHUDForView:self.view animated:YES]; }); }); ``` You can add the HUD on any view or window. It is however a good idea to avoid adding the HUD to certain `UIKit` views with complex view hierarchies - like `UITableView` or `UICollectionView`. Those can mutate their subviews in unexpected ways and thereby break HUD display. If you need to configure the HUD you can do this by using the MBProgressHUD reference that showHUDAddedTo:animated: returns. ```objective-c MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; hud.mode = MBProgressHUDModeAnnularDeterminate; hud.labelText = @"Loading"; [self doSomethingInBackgroundWithProgressCallback:^(float progress) { hud.progress = progress; } completionCallback:^{ [hud hide:YES]; }]; ``` You can also use a `NSProgress` object and MBProgressHUD will update itself when there is progress reported through that object. ```objective-c MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; hud.mode = MBProgressHUDModeAnnularDeterminate; hud.labelText = @"Loading"; NSProgress *progress = [self doSomethingInBackgroundCompletion:^{ [hud hide:YES]; }]; hud.progressObject = progress; ``` UI updates should always be done on the main thread. Some MBProgressHUD setters are however considered "thread safe" and can be called from background threads. Those also include `setMode:`, `setCustomView:`, `setLabelText:`, `setLabelFont:`, `setDetailsLabelText:`, `setDetailsLabelFont:` and `setProgress:`. If you need to run your long-running task in the main thread, you should perform it with a slight delay, so UIKit will have enough time to update the UI (i.e., draw the HUD) before you block the main thread with your task. ```objective-c [MBProgressHUD showHUDAddedTo:self.view animated:YES]; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ // Do something... [MBProgressHUD hideHUDForView:self.view animated:YES]; }); ``` You should be aware that any HUD updates issued inside the above block won't be displayed until the block completes. For more examples, including how to use MBProgressHUD with asynchronous operations such as NSURLConnection, take a look at the bundled demo project. Extensive API documentation is provided in the header file (MBProgressHUD.h). ## License This code is distributed under the terms and conditions of the [MIT license](LICENSE). ## Change-log A brief summary of each MBProgressHUD release can be found in the [CHANGELOG](CHANGELOG.mdown). ================================================ FILE: Pods/Pods.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 007E3BF0BF2A2854408ACF7433E709E8 /* FBSDKSendButton.h in Headers */ = {isa = PBXBuildFile; fileRef = F54A2AA54749108AF1EE5F405A33322F /* FBSDKSendButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 020A65A3E154C0B31D1B0351BD8FFEDA /* FBSDKShareOpenGraphAction.m in Sources */ = {isa = PBXBuildFile; fileRef = 15316CB5F2E0A74B37A4B65C34168EAD /* FBSDKShareOpenGraphAction.m */; }; 0276287E0E8F78A9E56AB05E8DCD3DE1 /* FBSDKAppGroupAddDialog.h in Headers */ = {isa = PBXBuildFile; fileRef = 7535232E21B0FD5DCB966BA692B0A851 /* FBSDKAppGroupAddDialog.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0339052284A47A46E7821D754BB990DF /* FBSDKLoginManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 17F4407284C3041C1FB4B7B9946068A6 /* FBSDKLoginManager.m */; }; 04264C5208F69D58A5F11669B4CE4BD7 /* FBSDKTriStateBOOL.h in Headers */ = {isa = PBXBuildFile; fileRef = 394DEC0187D9C4DD3025FCBDEE64E147 /* FBSDKTriStateBOOL.h */; settings = {ATTRIBUTES = (Project, ); }; }; 05FB221AC2755579479BBCD40E251230 /* FBSDKLikeBoxBorderView.h in Headers */ = {isa = PBXBuildFile; fileRef = 9EB37E92D58767FCF62D088DC62ED5C2 /* FBSDKLikeBoxBorderView.h */; settings = {ATTRIBUTES = (Project, ); }; }; 06A4A4AF7AFC580A244A78B2C7999E94 /* FBSDKLikeActionController.h in Headers */ = {isa = PBXBuildFile; fileRef = 296C259F6F86ABD6D4D15162E262E0B1 /* FBSDKLikeActionController.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0733D08910977EC97E27B2375ED23E7C /* FBSDKDynamicFrameworkLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 46CA2814DBE4937069A37145DEA3F89F /* FBSDKDynamicFrameworkLoader.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0833AF4DC458C2A0345733BC9231B289 /* FBSDKIcon.m in Sources */ = {isa = PBXBuildFile; fileRef = ACB414CD0EAEE64256401BCD8A426020 /* FBSDKIcon.m */; }; 08DAC2F4AEE5BBA86F713F32A79E24AF /* FBSDKLoginUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = CA407D693530EF67FBB1EA3D2C81B497 /* FBSDKLoginUtility.m */; }; 09377F0215E2E436F04644D375173567 /* FBSDKCoreKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = B1699EFE891F2CEBC1D7AFE5B9D55701 /* FBSDKCoreKit-dummy.m */; }; 097FBD368E967EB3E4B855ADE19422C7 /* FBSDKServerConfiguration+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 56B016FB0CBDC0DB06D82BAA62305478 /* FBSDKServerConfiguration+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0A1A1B87F24903B40A84CA388C14F889 /* FBSDKBridgeAPIProtocolWebV2.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DF483014F5F35035670878A8FEC5C0D /* FBSDKBridgeAPIProtocolWebV2.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0AAEA700978D1406CFC13FFEF8E72BB4 /* FBSDKMessengerIcon.h in Headers */ = {isa = PBXBuildFile; fileRef = 61D578A4D092674413B4F810B65617E8 /* FBSDKMessengerIcon.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0B8052279201BD94A1829862BFC57B2B /* FBSDKShareOpenGraphValueContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = E6715DAD6D0684A20A87622BF8E0A551 /* FBSDKShareOpenGraphValueContainer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0C11E95A97B2D6541603C23A850EC4EF /* FBSDKShareButton.m in Sources */ = {isa = PBXBuildFile; fileRef = B0C5CC746ED5CBE775F12C5660AD1541 /* FBSDKShareButton.m */; }; 0D9C01E9CFFF23D0BD3C3B9A73D48C16 /* FBSDKMessengerIcon.m in Sources */ = {isa = PBXBuildFile; fileRef = 7CD63C5B47C7DD78B701AFE52A61B10C /* FBSDKMessengerIcon.m */; }; 0EBC761E8EDAA546EC6F17F60255D437 /* Pods-PotterPics-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = EF5C3346B26F744DBD314D4284287A88 /* Pods-PotterPics-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0EEF80A8836783073DB22A229E6DA59E /* FBSDKLikeActionControllerCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 23A27F6D575E25C312B65E8A9904B718 /* FBSDKLikeActionControllerCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0FB1CE9AB76B77BEFC2F5DD025EB6032 /* FBSDKLoginUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A39E686532C21963B8155F97482BCF6 /* FBSDKLoginUtility.h */; settings = {ATTRIBUTES = (Project, ); }; }; 1011B357BB0B3BC60DA75A5BAC283B5E /* FBSDKMath.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E573958B4A3ED69E35F873DEF94A025 /* FBSDKMath.m */; }; 1065981079E04A302D057FF480D88144 /* FBSDKLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 57412D699CFA7F312241E647FC9D19A4 /* FBSDKLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; 1110C890C028A60D617B28184DFF9968 /* FBSDKLikeBoxBorderView.m in Sources */ = {isa = PBXBuildFile; fileRef = F4F13DEEC78A2EA3065FF203E4660B55 /* FBSDKLikeBoxBorderView.m */; }; 11D89502D964832FC217751339F7E7EF /* FBSDKShareOpenGraphValueContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = B47A1F95345E84BC07B8AC72EBA943D5 /* FBSDKShareOpenGraphValueContainer.m */; }; 11DEDD08EE2FBF22E26F8E4277B8E7CF /* FBSDKServerConfigurationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 60140D24CE91D843865E0ACF7ABC0810 /* FBSDKServerConfigurationManager.m */; }; 1200A152A08388893BFA023980C2CF48 /* FBSDKLoginManagerLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C085C3A1C9636BF6C842DE91E406454 /* FBSDKLoginManagerLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; 121DBDB1187D26610D1AE715C72731B5 /* FBSDKInternalUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B6976E4ED6C9EFA96E5199EC7E1C667 /* FBSDKInternalUtility.m */; }; 13608DABB5C9B433953DD7E64FDD352D /* FBSDKMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EAD10D545ACA391D87A813DC8B29B9B /* FBSDKMath.h */; settings = {ATTRIBUTES = (Project, ); }; }; 1360C072C79DBA6E4B292B7A05B73ACB /* FBSDKAppGroupJoinDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = 60EEE6453B96E7C95C343AC97A90FC50 /* FBSDKAppGroupJoinDialog.m */; }; 139FE4B378AF69FD65DF73C921B131AD /* BFCancellationToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EB7BD93203502485FD103872BC356F3 /* BFCancellationToken.m */; }; 1429D6597964E51BF53D74E9A9B2E8C8 /* FBSDKPaymentObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = EF7BC936D9DC70BBB915217A9BC6AAF5 /* FBSDKPaymentObserver.h */; settings = {ATTRIBUTES = (Project, ); }; }; 1480F4923DBBF217F60572EEECB4027C /* AFNetworkActivityIndicatorManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BA07E6014E4446BC05C4593902E8FED /* AFNetworkActivityIndicatorManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 14CCB9B9C95EBBD456D7E4EABD82E0BF /* FBSDKLoginCompletion+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 09CCCCC909E043460B5C164D04C39DCE /* FBSDKLoginCompletion+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; 15EDAC05EB1C7ADBF13CDE7ECEB68CF7 /* FBSDKLikeButton+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = D1EF1935E3B0AFCF73AC1E5676BC3307 /* FBSDKLikeButton+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; 174202BD6AE0E4A41F5CE66E975EAE52 /* UIRefreshControl+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F2F1C57FA99F5807769A238263BD45D /* UIRefreshControl+AFNetworking.m */; }; 17DBDC22CDC96ABAB7D15DC0B4252B95 /* FBSDKAccessTokenCacheV3.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C87CFBB77AFE7ED5094F696A20E00DD /* FBSDKAccessTokenCacheV3.h */; settings = {ATTRIBUTES = (Project, ); }; }; 180BFD5C4CF58060C6E4673D16922EF9 /* FBSDKGameRequestContent.h in Headers */ = {isa = PBXBuildFile; fileRef = BEE123787F3B550805CD837E4984E8FC /* FBSDKGameRequestContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; 188A670E26DA49268A133953AF0BF038 /* FBSDKShareOpenGraphValueContainer+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 296E51807D61C9A541B3F4E81594BC16 /* FBSDKShareOpenGraphValueContainer+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; 192AC43D2F848129D2CAC66DAAF6CA35 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51A9C43D488BB575BBE0FD9964B712BD /* Security.framework */; }; 199E8BF13BE175C4DD97FEC3976D5F65 /* FBSDKErrorRecoveryAttempter.m in Sources */ = {isa = PBXBuildFile; fileRef = EB3472AD9F8972FD61773DA8DF704869 /* FBSDKErrorRecoveryAttempter.m */; }; 1A1DBDBFC387F891086033E7C529931C /* FBSDKCheckmarkIcon.h in Headers */ = {isa = PBXBuildFile; fileRef = E27FF6725E1FBBC2A5EC8FA3557A9246 /* FBSDKCheckmarkIcon.h */; settings = {ATTRIBUTES = (Project, ); }; }; 1A76F6D34E402E6420FACDEC32E7A563 /* FBSDKAppEventsState.m in Sources */ = {isa = PBXBuildFile; fileRef = C34A702F2DD7C4CF61FD075393BE6CAC /* FBSDKAppEventsState.m */; }; 1C96677B1A87F2938E2A28D5DE93D6A2 /* FBSDKTestUsersManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C450A354F9C39F28DDC4916ADFA5FA41 /* FBSDKTestUsersManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1D8F71B0155497482375953A5F0FF61B /* FBSDKUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = D73633CF90D5AAD0C11B22324BF69CE1 /* FBSDKUtility.m */; }; 1DCFCA14CBF89C36D853B87417E126E6 /* BFCancellationTokenSource.h in Headers */ = {isa = PBXBuildFile; fileRef = CCD86D5BDACC24412DF3B69EFA3F6C1E /* BFCancellationTokenSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1E1403542B5C6A90FFB0A5300BE7C01E /* FBSDKUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 124B31DDC1B0856244E71C50AF92CF6B /* FBSDKUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1E3648E58DE7A089A9399DED81DA2D6B /* FBSDKServerConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 8919F3FC23A317CC4BF4E8285929398A /* FBSDKServerConfiguration.h */; settings = {ATTRIBUTES = (Project, ); }; }; 1E5B8F12ED7CC40ECDB9B1F755F387E5 /* UIActivityIndicatorView+AFNetworking.h in Headers */ = {isa = PBXBuildFile; fileRef = B5BABD9E98394148DDF630511B7E8095 /* UIActivityIndicatorView+AFNetworking.h */; settings = {ATTRIBUTES = (Public, ); }; }; 20607BE2B1E5F31765026E5AC64DB27D /* AFSecurityPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BD82AD0020AF025735DBEE92D90EC9B /* AFSecurityPolicy.m */; }; 20ABB95B04C837764640801509F64EF0 /* FBSDKBridgeAPIProtocolType.h in Headers */ = {isa = PBXBuildFile; fileRef = 53989C78F19889101ABE4E633CA7AB5E /* FBSDKBridgeAPIProtocolType.h */; settings = {ATTRIBUTES = (Project, ); }; }; 20EE8030FCF2402DAC7F1C9B9DDAEF79 /* AFURLRequestSerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = E5C2EE94032E562AA6883D2FE9C5201C /* AFURLRequestSerialization.h */; settings = {ATTRIBUTES = (Public, ); }; }; 20FEB85677DF043991A88A98291D01A4 /* FBSDKAppEventsDeviceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = F8168C0CD4D0232D99DAFC627DD18468 /* FBSDKAppEventsDeviceInfo.m */; }; 22BB41D5092D2F105C7C29CE5755846C /* FBSDKLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D292EA73AB2F774E99365CA751E06BF /* FBSDKLogger.m */; }; 22F4E832A59064E51FBB64149BACAAB6 /* FBSDKBridgeAPIProtocolWebV2.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B28531CB7D39F0479D319C3355285B2 /* FBSDKBridgeAPIProtocolWebV2.m */; }; 243B4209461BA07590EAF27862C40B61 /* FBSDKAccessToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 67E43505100A6295D31ADED7C5FC9A1D /* FBSDKAccessToken.m */; }; 24600483CE2FB9BBDED179CCC892F3F8 /* BFExecutor.h in Headers */ = {isa = PBXBuildFile; fileRef = 8576C6B324FE7A205D9EE0109D560DEB /* BFExecutor.h */; settings = {ATTRIBUTES = (Public, ); }; }; 24DB7D4E986A59B0E032E4F83A69536A /* FBSDKAppGroupJoinDialog.h in Headers */ = {isa = PBXBuildFile; fileRef = 7D7F52C33CAA98AAFDC7C1F9BB8DB72D /* FBSDKAppGroupJoinDialog.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25D47C6377A30926CA5FB9C542DE1878 /* FBSDKGraphErrorRecoveryProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 63803F001E344958E2374A6E2CF2D3B2 /* FBSDKGraphErrorRecoveryProcessor.m */; }; 2691F6D8E9EED6EFC03361C9DAEA65F5 /* FBSDKProfile+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = D2298735034342AA6ADB4F009EEFBF84 /* FBSDKProfile+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; 26D3A3843B30222F9A4E20F5C6C3F99E /* FBSDKErrorRecoveryConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 26053F1FAB9B2DA8CE98D25FD7F7F394 /* FBSDKErrorRecoveryConfiguration.h */; settings = {ATTRIBUTES = (Project, ); }; }; 26F9695CA49AF7F6E6B2ECCA2EA9AD28 /* FBSDKWebDialogView.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A076680535D6C630B144572313F884B /* FBSDKWebDialogView.h */; settings = {ATTRIBUTES = (Project, ); }; }; 27591714E6846BFD95B8FBBEC15F97D1 /* FBSDKShareOpenGraphContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 234EEAD5437409F3A7C37D7ADFB11D39 /* FBSDKShareOpenGraphContent.m */; }; 27AFC2D1A21EAE366618898F50287183 /* FBSDKAppGroupContent.m in Sources */ = {isa = PBXBuildFile; fileRef = E358A56A466C2082917A1BD0273080ED /* FBSDKAppGroupContent.m */; }; 27B18B6B5E2943CF3B3CDD4812B7DB77 /* FBSDKURLConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 179F15CC373EBC2355183B3C2136DE83 /* FBSDKURLConnection.h */; settings = {ATTRIBUTES = (Project, ); }; }; 27B378AAF73A1EBB45FFD7EA38D37247 /* FBSDKLoginManagerLoginResult.m in Sources */ = {isa = PBXBuildFile; fileRef = D0EF04BF188BEED43329404FE99E480A /* FBSDKLoginManagerLoginResult.m */; }; 27D6CB001580A3864F7B7B18B5CA11D3 /* FBSDKAudioResourceLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = D2B0320B381026451CC830A8AC04FD6C /* FBSDKAudioResourceLoader.m */; }; 2866B55F0B1E204001EF16753AFD3426 /* FBSDKHashtag.m in Sources */ = {isa = PBXBuildFile; fileRef = CC012CCA1D0FFDDFF34638747D3E00B5 /* FBSDKHashtag.m */; }; 28765B10E7DCB9D8DF17F0F480743152 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E83BA00BAE5A68D7C4ACDB9A328E249 /* CoreGraphics.framework */; }; 2989C26698615F83CF5ED2957271513C /* FBSDKProfilePictureView.m in Sources */ = {isa = PBXBuildFile; fileRef = B6038486C630F3839521911A8E33D5A0 /* FBSDKProfilePictureView.m */; }; 2C00247AC73BCEF8AFF662C9CA21A471 /* FBSDKGraphRequestMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 050BDEAD1916698E214AFB26A79288B0 /* FBSDKGraphRequestMetadata.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2C1DCEEF93879DDE6AD0C2F2BC350C0A /* FBSDKLikeDialog.h in Headers */ = {isa = PBXBuildFile; fileRef = 69B93026B22A6256BC91593D0060E4A7 /* FBSDKLikeDialog.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2C737796AAD49FE609E7FB0CCF8A263C /* Bolts.m in Sources */ = {isa = PBXBuildFile; fileRef = 73CC49F1A238A9C23974D3948CD7BC41 /* Bolts.m */; }; 2D00B6543D85CBD4B2650AFDC43D093B /* FBSDKDialogConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 289E794C1F5558F52ACC04E4BFE43EB8 /* FBSDKDialogConfiguration.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2D8531AC642B560633B709121A1E5C0F /* _FBSDKTemporaryErrorRecoveryAttempter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6594B26F7080EF6B56DCB5ED6395DF1E /* _FBSDKTemporaryErrorRecoveryAttempter.m */; }; 2D93C198F3B9D0B084C2DF2049EAAD53 /* FBSDKKeychainStore.h in Headers */ = {isa = PBXBuildFile; fileRef = C2CCD702DFCD015849180F62A26CFD95 /* FBSDKKeychainStore.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2E855474A46D61569DF5CE7D2C7BC945 /* FBSDKBridgeAPICrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = DE14C7CF1D6A0C2E591C30AB03E3A304 /* FBSDKBridgeAPICrypto.h */; settings = {ATTRIBUTES = (Project, ); }; }; 2E8A32ED46194EDBE22146271F6D26DE /* UIImageView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 0AD5FFE35DAAACBC54403D264F0BE44C /* UIImageView+AFNetworking.m */; }; 2EF92BC89987CA7A7F9D8EC80B115F1C /* FBSDKGraphRequestDataAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E8C117351A53CF2CF897455EC1A43E0 /* FBSDKGraphRequestDataAttachment.m */; }; 2FA0E03C590839B4243AB5B91DD749AF /* FBSDKShareVideoContent.h in Headers */ = {isa = PBXBuildFile; fileRef = 17A80EE44E29E6E08FB9D28A2EBF7B4D /* FBSDKShareVideoContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; 2FE8ED56BF39F0870039E6E837BE5C25 /* FBSDKPaymentObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = AA72FA1E6640E44D8AF0EA9B06FF3FF3 /* FBSDKPaymentObserver.m */; }; 30BC73BB0A3D2A9FD2416A00659023B0 /* FBSDKAudioResourceLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F727643E3C6321D531B62D7A265941C /* FBSDKAudioResourceLoader.h */; settings = {ATTRIBUTES = (Project, ); }; }; 3249F988C94C1B64192C42A11902D850 /* FBSDKLoginError.h in Headers */ = {isa = PBXBuildFile; fileRef = 09FCBDC873BEAA3952579FB53590F48F /* FBSDKLoginError.h */; settings = {ATTRIBUTES = (Project, ); }; }; 334A9EB0A89E519A4CD425EF39DCDA2F /* FBSDKLoginManager+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = D06DF8B0C5E620647EF9C1A634661190 /* FBSDKLoginManager+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; 343843D298290E746FF42BFC7EEB9AA9 /* BFAppLinkNavigation.m in Sources */ = {isa = PBXBuildFile; fileRef = EC52AD4D8DBD5728FE40009628C28BDC /* BFAppLinkNavigation.m */; }; 34734437C2FDA7D41AE9F77A3CD07ECA /* FBSDKGraphRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 84D7111970DA475CC83DBD97DB62803D /* FBSDKGraphRequest.m */; }; 3708AA48F1D26CB56F88BB6FEC72DE36 /* Bolts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 10E426D732CEC0BDD792FCFFDFC725C3 /* Bolts.framework */; }; 375E8C355CB9A979E9F03DAEE9703171 /* FBSDKShareOpenGraphAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E415A3350D8CF5BECE3063DDAA0BE6D /* FBSDKShareOpenGraphAction.h */; settings = {ATTRIBUTES = (Public, ); }; }; 384AB7595557A39CB10CBD9CB467D24D /* FBSDKLiking.h in Headers */ = {isa = PBXBuildFile; fileRef = F1C7C6ED4FC099A65098F800F96701A3 /* FBSDKLiking.h */; settings = {ATTRIBUTES = (Public, ); }; }; 384AFBA2151B288649310D44078377DC /* FBSDKMonotonicTime.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A542E25A53E3F8A0E0CF2B68F2F0B29 /* FBSDKMonotonicTime.m */; }; 385E8CF0234426575581CCA6F53DD434 /* FBSDKGameRequestFrictionlessRecipientCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 76319A57979578EDB7F1DA23EDD1AC64 /* FBSDKGameRequestFrictionlessRecipientCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; 387B78488B01402C1A6A04A4485972AA /* FBSDKShareUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 322BD0C3BEA3B1E5C0531B171EB81035 /* FBSDKShareUtility.m */; }; 38EF43F03EBACFE40F480F4F8BC20FD5 /* BFURL.m in Sources */ = {isa = PBXBuildFile; fileRef = 64F241D129894E6FBF8D9AC83C2333EA /* BFURL.m */; }; 3963AF83388A5E8A18C48332F35020D4 /* FBSDKAppEventsUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = B68D7B05294DC4B65D14D28CB5312A52 /* FBSDKAppEventsUtility.h */; settings = {ATTRIBUTES = (Project, ); }; }; 3979D814B1CB5D0DF8E18C3ABDD1E5EC /* FBSDKDynamicFrameworkLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 8C76DA62C32050738F372FB86436B630 /* FBSDKDynamicFrameworkLoader.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 39E4FA2B5D0B8EFD4F9B953111DA1CFC /* BFWebViewAppLinkResolver.m in Sources */ = {isa = PBXBuildFile; fileRef = B13B01C1E5FD1A5170F6BF0ADA24F303 /* BFWebViewAppLinkResolver.m */; }; 3A01CE59DF9D68D5F2623F88E522A33E /* FBSDKGameRequestFrictionlessRecipientCache.m in Sources */ = {isa = PBXBuildFile; fileRef = B2E603D2319B68E69E2A216E62709325 /* FBSDKGameRequestFrictionlessRecipientCache.m */; }; 3A59407EA76E94E2F14A570B69CE739B /* FBSDKTypeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = AD33ECD19031FEF0B81D507EB39BD02D /* FBSDKTypeUtility.h */; settings = {ATTRIBUTES = (Project, ); }; }; 3B03433830A1679D96F443321F9E7CD2 /* FBSDKGraphRequestBody.m in Sources */ = {isa = PBXBuildFile; fileRef = C1777F9C07CE6501DB231C2A30C7BFE0 /* FBSDKGraphRequestBody.m */; }; 3D2789FC760A97301909F0B1201626CD /* AFNetworking-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D37DBF6D698BB99BFFC4CB01A283B435 /* AFNetworking-dummy.m */; }; 3D6D69351FD8DF6501A8144FF882C074 /* BFAppLink.m in Sources */ = {isa = PBXBuildFile; fileRef = 2E1AB7D493DCC2425913A6C4876BE077 /* BFAppLink.m */; }; 3EA077D046DCD950DCAC4BCD2C1C3233 /* FBSDKShareUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 8FE9770DE6951597524C4EE305EAACD3 /* FBSDKShareUtility.h */; settings = {ATTRIBUTES = (Project, ); }; }; 3F17A710798B958949B20EC8D0CCFAC0 /* FBSDKMessageDialog.h in Headers */ = {isa = PBXBuildFile; fileRef = EB25923A3C24D72670801C96252FF023 /* FBSDKMessageDialog.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3F1BC9BAFFEEABB1ABC7614DF0FC97D5 /* AFAutoPurgingImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 6154A9766C3A3BCA58EF4EBA4038751C /* AFAutoPurgingImageCache.m */; }; 3F2458F552FB89EA66BFB571C276F845 /* FBSDKApplicationDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EE74E13A61B4A768AA0B8FFACF358EFF /* FBSDKApplicationDelegate.m */; }; 3FD0D93AD926C94818225AA013D70FDF /* FBSDKShareKit-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = D5EB9C9B78B77B89CEEB5F087D46C5D1 /* FBSDKShareKit-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 406804221AD8D7EC71E4CC582AF7B1C2 /* FBSDKAppGroupContent.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B70566318E571FC681C81172C2736AE /* FBSDKAppGroupContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; 409F5BE5BDBB1D3850F4D62D5504D662 /* BFTaskCompletionSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A5E4C2CB0C115FCE208B405B681F1189 /* BFTaskCompletionSource.m */; }; 4157F58C771B24EB545FBB57552535B2 /* FBSDKGameRequestDialog.h in Headers */ = {isa = PBXBuildFile; fileRef = 956EDC51481C99DF614CB014E3A6B339 /* FBSDKGameRequestDialog.h */; settings = {ATTRIBUTES = (Public, ); }; }; 41637DA371D84C3DD6CE1A2BAD23DFE2 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A0E3C506E620CE2E7D9EE7EA6F2E5AD /* QuartzCore.framework */; }; 41B52B3E513F62AB8BD7FE9FC08368E1 /* FBSDKSystemAccountStoreAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = 302F33D66A77991641D9EABE527E2020 /* FBSDKSystemAccountStoreAdapter.h */; settings = {ATTRIBUTES = (Project, ); }; }; 42F44AD72DA11C66072D46BEC5DF08B2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70827AF45BE2EBCD723C40A04D7ECB46 /* Foundation.framework */; }; 4332DBEF82690666648C01092597A5CD /* FBSDKContainerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F51662A395C193FC0CD95DF4D613BCDA /* FBSDKContainerViewController.m */; }; 443CD693458E72E577CD457C3F55D9DD /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E9C62EB5AB13006083EC3A1F3519FC4 /* FBSDKCoreKit.framework */; }; 46D8BDB08F59CA6D31688A125F4C0E48 /* FBSDKViewImpressionTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 24B9BC43CDA1316D5C29C2814F5B936F /* FBSDKViewImpressionTracker.h */; settings = {ATTRIBUTES = (Project, ); }; }; 46E961BEA7247217652A5F012F82FECC /* FBSDKTooltipView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7A210A47B0DF6B6CBBBFB5FEA7C82DD2 /* FBSDKTooltipView.m */; }; 48FF5E216FDC53AA9802827D423EF8D3 /* FBSDKAppLinkUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F4133D976E5AC5E829D1D76612C9AB8 /* FBSDKAppLinkUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; 49239C6CF815B92F2DF5B5D79FB9B5AF /* FBSDKTooltipView.h in Headers */ = {isa = PBXBuildFile; fileRef = 071D9291B24AAEC6A06D97DC10C701E7 /* FBSDKTooltipView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4C1699BEA8B4E49D98292993C613994C /* FBSDKButton.h in Headers */ = {isa = PBXBuildFile; fileRef = D9F3A3FD7BD2508F05C8FBF147009DA3 /* FBSDKButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 4D07D0151693228D6281EDB319B448C0 /* FBSDKViewImpressionTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = D4D7A0BB6AA817122DC09D746FB66A67 /* FBSDKViewImpressionTracker.m */; }; 4DA130F813859583C3363088029A470E /* _FBSDKLoginRecoveryAttempter.h in Headers */ = {isa = PBXBuildFile; fileRef = E5499B12C2B8CAC69028FF98296B9B10 /* _FBSDKLoginRecoveryAttempter.h */; settings = {ATTRIBUTES = (Project, ); }; }; 4DCE84710050E8583735F97ADC84FCA7 /* BFAppLinkReturnToRefererController.m in Sources */ = {isa = PBXBuildFile; fileRef = C8F73117E940B605910F515665016FA9 /* BFAppLinkReturnToRefererController.m */; }; 4EBCD6EC15EDFC23EAB49AEFD48644FA /* FBSDKGraphRequestConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 3564E4DE0349A19993E8610CC040CC9A /* FBSDKGraphRequestConnection.m */; }; 4ECA9BE68D373E094EFA019CC4EA1720 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E83BA00BAE5A68D7C4ACDB9A328E249 /* CoreGraphics.framework */; }; 4F3E18A34A2779B9BA8070B9FFD8E091 /* Pods-PotterPics-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 61D174F17C7058A08EC9658CFBC014B0 /* Pods-PotterPics-dummy.m */; }; 4FA93C7BE82E47E93B2186C08174D7F9 /* FBSDKAppEventsStateManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E3775D041D8EEC8ED6D0BBA93F4FDE46 /* FBSDKAppEventsStateManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; 4FE3D0FC60D1370E831CBFF9680FA8EB /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C66B4D4D88E19B41C4EF1475A1477D3 /* MobileCoreServices.framework */; }; 514B1324C72A235480C29BBC3AD1C250 /* BFAppLinkTarget.m in Sources */ = {isa = PBXBuildFile; fileRef = B333B404501B047047F3294F00FC52A8 /* BFAppLinkTarget.m */; }; 51C1B7B60D51F4AEAA2036128E814BA0 /* FBSDKURLOpening.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C1BD126961E83CEEFB3526EC233B08F /* FBSDKURLOpening.h */; settings = {ATTRIBUTES = (Project, ); }; }; 52681368D4EB6EE79BE9FEF151AC185F /* FBSDKShareDialogMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 949E48FA38B27F20B10797133DACC6B1 /* FBSDKShareDialogMode.m */; }; 53DCAD2FF5018897F635A8F80D1B9A95 /* FBSDKWebDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = 2993229BA329377C244F962B75E1414E /* FBSDKWebDialog.m */; }; 5493E80E04D895A735853EA349C4AAE3 /* BFCancellationToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 4D509173ECC78BD99B42F22A17D81FB5 /* BFCancellationToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; 54B55A60F4122485684FA7EC79C0FF32 /* FBSDKAccessTokenCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = FBF5EC3AC894B9183DB7EDA870D9A9CB /* FBSDKAccessTokenCaching.h */; settings = {ATTRIBUTES = (Project, ); }; }; 560698A4D707DCBCC1C8F98BC9B89B23 /* AFURLSessionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = FFB5F1ED229E2F69AA805EDD810F893A /* AFURLSessionManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 56FF2E7748A9026DEECE6CB0007037FA /* FBSDKErrorConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = BA7945F87AC9D33609535DF4E917D6D5 /* FBSDKErrorConfiguration.m */; }; 57223DDD941FECB4AE83105F412AA598 /* FBSDKGraphRequestMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 95F51D818439DB35C2333ECF580CEAD7 /* FBSDKGraphRequestMetadata.m */; }; 5808B477EFF509D810B5CDCFDC944F80 /* AFImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = F696FAB825675820258C0860126EB967 /* AFImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 591FC299A2D9A1B4ED34D81F3A5B3364 /* FBSDKServerConfigurationManager+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 55E1F587AC7AD403D01F7E956416682E /* FBSDKServerConfigurationManager+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; 59834F5509421BF031C29B9CAFE404F0 /* FBSDKColor.m in Sources */ = {isa = PBXBuildFile; fileRef = A5D4C2A33C852492DAF27E4A23F3DC33 /* FBSDKColor.m */; }; 5A40CE0717F4DFAF776F12F835401D72 /* FBSDKShareError.h in Headers */ = {isa = PBXBuildFile; fileRef = DBBFC9D33690BE5B8CD94F27485FD494 /* FBSDKShareError.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5B32EA8AB19F49234A383200A5135921 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70827AF45BE2EBCD723C40A04D7ECB46 /* Foundation.framework */; }; 5C5D17AB22A659C7A35FBDB5C8DEC1AE /* FBSDKBridgeAPIProtocolNativeV1.m in Sources */ = {isa = PBXBuildFile; fileRef = BFB22238BD35F9F2CB6B4C4B72394FD2 /* FBSDKBridgeAPIProtocolNativeV1.m */; }; 5CA8E916EED0300D905FD4BCC1C336ED /* FBSDKAppEvents.h in Headers */ = {isa = PBXBuildFile; fileRef = 0DF2B5FCF45BF2A41A287E6BB8214F99 /* FBSDKAppEvents.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5DB28EB181DDB2482EAB7052C0FFDD4A /* FBSDKShareKit+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A11B62A187E7DF271BED1C24DE60AD2 /* FBSDKShareKit+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5DD204D3BDBEF19C2FFC64106A3BE225 /* FBSDKServerConfigurationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = B34CC697BCB8B6B4341DE153961C35D5 /* FBSDKServerConfigurationManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; 5F26B65B4A4711EB4BC2BC9BC48FF041 /* BFAppLinkReturnToRefererController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F9824B0ED4577D5374BC2CB42CD0687 /* BFAppLinkReturnToRefererController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5FF6453E55785669885F626B853FD2AA /* UIProgressView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 20CE7239B1D2FDDB8288044920159A7D /* UIProgressView+AFNetworking.m */; }; 60CAF8D6E879B1585D61B55EE807A113 /* BFTask+Exceptions.m in Sources */ = {isa = PBXBuildFile; fileRef = BD13EABB51615CBC9F07BB5ABD554881 /* BFTask+Exceptions.m */; }; 60E3009342BEE96D32C546BE2DB60052 /* UIImageView+AFNetworking.h in Headers */ = {isa = PBXBuildFile; fileRef = 3419D37B887BC1CE701D49ED228E9436 /* UIImageView+AFNetworking.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6167D4C5CA1DF7E209EE66CD5E706DB5 /* FBSDKLikeObjectType.h in Headers */ = {isa = PBXBuildFile; fileRef = C65B8B4258A289D02EEB422B96A89EF4 /* FBSDKLikeObjectType.h */; settings = {ATTRIBUTES = (Public, ); }; }; 61E2DD53D9A1ED0A5DCE23326A57765C /* FBSDKProfilePictureView.h in Headers */ = {isa = PBXBuildFile; fileRef = 7619958FDC7FDB339812E4C7FA92EA62 /* FBSDKProfilePictureView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6200682BC2425BD28680140B8EF3851E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70827AF45BE2EBCD723C40A04D7ECB46 /* Foundation.framework */; }; 62A48526C86AC1FD4D71E2A0C913AAB8 /* FBSDKTriStateBOOL.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B50E574550A9353C447811E34C10086 /* FBSDKTriStateBOOL.m */; }; 652EE84BA55F2A6BD325768B753565D8 /* BFExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E31B7EF7D80815F0DF17659122C16 /* BFExecutor.m */; }; 6548721272A6621436915353754710A7 /* FBSDKConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 800B0D395871B2D1804E151D5EC2B4DD /* FBSDKConstants.m */; }; 65866EFFD741914649CE881BDDC24F60 /* FBSDKWebDialogView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8232C20793F566FF30C03A94BDA3EE78 /* FBSDKWebDialogView.m */; }; 659960F7E28E993E08CCC1E8A383E710 /* UIKit+AFNetworking.h in Headers */ = {isa = PBXBuildFile; fileRef = F0AC2705D48C5A4C7DE0885AB3E06FB1 /* UIKit+AFNetworking.h */; settings = {ATTRIBUTES = (Public, ); }; }; 65AD76A5209F07993BCCF096FA03E254 /* FBSDKLikeControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B7482B2E7186DBE28DA80B8BBEFE69D /* FBSDKLikeControl.h */; settings = {ATTRIBUTES = (Public, ); }; }; 65EF134F08720505DBCEEA7977CA7C55 /* Pods-PotterPicsUITests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = A63C29CD93EA418D5FD134CBB77B5099 /* Pods-PotterPicsUITests-dummy.m */; }; 66533D7A594AA93C8C43EF1BCE668A74 /* FBSDKAppInviteContent.h in Headers */ = {isa = PBXBuildFile; fileRef = 30277D302B666A9583A67ADEE4829C79 /* FBSDKAppInviteContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; 68152D921ABF6A423C192C04FDF94F0F /* AFNetworkReachabilityManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 404F63CB215FA69CA32209AE8B409949 /* AFNetworkReachabilityManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6817DE148CDBD0D314AFC83255A645E4 /* FBSDKLoginTooltipView.h in Headers */ = {isa = PBXBuildFile; fileRef = 52103E91501D5814A590442E9FDBE139 /* FBSDKLoginTooltipView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 683F00DC5BC8E350C511CB04D6489A61 /* FBSDKURLSessionTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 614120AD63FA0D77588B740BBB2F70B0 /* FBSDKURLSessionTask.h */; settings = {ATTRIBUTES = (Project, ); }; }; 683FC99BAEA8DDE9EBEE2EC93F949B36 /* FBSDKLoginManagerLoginResult+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B849A31AF3D7B0536BAF097C883CE83 /* FBSDKLoginManagerLoginResult+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; 688E37A2E29646148D380D9034875174 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BF4F0A153C80690869A35B06385A66D /* SystemConfiguration.framework */; }; 68A38977EBAE334DC3C22386D00D2622 /* AFNetworkReachabilityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = EC41976D2B74FA9072C676F86517427B /* AFNetworkReachabilityManager.m */; }; 6A42401E163EF7DF7C8464E941864541 /* FBSDKMutableCopying.h in Headers */ = {isa = PBXBuildFile; fileRef = A8E2E6394893FE46321D0A87D90E8774 /* FBSDKMutableCopying.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6A8B92B5BDFBEE6BD3F70901FB71A0B1 /* BFTask+Exceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 7645ABECFC91260CE63FE96F1F0F938A /* BFTask+Exceptions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6B7DD32A130E3052BBB254E95E8897F5 /* FBSDKGameRequestContent.m in Sources */ = {isa = PBXBuildFile; fileRef = D8532C3DE9D5AC1EEDFADF9E33A8CA51 /* FBSDKGameRequestContent.m */; }; 6BBB1458E4A923496BDABF7A13E00C27 /* FBSDKBridgeAPIProtocolWebV1.m in Sources */ = {isa = PBXBuildFile; fileRef = B4023741CB92EC46CEB293AF1BF5F718 /* FBSDKBridgeAPIProtocolWebV1.m */; }; 6BC497E6FA97D13CEFE6919C46F7EFF4 /* FBSDKLikeBoxView.m in Sources */ = {isa = PBXBuildFile; fileRef = 57A52633C9C0C5FA2191B342B8DBB6D7 /* FBSDKLikeBoxView.m */; }; 6C9A8D47F3B71046F320078FCF8E4B21 /* FBSDKError.h in Headers */ = {isa = PBXBuildFile; fileRef = FC56D94F5E6790B727E2400EF769F104 /* FBSDKError.h */; settings = {ATTRIBUTES = (Project, ); }; }; 6CB8F54E16ED334F8114F012E41D6B94 /* Bolts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 10E426D732CEC0BDD792FCFFDFC725C3 /* Bolts.framework */; }; 6CEEDECCE819709B38F3232102D4808B /* FBSDKLogo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3368C70225DA4184943E1A027F4C750E /* FBSDKLogo.m */; }; 6D18D3AD65417A5E1F5C62611794A141 /* FBSDKCrypto.m in Sources */ = {isa = PBXBuildFile; fileRef = EFA1CD6866EC21FCF10919413F1D2141 /* FBSDKCrypto.m */; }; 6E2B6054F217E3D01C59665D011B09B1 /* BFMeasurementEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = AD53C2272608B872C324855ECB5511D9 /* BFMeasurementEvent.h */; settings = {ATTRIBUTES = (Public, ); }; }; 6ED4ABEE8A5F51F5ECB59FA1781D29C6 /* UIActivityIndicatorView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = 4747C6A0E75EBEDCF1246631896B81A2 /* UIActivityIndicatorView+AFNetworking.m */; }; 6F852F8B67F8A20BB296716E1AEE0AB7 /* FBSDKShareKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C58C011E0A74E340CC9F79605F65D85A /* FBSDKShareKit-dummy.m */; }; 700A0C2CD36658F1B0C0B1F06B8EEB26 /* FBSDKCloseIcon.m in Sources */ = {isa = PBXBuildFile; fileRef = F1AF5D1C5557D2E36ACA410EE645160C /* FBSDKCloseIcon.m */; }; 707B1A7541C8DBDDE8C27896A61370BE /* AFURLSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C4CD1BAB77A875F0B791189A9DF7A89 /* AFURLSessionManager.m */; }; 70A9ACFE11830087A2F515C2D9B83A36 /* FBSDKConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EA26D4657F56ED7C7AD3C7CF40938DF /* FBSDKConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7332F15718920917F544F35CE2C038AA /* AFURLResponseSerialization.h in Headers */ = {isa = PBXBuildFile; fileRef = DC96BE4A20B07F3244063DF2220E0AB4 /* AFURLResponseSerialization.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7333194276505D454DACD2603FEE0271 /* BFCancellationTokenRegistration.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A7898F3536B5C094F621EC7E3310342 /* BFCancellationTokenRegistration.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7363AA8C008065817E76B9388EAEDFF8 /* Pods-PotterPicsTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F71BFA8EDBB8BE5A3A1072C32B5DD3A /* Pods-PotterPicsTests-dummy.m */; }; 73AD14D5BACD6BC0D90B444C458E8FD4 /* FBSDKDialogConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7EDD6E1F6211E24E396BF86C89B5B0 /* FBSDKDialogConfiguration.m */; }; 747339FDBF19337791654E8E26A10995 /* FBSDKMonotonicTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D91C36CE02C714CF6686A657B9979E0 /* FBSDKMonotonicTime.h */; settings = {ATTRIBUTES = (Project, ); }; }; 755CAA0856609A25D4C138A0DF24B800 /* FBSDKAppEvents.m in Sources */ = {isa = PBXBuildFile; fileRef = 969A5B09EED30468F88F2401AAEF5758 /* FBSDKAppEvents.m */; }; 75BAFB5D292A5AC28EBAC6EA8D73CFC6 /* Bolts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 10E426D732CEC0BDD792FCFFDFC725C3 /* Bolts.framework */; }; 762276A054BDBCD8DD9667D736190CF9 /* FBSDKAppLinkUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 418F149D3D82EED551FD8535B54E541D /* FBSDKAppLinkUtility.m */; }; 763F76FF18569C1C701FA8B251DA3AFE /* FBSDKLoginManagerLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 355EAFC2BF57DCFF081CC4F62BEFA490 /* FBSDKLoginManagerLogger.m */; }; 767C65F9CCCCA6B6E0A43C04594899BC /* FBSDKLoginConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = E120AA6183A04CF6357B5A672B44C9B7 /* FBSDKLoginConstants.m */; }; 76F6D75839266FB7F287B7DB0D378184 /* FBSDKGraphRequest+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 0705221C472B862B8D97A7E30C67C5C3 /* FBSDKGraphRequest+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; 76F96A14F0A8DBF44BD7E419DAF7B877 /* FBSDKLikeButtonPopWAV.h in Headers */ = {isa = PBXBuildFile; fileRef = FB4B3634A661281E58317EADEB114C90 /* FBSDKLikeButtonPopWAV.h */; settings = {ATTRIBUTES = (Project, ); }; }; 77BF46EE1E54C91A7080408F8767A3DF /* FBSDKShareVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 00676AF610DA21956BC730C01D7298FD /* FBSDKShareVideo.m */; }; 78086867BF7BBED7E16245632C4E84CA /* FBSDKLoginError.m in Sources */ = {isa = PBXBuildFile; fileRef = E4A9423C5315B0FFA7996239E7E13BC1 /* FBSDKLoginError.m */; }; 78E3B43BC8EA92B48B10612FBA17B02C /* FBSDKBridgeAPIResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F6224EB54AEB5C2DE1DE420F9A43596 /* FBSDKBridgeAPIResponse.m */; }; 78EA084779CE7F9CED6ACF196B5EB607 /* FBSDKLogo.h in Headers */ = {isa = PBXBuildFile; fileRef = E5A7F39C006211ABC22FC3E7431BD43E /* FBSDKLogo.h */; settings = {ATTRIBUTES = (Project, ); }; }; 79BE10093D731A2D4878DB7F8F46ADB3 /* FBSDKCloseIcon.h in Headers */ = {isa = PBXBuildFile; fileRef = C03EA17AC9B7FA3EF6873BD9015ECF79 /* FBSDKCloseIcon.h */; settings = {ATTRIBUTES = (Project, ); }; }; 7B0F099011442A12FE9794107B879B9C /* FBSDKAccessTokenCacheV3.m in Sources */ = {isa = PBXBuildFile; fileRef = C1BAA4B321D5F11E1C62671BEA4CC582 /* FBSDKAccessTokenCacheV3.m */; }; 7BB98E50240143972C28AA9A13EBC3D5 /* BFAppLinkResolving.h in Headers */ = {isa = PBXBuildFile; fileRef = D6DEC30656F6CB2F37C4C8127F8A6B19 /* BFAppLinkResolving.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7C7E248D341E116E1A7B8C16A8F58C6B /* BFTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 718E2D10A7A72D21C487CA83B3F5A13F /* BFTask.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7D71E19849D32B258191F32920CE8C74 /* FBSDKCoreKit.h in Headers */ = {isa = PBXBuildFile; fileRef = EA7FBCFFA76DC9969D1C804EC5A2DF5E /* FBSDKCoreKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7E7F5D5FECCC6BB4319C11A419E9BB09 /* FBSDKProfile.m in Sources */ = {isa = PBXBuildFile; fileRef = DA2F8969582848AC7C57D2530917927E /* FBSDKProfile.m */; }; 7E9100394CBFFADF64B26C6F4373F78E /* FBSDKAppInviteDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BA89B7CB74DAA591F92581FD6474C01 /* FBSDKAppInviteDialog.m */; }; 7F0237413FACB7A3676D95631D9F3B0C /* _FBSDKTemporaryErrorRecoveryAttempter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1BD23CFB4A0B2C21AB6643701F7A53D7 /* _FBSDKTemporaryErrorRecoveryAttempter.h */; settings = {ATTRIBUTES = (Project, ); }; }; 808E738E1648120C1045BB75BB8AC058 /* FBSDKCheckmarkIcon.m in Sources */ = {isa = PBXBuildFile; fileRef = CA75839331F42194ED8BABCA637B61DC /* FBSDKCheckmarkIcon.m */; }; 812CC9954198FB632F3670E2D554898F /* FBSDKShareConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = EAD69571A07FB3D8D3FB6191BCDB7F69 /* FBSDKShareConstants.m */; }; 8170C4AC05E84ED31A9D33A4CD205D2C /* BFWebViewAppLinkResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = B6C4053DC4067A1964C8D3A08AB1AA0A /* BFWebViewAppLinkResolver.h */; settings = {ATTRIBUTES = (Public, ); }; }; 81AADA5ADE8535AD6F7678C6F3A06E89 /* MBProgressHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = A8D64AE9FE48CBC32B35A212E4B461C6 /* MBProgressHUD.m */; }; 81B617F8D26BB10C5726D75E85D21EB7 /* UIButton+AFNetworking.h in Headers */ = {isa = PBXBuildFile; fileRef = BB144CFDE6AF6A88F63BC0B5D75AD5F3 /* UIButton+AFNetworking.h */; settings = {ATTRIBUTES = (Public, ); }; }; 82008ED885D5AB3464812191AB960057 /* FBSDKShareVideoContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 356DB9AFF70A7328E4141C2B7805D5C2 /* FBSDKShareVideoContent.m */; }; 828A250670EEC2897DACA767080A8CA7 /* FBSDKLoginManagerLoginResult.h in Headers */ = {isa = PBXBuildFile; fileRef = B43763897ABF0E93E17BF93AB719E3F8 /* FBSDKLoginManagerLoginResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; 82D7BE28B1585DA660DE327BB496D656 /* FBSDKBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = D72C11AF3A74FB5E0B69AC82FD7BEB76 /* FBSDKBase64.h */; settings = {ATTRIBUTES = (Project, ); }; }; 835DEC134806538B138A8837B3D24F70 /* FBSDKBridgeAPIProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 5845C018E4DD128CECEBF0909F0741FD /* FBSDKBridgeAPIProtocol.h */; settings = {ATTRIBUTES = (Project, ); }; }; 845719FAA2F09FF6781E7D43D3A6F5A3 /* FBSDKSettings+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = E5F6F9EDBCDDE76BDC6C33E0669EF224 /* FBSDKSettings+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; 84DAB5206F3A2091F6E750821F398C09 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70827AF45BE2EBCD723C40A04D7ECB46 /* Foundation.framework */; }; 85D97B96B98C541629F6C6866DAFC1A2 /* FBSDKBridgeAPIProtocolWebV1.h in Headers */ = {isa = PBXBuildFile; fileRef = AE6CADA5CA6B23D2715AC2D9938757C7 /* FBSDKBridgeAPIProtocolWebV1.h */; settings = {ATTRIBUTES = (Project, ); }; }; 86A4C9883826DA7856397C1EE3441257 /* FBSDKShareLinkContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E0B8656F789272A8FBBDF797EEFF2E9 /* FBSDKShareLinkContent.m */; }; 86C7B4DC7245C1E31565C74EBC34B5A8 /* FBSDKLoginManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 674612913AD6C74859A7D27EA17410D4 /* FBSDKLoginManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 885EA75AEF9C1C5631087D67494599F1 /* FBSDKLikeControl.m in Sources */ = {isa = PBXBuildFile; fileRef = D6858FA37A34E608E6179A5EE01A9D62 /* FBSDKLikeControl.m */; }; 89B59BD52908BA3B2EEED23398CF79E6 /* FBSDKCoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E9C62EB5AB13006083EC3A1F3519FC4 /* FBSDKCoreKit.framework */; }; 89DC0A9AEBB5F53137CAC02700F1EC77 /* FBSDKAccessTokenCacheV3_17.h in Headers */ = {isa = PBXBuildFile; fileRef = C95CF36B007E563455F5296F4BF0218D /* FBSDKAccessTokenCacheV3_17.h */; settings = {ATTRIBUTES = (Project, ); }; }; 8BB11C8D9F58C1E81A26BD7EE74093D1 /* FBSDKShareAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = B415354078EAF066BEEA2A2941FB7DDD /* FBSDKShareAPI.m */; }; 8BF401C38065E3AC9BD840243F4DD820 /* FBSDKAppGroupAddDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = A57D7246BF58D3474B15611646CF3E11 /* FBSDKAppGroupAddDialog.m */; }; 8C7CABBE4EC64C461AF9AE36EA44C050 /* FBSDKShareMediaContent.h in Headers */ = {isa = PBXBuildFile; fileRef = 93C77F3F8273FA0EDE7F082BB7C6BE6C /* FBSDKShareMediaContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8D4CD2DC3A6A4B2AA3087AA5048399E7 /* FBSDKKeychainStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 855D8A1728D8820964F4D6A0312D7A5D /* FBSDKKeychainStore.m */; }; 8E2D371C41A1C09CEF9F9BFCB630C0BE /* FBSDKGraphRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = BAE798271E874DBB143FD87F7C9B5009 /* FBSDKGraphRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8E4988A18BF13F6406E4D2E633027231 /* FBSDKGraphErrorRecoveryProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = E464801267CE346683BC078B76EF31AF /* FBSDKGraphErrorRecoveryProcessor.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8E678F3A93AF7E81BD5B4DE16E9FAC71 /* FBSDKMessageDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E08664A53F5655D415B1FE8A309FA30 /* FBSDKMessageDialog.m */; }; 8FD9899D436F154F3491C5D308B57B32 /* FBSDKSharingContent.h in Headers */ = {isa = PBXBuildFile; fileRef = A72EBD6B3894AA3DCD35DA7D490A9270 /* FBSDKSharingContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; 90EB41BDF3FE41A9FBFCBA9F77EDACE3 /* FBSDKBoltsMeasurementEventListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BCB92F107DC90466A905DFE5FCDA41E /* FBSDKBoltsMeasurementEventListener.h */; settings = {ATTRIBUTES = (Project, ); }; }; 91461806305F16B4B68CC47B4FE551C3 /* FacebookSDKStrings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = CDDE60295A376CD8BB037C7A798D32CE /* FacebookSDKStrings.bundle */; }; 91AFF1186F1BBFB010FE5A706961ECE0 /* FBSDKBridgeAPIRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = BA472FAE62F4170052081A3990353BCE /* FBSDKBridgeAPIRequest.h */; settings = {ATTRIBUTES = (Project, ); }; }; 928E3FA159592606B2D377B32D56934F /* FBSDKBase64.m in Sources */ = {isa = PBXBuildFile; fileRef = 56A18B2B02035244FF1C4670E485B31D /* FBSDKBase64.m */; }; 93CB179F47B5E343CCF361D181638E2E /* FBSDKShareDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = D66F787B8DEE80A4542BD8B221A29756 /* FBSDKShareDialog.m */; }; 9404840E2A2064803E55062DD88154F7 /* FBSDKGraphRequestConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F122C0918E12CF55D9A81F9A003998 /* FBSDKGraphRequestConnection.h */; settings = {ATTRIBUTES = (Public, ); }; }; 97CD6CF37BB5BE78C2A234AC897802B7 /* FBSDKLikeBoxView.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CF7F766822A475D8B194105C5BD3E81 /* FBSDKLikeBoxView.h */; settings = {ATTRIBUTES = (Project, ); }; }; 98AF6E202E68E9B4F22202842DC0D619 /* FBSDKSharePhotoContent.m in Sources */ = {isa = PBXBuildFile; fileRef = B22FDA84998D1688B0DD780C38A80F0E /* FBSDKSharePhotoContent.m */; }; 9991B7ED54593BD5F26EF68DC59E1D4B /* FBSDKLikeActionControllerCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 89D7C0A0BD6013F82B4B5D8EBBDC4A98 /* FBSDKLikeActionControllerCache.m */; }; 99BCC2F48031C4DF19C25EC274DB057F /* FBSDKSharing.h in Headers */ = {isa = PBXBuildFile; fileRef = 338833E9EEBA4312501F310EA0F85CFD /* FBSDKSharing.h */; settings = {ATTRIBUTES = (Public, ); }; }; 99FA28E0A77EBF35E1C94E6C5851DB44 /* BFCancellationTokenSource.m in Sources */ = {isa = PBXBuildFile; fileRef = AF6C35358530931A262498189B73AD23 /* BFCancellationTokenSource.m */; }; 9A0B6587B7EDADD06D3ADD8F12ECA0C5 /* FBSDKAccessTokenCacheV4.h in Headers */ = {isa = PBXBuildFile; fileRef = 2C643A8A0CDCBDC00ECAB15922C9DA24 /* FBSDKAccessTokenCacheV4.h */; settings = {ATTRIBUTES = (Project, ); }; }; 9B045FC64D2A32D380593AEA86A28904 /* Bolts.h in Headers */ = {isa = PBXBuildFile; fileRef = E47F8F57287DE302CE0477B586E91983 /* Bolts.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9BBF52FCCBDF34280736F72483E33379 /* FBSDKBridgeAPIRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 40EB7017FCE21EF267F33905494BFE43 /* FBSDKBridgeAPIRequest.m */; }; 9BBFEC80F690828CA401BE7E11345EE6 /* FBSDKInternalUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 3818796F76375FAF3283D90B9B1B6172 /* FBSDKInternalUtility.h */; settings = {ATTRIBUTES = (Project, ); }; }; 9CADD29609C9EAF87DB90BF1CF5233D7 /* FBSDKMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 31381C7B24A5039BBB6CCF74EB2C2EF5 /* FBSDKMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9E1E90DED74B73ECE53C9AD76DE53E2D /* UIImage+AFNetworking.h in Headers */ = {isa = PBXBuildFile; fileRef = DEA2562FC7F4C75E4E3C454A1A88CF70 /* UIImage+AFNetworking.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9E40001D7D2CAC32039C59FC0208A7CA /* Bolts-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 785F63E278C09554AFFFCF5F7CDF4A84 /* Bolts-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9E82EB8CB75FC077C589F4C52A24095F /* FBSDKAccessTokenCacheV3_21.m in Sources */ = {isa = PBXBuildFile; fileRef = C56454497F44EC43E8AD4122182BA797 /* FBSDKAccessTokenCacheV3_21.m */; }; 9ECB71F2FC66B85082C35CE4AEAAD509 /* FBSDKGraphRequestPiggybackManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 916F359EF719D81C62ED80EE052EC6AB /* FBSDKGraphRequestPiggybackManager.h */; settings = {ATTRIBUTES = (Project, ); }; }; 9FE6105E7FF114DF7F9C43BF76A7B790 /* FBSDKButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FD04A0F50673290125B8C62ED8506C4 /* FBSDKButton.m */; }; A0DF7E397B57D50B5E89228082DB4361 /* FBSDKShareMediaContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 3600C3929B2E962EBC7189EC010FC34B /* FBSDKShareMediaContent.m */; }; A3CE342B34D0DAA7BE2AA45BEF94CAFC /* BFAppLink_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C1A016781B2CFFF3675BBD3E47ECBEEF /* BFAppLink_Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; A411DDDACF2FE64E4123D2654049E331 /* BFMeasurementEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 0A125CDAF09D1BA4CC6380D652520C21 /* BFMeasurementEvent.m */; }; A462945883F7729B185B64B679A6BFBE /* UIWebView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = B90052B3335BE6C11194A4B1B3EB1F69 /* UIWebView+AFNetworking.m */; }; A54F557F6175E445E98C30B98B5A3AD6 /* FBSDKSharePhoto.m in Sources */ = {isa = PBXBuildFile; fileRef = 14FF537E964BE5C76DF4B233527AD0CF /* FBSDKSharePhoto.m */; }; A6437070CF1C249685D69D693BB130F5 /* FBSDKSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = 822A1AFEADDF1069BE0A1DBBCAD88637 /* FBSDKSettings.m */; }; A69128071A53DBC4882CC8DC76782334 /* FBSDKLoginTooltipView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7799E170550970BBF284103DCCAB56B4 /* FBSDKLoginTooltipView.m */; }; A6C6019D45BE62C61210A9CC619368EF /* AFNetworkActivityIndicatorManager.m in Sources */ = {isa = PBXBuildFile; fileRef = A9D0227C8AF275CF95C09168D0B754B9 /* AFNetworkActivityIndicatorManager.m */; }; A73E5104E58344ECB5A8F7B162F4C988 /* FBSDKServerConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = B4D3BA24C465B15F981E476FD5D9E3B4 /* FBSDKServerConfiguration.m */; }; A877EB9CF2930345DD962B4BC0D24959 /* BFTaskCompletionSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 6AF1AB60322572242167BDB50A1044A8 /* BFTaskCompletionSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; A8B64346A4A2013DFBD54486BFCE11A9 /* FBSDKBridgeAPIRequest+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = FCE73BF6B4E09090F8B4D7EAE911A6EB /* FBSDKBridgeAPIRequest+Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; A8B8AED7CC2CC62986985FC638A2547C /* FBSDKAppEventsStateManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FD407E320BE66588168BEB8DAFB77B8 /* FBSDKAppEventsStateManager.m */; }; A8E0FCC37561E057927BC29EF5B99E02 /* FBSDKCopying.h in Headers */ = {isa = PBXBuildFile; fileRef = 49FB2AE04082C4817E34C765D0CC168A /* FBSDKCopying.h */; settings = {ATTRIBUTES = (Public, ); }; }; A9650954E31B48DD860AFE2F0752C80A /* FBSDKAppLinkResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = A8AE2299D370304260AD0BE1EE2F4799 /* FBSDKAppLinkResolver.h */; settings = {ATTRIBUTES = (Public, ); }; }; A9EF2B17DE733FCA4623A40A27F6ECC5 /* SwiftyJSON-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CDA368B9F67E0B774EA1AC6F3142A78 /* SwiftyJSON-dummy.m */; }; AA94F90D3D0EEA7792F9584C860ADD30 /* FBSDKGraphRequestPiggybackManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E8E73443DC19BD45AC2BE2F1D5DA6FEB /* FBSDKGraphRequestPiggybackManager.m */; }; AB39AC9746E7575D7449700475E41B0B /* AFHTTPSessionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E75958EF9F3DB83089704F6DF0207418 /* AFHTTPSessionManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; AD52B349A273F0EB40F823990A40D2CD /* FBSDKLoginConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = C67B3396039B22A161B9FFC678BEF36C /* FBSDKLoginConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE2A07407FB50BA249984DC0620E84C0 /* UIWebView+AFNetworking.h in Headers */ = {isa = PBXBuildFile; fileRef = B3BF0923C01840E90921E5BCD8CEC87E /* UIWebView+AFNetworking.h */; settings = {ATTRIBUTES = (Public, ); }; }; AE88CF4A135C8C1E79FEBB43EE2B38F8 /* BFAppLinkReturnToRefererView_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 3ABB7E09BE20FAE0E0F42F34FBD487CC /* BFAppLinkReturnToRefererView_Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; AEC88D8012A4396714B28985099C6EFF /* FBSDKAccessToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 53434689A20D327D05B13DD331C4F27D /* FBSDKAccessToken.h */; settings = {ATTRIBUTES = (Public, ); }; }; AF03C11A1FAC8132AD3749D8F541701A /* UIButton+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = B8E5EDD2E5CE2CD25F918C7F6C0E6CB2 /* UIButton+AFNetworking.m */; }; AF53BABEF4555D0436B0D6DAB01F75D2 /* FBSDKURLConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = 60AC0A7B43501C2A1D4BAF0FC1A03769 /* FBSDKURLConnection.m */; }; B23C036B9C9FE3E152A6BC3FA8F9828D /* FBSDKCrypto.h in Headers */ = {isa = PBXBuildFile; fileRef = DDB995465AE9F9D7AFA7C1E10FD68131 /* FBSDKCrypto.h */; settings = {ATTRIBUTES = (Project, ); }; }; B3EF5F677DAF43756C055223BB16FC64 /* FBSDKAccessTokenCacheV4.m in Sources */ = {isa = PBXBuildFile; fileRef = 9032105C5C5AA8354FCE77960A9887D5 /* FBSDKAccessTokenCacheV4.m */; }; B534C8C1D32294DB54F3C5CFFD5AAA9B /* FBSDKLoginButton.m in Sources */ = {isa = PBXBuildFile; fileRef = A0B37EFD471FF5DEECEE4775C9AC24A7 /* FBSDKLoginButton.m */; }; B5852322ADE88AAD56EE042B80BA81E4 /* AFURLResponseSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 325A848210CDC11F2737F04B83826DB3 /* AFURLResponseSerialization.m */; }; B6A35457F14D3CCDEB68B8E69D71EAE5 /* FBSDKTypeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F33E2D7EB6A1A15DFA3E425BE4CDBC1 /* FBSDKTypeUtility.m */; }; B73B1BCB2899627D421709275BA22697 /* FBSDKError.m in Sources */ = {isa = PBXBuildFile; fileRef = 69768F59318EE677B9D13A269EFC5AAD /* FBSDKError.m */; }; B74D40AC59FF4E03D30024F6CFE94BD1 /* FBSDKLikeButton.h in Headers */ = {isa = PBXBuildFile; fileRef = C1D2C05DC29BBFFBED4CFBED1C5A6E12 /* FBSDKLikeButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; B80E99999E2A245B701DC0731CB02ABC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70827AF45BE2EBCD723C40A04D7ECB46 /* Foundation.framework */; }; B99FAFBBC58F176BCBAA61124A21C14B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70827AF45BE2EBCD723C40A04D7ECB46 /* Foundation.framework */; }; B9F622CCC8F218363ADC3D4B029279A2 /* FBSDKKeychainStoreViaBundleID.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BFD3450928A0D3AB4430B03901CFCAB /* FBSDKKeychainStoreViaBundleID.h */; settings = {ATTRIBUTES = (Project, ); }; }; BB0AA4F4FAF414D7D1317C96DC4B64E1 /* FBSDKSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = 98D2BF226F3B31B1A062BF6C4D02E928 /* FBSDKSettings.h */; settings = {ATTRIBUTES = (Public, ); }; }; BC6E9E2792A93805AA69AD5E503E69DA /* FBSDKKeychainStoreViaBundleID.m in Sources */ = {isa = PBXBuildFile; fileRef = F75911B1C5FA2475BFF11249796F94D2 /* FBSDKKeychainStoreViaBundleID.m */; }; BC82780C5FED62B06DC51F6DCA0491B5 /* BFURL_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = CAC188BFAD7FD3006FDEAA6F11B98188 /* BFURL_Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; BCAB58F8DE87B33E128B5C090EEB3E8E /* FBSDKShareAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = A93C272A5F5F3856EDD3567597A6F6B0 /* FBSDKShareAPI.h */; settings = {ATTRIBUTES = (Public, ); }; }; BD1FA39CEA9C5F52DA8E2729A7E366F4 /* FBSDKTestUsersManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D9DB3883D692B0606CD7C950B471957 /* FBSDKTestUsersManager.m */; }; BD58659499DB6E135229A124B3FC2EEF /* FBSDKErrorRecoveryAttempter.h in Headers */ = {isa = PBXBuildFile; fileRef = 3E5817463D8E6C05AE18A2727EE775AB /* FBSDKErrorRecoveryAttempter.h */; settings = {ATTRIBUTES = (Project, ); }; }; BDA6B7E75F4E3C0233182FFD67F1DAA8 /* FBSDKMaleSilhouetteIcon.h in Headers */ = {isa = PBXBuildFile; fileRef = F5B5D8ADAEF759D6862C19B408FC4C58 /* FBSDKMaleSilhouetteIcon.h */; settings = {ATTRIBUTES = (Project, ); }; }; BE537D3EDB5514160FD8CCD95B97F39B /* FBSDKTimeSpentData.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D46190A40A28D9477301E0E9F818EA8 /* FBSDKTimeSpentData.m */; }; C05225EA8ACCF663097C4EC96E8E9887 /* BFAppLinkReturnToRefererView.m in Sources */ = {isa = PBXBuildFile; fileRef = 417010D9205941599775F7E5B437FA89 /* BFAppLinkReturnToRefererView.m */; }; C2D51BA1EC47A0EAE713858A0EDEB951 /* FBSDKWebDialog.h in Headers */ = {isa = PBXBuildFile; fileRef = 543C86122D60B63563B33DACF4683FC8 /* FBSDKWebDialog.h */; settings = {ATTRIBUTES = (Project, ); }; }; C2DD28375E1F0B1D0D1D2E4E607C499F /* AFSecurityPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A55A04F0794E3AED3095BF9F3F91384 /* AFSecurityPolicy.h */; settings = {ATTRIBUTES = (Public, ); }; }; C2F01DAF3B61ED2055801480ABBF9B94 /* FBSDKTimeSpentData.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CD2C6B54FE2F8E9C9C0D350E8BAA1BA /* FBSDKTimeSpentData.h */; settings = {ATTRIBUTES = (Project, ); }; }; C39613DBB90FF65789612725FC595542 /* FBSDKAppInviteDialog.h in Headers */ = {isa = PBXBuildFile; fileRef = 64CC903CB9F6197DD6C870CF0672B6D3 /* FBSDKAppInviteDialog.h */; settings = {ATTRIBUTES = (Public, ); }; }; C51B4865E5186E9BF6DB6BEFC9517EF1 /* FBSDKHashtag.h in Headers */ = {isa = PBXBuildFile; fileRef = 7F6EDE97780B565FFB1B4DBE05562EBB /* FBSDKHashtag.h */; settings = {ATTRIBUTES = (Public, ); }; }; C56378807B25F03F1862E3E22E992A8D /* SwiftyJSON.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E079AE02625BC14DAD98571BEBEB8BF /* SwiftyJSON.swift */; }; C583FF6D5F3A73498E46D8D80B21E3DB /* FBSDKLoginKit+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = FD8FD30657D301CAC2E078975D5035FD /* FBSDKLoginKit+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; C6354FEC7728A4C86DAD8092509BA7D4 /* UIRefreshControl+AFNetworking.h in Headers */ = {isa = PBXBuildFile; fileRef = B6AC322AFE8269208192FA62AD2A219F /* UIRefreshControl+AFNetworking.h */; settings = {ATTRIBUTES = (Public, ); }; }; C690CF49E6BA659D39725D34B0CC260B /* FBSDKIcon.h in Headers */ = {isa = PBXBuildFile; fileRef = B4CA25A29D26AF8E66E28490C969AF5B /* FBSDKIcon.h */; settings = {ATTRIBUTES = (Project, ); }; }; C6BED30D7A2A56482A411EDAECCEDCBF /* Pods-PotterPicsTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = D751570D07A6198A619045C589D426A9 /* Pods-PotterPicsTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; C77BADC0FD562402E2E30759A5F17CFA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70827AF45BE2EBCD723C40A04D7ECB46 /* Foundation.framework */; }; C7E1185AD9DA7CDEF22CC10F4317E941 /* FBSDKGraphRequestDataAttachment.h in Headers */ = {isa = PBXBuildFile; fileRef = DDCA2DD0D90DEA85D29FC3C7A43E10DD /* FBSDKGraphRequestDataAttachment.h */; settings = {ATTRIBUTES = (Public, ); }; }; C8A2479793F6D05DE6D8FA164EB7C00D /* Bolts-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D28EF19A899EA7B11BFB90D1F8F63312 /* Bolts-dummy.m */; }; C9239042BAF0562154A942D3598BEFAA /* FBSDKShareDialogMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FE6EB1A3A06BF08C38149DE373F02D6 /* FBSDKShareDialogMode.h */; settings = {ATTRIBUTES = (Public, ); }; }; C9A879CF614BAB80706EA977904B0BB9 /* FBSDKShareError.m in Sources */ = {isa = PBXBuildFile; fileRef = 410531D8C1D4D3F7F42F12F7ED9D9951 /* FBSDKShareError.m */; }; C9B57D939AB4480C7A93482A12D87C4B /* FBSDKLoginCompletion.h in Headers */ = {isa = PBXBuildFile; fileRef = CAA129C29843E84557F30FA22E3BD93C /* FBSDKLoginCompletion.h */; settings = {ATTRIBUTES = (Project, ); }; }; C9BD44D9DC9D9E459BCB805875DC2306 /* FBSDKLikeActionController.m in Sources */ = {isa = PBXBuildFile; fileRef = A0EC3FABD68D980F29E217F43B8E7531 /* FBSDKLikeActionController.m */; }; CAC483EF637FB4A2C2E2FC75BA631B87 /* AFAutoPurgingImageCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 64BC906D3B3F04EF99E4F99888D14BFD /* AFAutoPurgingImageCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; CB67930A4314E6E46A903F3489EB7608 /* FBSDKShareOpenGraphContent.h in Headers */ = {isa = PBXBuildFile; fileRef = 373558AB5D05183762C694E29BDD49DF /* FBSDKShareOpenGraphContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; CDB7896D8D7B6198A8930A88526BAE3C /* FBSDKAppEventsDeviceInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = B7FB3070FF4872061FB66A25E85BF7CE /* FBSDKAppEventsDeviceInfo.h */; settings = {ATTRIBUTES = (Project, ); }; }; CDE764570B1C9BED83BD2F23533A3097 /* BFAppLinkReturnToRefererView.h in Headers */ = {isa = PBXBuildFile; fileRef = CC141E7006767F72BFBBA10C3EF7924D /* BFAppLinkReturnToRefererView.h */; settings = {ATTRIBUTES = (Public, ); }; }; CDECDF26D5914B5118DA15DC06FABFDF /* FBSDKShareLinkContent+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = B09B5367079E398942D665788719ED06 /* FBSDKShareLinkContent+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; CE0233C459CA5BF1F081257EB3655004 /* FBSDKLikeObjectType.m in Sources */ = {isa = PBXBuildFile; fileRef = E76E62E37B5FC6CA07F3E99A07FF64FA /* FBSDKLikeObjectType.m */; }; CFA8D6B529A0EBFF0316F2629AB2556E /* AFImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 2257964A3F9373499E0DA0099EEB778E /* AFImageDownloader.m */; }; CFDAC1FC6D948576796D48F01601D00B /* FBSDKShareDialog.h in Headers */ = {isa = PBXBuildFile; fileRef = C43A78A5372F75EB57D137461A709703 /* FBSDKShareDialog.h */; settings = {ATTRIBUTES = (Public, ); }; }; D05E51C8CEED91610DDE599FA220A58F /* FBSDKGameRequestDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = 5B23364F56723A25F90AABD8FF435C50 /* FBSDKGameRequestDialog.m */; }; D20BAF8A10A6F2B9E2A7B6DD82C056F6 /* FBSDKShareOpenGraphObject.h in Headers */ = {isa = PBXBuildFile; fileRef = BF6124C6F3541980379CB23661270EE2 /* FBSDKShareOpenGraphObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; D347F65DE4E6C432B5182A7376869D0C /* FBSDKShareConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = B08AC453B44CE1E8B261D54410E3F0B9 /* FBSDKShareConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; D34DCA75165C72964785F46234C55617 /* FBSDKCoreKit+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 50795EF8289E03FFD8A3E6F9B76FAE25 /* FBSDKCoreKit+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; D3B8A9EFB1AFEFE16BE8C7F4FE410F20 /* FBSDKSendButton.m in Sources */ = {isa = PBXBuildFile; fileRef = CAF2E3BCF8134ECFEBAD9A4DAB39EB06 /* FBSDKSendButton.m */; }; D47ED08B9196AE9B0A1D681207FF5789 /* FBSDKAccessTokenCacheV3_17.m in Sources */ = {isa = PBXBuildFile; fileRef = FAA41E1A3AB2CDE00AC2A074261AA18B /* FBSDKAccessTokenCacheV3_17.m */; }; D526206FE0167F9A3C4292B0F3E4F337 /* FBSDKUIUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B74E1FBB9A29E0DA697CE9244BA863E /* FBSDKUIUtility.h */; settings = {ATTRIBUTES = (Project, ); }; }; D54C8902B21F00E3539FC2E2A1645077 /* Pods-PotterPicsUITests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 51E7B36DB5767A90185B3AAE2038FB81 /* Pods-PotterPicsUITests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; D5A52B04EF08F7245C8D6B9E42BB906A /* FBSDKShareDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 296F6C441E737F5D403A52D4A6659679 /* FBSDKShareDefines.h */; settings = {ATTRIBUTES = (Project, ); }; }; D5BA74145C0DD3D7C2146DB73A378CB5 /* FBSDKBoltsMeasurementEventListener.m in Sources */ = {isa = PBXBuildFile; fileRef = A294C9820557DFCF402698559CD8EEFE /* FBSDKBoltsMeasurementEventListener.m */; }; D6ABDFF81E566FFECF367E42C6333D79 /* MBProgressHUD-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D10491C882280228A0100282683FB39 /* MBProgressHUD-dummy.m */; }; D711EBBB664A6ED7779B62B8710FB875 /* MBProgressHUD-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = A2526D92C805D78393CCA38F2F559B1A /* MBProgressHUD-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; D733DF9E662E26A7E088F42481BD4226 /* SwiftyJSON-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C5FC5BC8940E982554939347A24EFFF /* SwiftyJSON-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; D80E3A1971AF7FDCE82F3241BA53B59B /* FBSDKLoginKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 5B08B8F4C78247FC48A72B438A6CBBB6 /* FBSDKLoginKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; D8E3EF0B890201C0DD54E9CF5527F88C /* BFAppLinkTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = B11CD9C22ABED727DBA3C605481D722B /* BFAppLinkTarget.h */; settings = {ATTRIBUTES = (Public, ); }; }; D96FC2C9AB1D0FB9891F97920F5C5059 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70827AF45BE2EBCD723C40A04D7ECB46 /* Foundation.framework */; }; D9B2E2CE9E2DF615FE197377486BB214 /* BFCancellationTokenRegistration.m in Sources */ = {isa = PBXBuildFile; fileRef = 18232EEB415F885FD50804B08FAA7118 /* BFCancellationTokenRegistration.m */; }; D9F4E833E37B611B432F6B5D7072DDA2 /* UIProgressView+AFNetworking.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A032B4D7063E2F7F39E624712161E3C /* UIProgressView+AFNetworking.h */; settings = {ATTRIBUTES = (Public, ); }; }; DD71FF7082841E53507DF58A816EF24A /* FBSDKAppEventsState.h in Headers */ = {isa = PBXBuildFile; fileRef = 10DB4B38151CCF261FB5B725FC3C1759 /* FBSDKAppEventsState.h */; settings = {ATTRIBUTES = (Project, ); }; }; DFC3DF985B5065268315681B81A235DE /* BFURL.h in Headers */ = {isa = PBXBuildFile; fileRef = C5CD1E73DFD39E5D339E021817B9DA2F /* BFURL.h */; settings = {ATTRIBUTES = (Public, ); }; }; DFF1485B513E216D515C7B872145EC0A /* FBSDKButton+Subclass.h in Headers */ = {isa = PBXBuildFile; fileRef = DBB02E482BD1DF480E6409A036C5FC12 /* FBSDKButton+Subclass.h */; settings = {ATTRIBUTES = (Project, ); }; }; DFFA215EEAA8DDBD540076927535275C /* AFURLRequestSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = ACA8F295B43D163B70210857413B38D2 /* AFURLRequestSerialization.m */; }; E0095D397882896F3871DC2E380152D1 /* FBSDKSharePhotoContent.h in Headers */ = {isa = PBXBuildFile; fileRef = F76024F6A89EEA91F3F7CE0033C71B96 /* FBSDKSharePhotoContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; E0D4045AC4C1B41917FCA23A042D18B2 /* AFHTTPSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 442A884AB0F3C44425BEF2E15FD50E0C /* AFHTTPSessionManager.m */; }; E0D8CC2D833E62302F30B2FE5DACC3C9 /* FBSDKAccessTokenCacheV3_21.h in Headers */ = {isa = PBXBuildFile; fileRef = AE89EBA20669231D87F412BE0080CF31 /* FBSDKAccessTokenCacheV3_21.h */; settings = {ATTRIBUTES = (Project, ); }; }; E2538D972FF83B2B65506DFEF1DBF704 /* FBSDKShareLinkContent.h in Headers */ = {isa = PBXBuildFile; fileRef = 401B98C26CCE7BAC7B06C52BF65218A3 /* FBSDKShareLinkContent.h */; settings = {ATTRIBUTES = (Public, ); }; }; E2FF4576C5740EDF6E0E2A62495A9E5C /* FBSDKLikeControl+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BF80BA302324AC6AEF69A593C8DEF28 /* FBSDKLikeControl+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; E33C52610245504BC91ADA56E67826B3 /* FBSDKSharingButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F4DEE2AB3EC71BDEDF7872D4DFBAD6B /* FBSDKSharingButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; E39ED3657FEE321A20AE105D8BE1A340 /* BFAppLinkNavigation.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B81D75978055EB91A7F320BEA156D53 /* BFAppLinkNavigation.h */; settings = {ATTRIBUTES = (Public, ); }; }; E3AE71AF80F5D8A842E69202847A0710 /* FBSDKAppInviteContent.m in Sources */ = {isa = PBXBuildFile; fileRef = 320EC985715765292F038461B143AAD1 /* FBSDKAppInviteContent.m */; }; E3F3CBC9723823D11DCF58CDFA25AA77 /* BFTask.m in Sources */ = {isa = PBXBuildFile; fileRef = FA00C1C3274A7E11FF27A45C4CE750C2 /* BFTask.m */; }; E405BE065D3907EBEA6CA987F7B28970 /* FBSDKBridgeAPIProtocolNativeV1.h in Headers */ = {isa = PBXBuildFile; fileRef = CD8846B8FF6EE2E1CA42E78339D4AA6D /* FBSDKBridgeAPIProtocolNativeV1.h */; settings = {ATTRIBUTES = (Project, ); }; }; E506115FCDC9F77D14E1C78466568D4C /* FBSDKErrorRecoveryConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = C6D6274B3F544F77220B92171CF9F919 /* FBSDKErrorRecoveryConfiguration.m */; }; E7988678C81F7CCB95D239375FC6986D /* AFNetworking.h in Headers */ = {isa = PBXBuildFile; fileRef = 718B950C70F3134649C4AFE37F4F807F /* AFNetworking.h */; settings = {ATTRIBUTES = (Public, ); }; }; E89B7AA1C8A33AA609D3377A2146F960 /* FBSDKGraphRequestConnection+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = A24D533C6F87D953E9D4167CE6CCBD31 /* FBSDKGraphRequestConnection+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; E946BACAA3326E2D9FC5C3BDCE897918 /* FBSDKErrorConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 6987C863B1CEBBD311F5CE3FB5DAEF3E /* FBSDKErrorConfiguration.h */; settings = {ATTRIBUTES = (Project, ); }; }; E9E40449AFDF5DCD1B0E16F2993DE940 /* FBSDKAppEvents+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = AC1EF366A578B87EA50F8772B5F8FB3F /* FBSDKAppEvents+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; EA92883DCDC909379715AAA47109F2B8 /* FBSDKApplicationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = E327066FFF0F45B24255C9027C06334F /* FBSDKApplicationDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; EAF4063C5D3C8C1AE3C7513759BA9D0B /* MBProgressHUD.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CBF89B1639B480078C319B893452776 /* MBProgressHUD.h */; settings = {ATTRIBUTES = (Public, ); }; }; EC515D6442B6FDC3C7E12FDDFAABF756 /* FBSDKBridgeAPICrypto.m in Sources */ = {isa = PBXBuildFile; fileRef = 67B6CEFEAC287216153D11E9CA2AB080 /* FBSDKBridgeAPICrypto.m */; }; EC7CADE416A78A1CD6936018A6695126 /* AFNetworking-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 78E89BE08BF96B56B9C8BB7C1A0134E0 /* AFNetworking-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; EDD254449CD8FF482448772C604D758A /* FBSDKLoginKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 85DA2F1CED9B84902AB69D909A20804A /* FBSDKLoginKit-dummy.m */; }; EE36AB0C7B5DAF57B04542DFC5A02F92 /* FBSDKProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A45B69EB5BAB1BBE74F78F69B839C90 /* FBSDKProfile.h */; settings = {ATTRIBUTES = (Public, ); }; }; EE5B930F9F26CBF2093E59FAF8DFAA2C /* FBSDKURLSessionTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 16E1CFB4C583CB72BEA38953BF63E291 /* FBSDKURLSessionTask.m */; }; F12275031D131B6A70A0195761B1C7CA /* FBSDKVideoUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = BEDB9F06356271BE836C1075461A2E5F /* FBSDKVideoUploader.m */; }; F12AF773342F9806BE3A3E4BBAE8EE2C /* FBSDKApplicationDelegate+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = C9AECD149DAA9CBBE44D0552225C4FFF /* FBSDKApplicationDelegate+Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; F1375F74031F3731A3D9F42A66A6327D /* FBSDKLikeButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D2BCE0C3DC1E7FB0BE6E02ECEC19F2B /* FBSDKLikeButton.m */; }; F294B75539C74EDB0B55D2350874A225 /* FBSDKLoginButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 9D47EAC837C24B66E7DF055BB3F46694 /* FBSDKLoginButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; F36A25CB7A3F6373D55CC4183C639E86 /* FBSDKCoreKit-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 60BA4F2856A8EE256F5FD5D10DB27395 /* FBSDKCoreKit-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; F42198560289E76E8550D33440165462 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70827AF45BE2EBCD723C40A04D7ECB46 /* Foundation.framework */; }; F4F8771CF43018CF648DF325FD6546E5 /* FBSDKSharePhoto.h in Headers */ = {isa = PBXBuildFile; fileRef = C6A497B03B5633DDD9411F414F9F6373 /* FBSDKSharePhoto.h */; settings = {ATTRIBUTES = (Public, ); }; }; F5862151DF7C94B129A3917F880F9985 /* FBSDKContainerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 13EB02F3205B2D58148E051D3FE0495C /* FBSDKContainerViewController.h */; settings = {ATTRIBUTES = (Project, ); }; }; F5F9597A3167E2AE7937E6CF4BD09AB8 /* FBSDKLoginCompletion.m in Sources */ = {isa = PBXBuildFile; fileRef = A2F3964515C2693109855A15979E3DE9 /* FBSDKLoginCompletion.m */; }; F66676CD9BBA00D2169C4224BDE79829 /* FBSDKGraphRequestBody.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C02168CB9621997A0F79BB3489C79BD /* FBSDKGraphRequestBody.h */; settings = {ATTRIBUTES = (Project, ); }; }; F6878FC9541012F94978CF46070D1301 /* FBSDKAccessTokenCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 500C49C75006CC6F013D43A00F9E43BA /* FBSDKAccessTokenCache.h */; settings = {ATTRIBUTES = (Project, ); }; }; F6A635CE6CDD2D57711CCEC692128382 /* FBSDKShareButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C3C0A132E0782A93A180B945919D8AB /* FBSDKShareButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; F7581524FBA63576F76650BAC9B15C04 /* FBSDKLoginKit-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 205386F477BF64F1FF7054572AB0EC3C /* FBSDKLoginKit-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; F759176BF99FB3C01BA3EEE8C6A40D2A /* BFAppLink.h in Headers */ = {isa = PBXBuildFile; fileRef = 55F1ED0FA41DA559ACA70075456C78E0 /* BFAppLink.h */; settings = {ATTRIBUTES = (Public, ); }; }; F83D82020F9347F75495D09AA4F295AE /* BFMeasurementEvent_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 15B643D9CA5F7D4DF2406B76D08469DA /* BFMeasurementEvent_Internal.h */; settings = {ATTRIBUTES = (Project, ); }; }; F968CDDC661EA2C602666CE712CEB7A4 /* FBSDKShareVideo.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CC1A69AD010CB80F7ECC513E4343904 /* FBSDKShareVideo.h */; settings = {ATTRIBUTES = (Public, ); }; }; F9B9A77D836E30A07D84E3C3AB5FAE7A /* FBSDKVideoUploader.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1F9F6B6D37F39C85DB019B87701253 /* FBSDKVideoUploader.h */; settings = {ATTRIBUTES = (Project, ); }; }; F9BA81C41C3DDABA6BEC897850E45D8D /* _FBSDKLoginRecoveryAttempter.m in Sources */ = {isa = PBXBuildFile; fileRef = 40A0330BAC9BB3AA5026B8F00AC08079 /* _FBSDKLoginRecoveryAttempter.m */; }; FA158C22016D2FC0737B76CFDDB52D0C /* FBSDKLikeDialog.m in Sources */ = {isa = PBXBuildFile; fileRef = 0DAF20656ED36E53470D2DBF6D0FBD4C /* FBSDKLikeDialog.m */; }; FAE007ED5F7CAEB03A3B3EF38A9A2749 /* FBSDKAppLinkResolver.m in Sources */ = {isa = PBXBuildFile; fileRef = 0349FF89F9C33365619790DEDBA08F70 /* FBSDKAppLinkResolver.m */; }; FAFF0338DA0F7C773CE1E2813A9AD99E /* FBSDKAppEventsUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 285EA1C5DE8FD4B3F7946555AA602481 /* FBSDKAppEventsUtility.m */; }; FBB79DC1BDCDDEA2FA5A5689B1F803EB /* FBSDKBridgeAPIResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 0D2BDE42CEA153BF1D92D881993DE575 /* FBSDKBridgeAPIResponse.h */; settings = {ATTRIBUTES = (Project, ); }; }; FBFC84F1732ECA4AC061AE15DB5F8404 /* FBSDKAccessTokenCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 1DA1AF8EE4E1991D2A0DF7BCD823E758 /* FBSDKAccessTokenCache.m */; }; FC4664DAFACB0D557FED3B200AC6FE4F /* FBSDKMaleSilhouetteIcon.m in Sources */ = {isa = PBXBuildFile; fileRef = 678FFAFC127E69071CB03622EA32A27C /* FBSDKMaleSilhouetteIcon.m */; }; FC7F0A1FFB2641FAB705A0CF9EFC1303 /* FBSDKShareKit.h in Headers */ = {isa = PBXBuildFile; fileRef = F4F30481231EF67BD4487BBF6C5D1CB1 /* FBSDKShareKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; FD37427BF19B0520BCC86974E7FB9192 /* FBSDKColor.h in Headers */ = {isa = PBXBuildFile; fileRef = C93EDE5838549A4DDAF2016C59DD7FA0 /* FBSDKColor.h */; settings = {ATTRIBUTES = (Project, ); }; }; FD395FC2A672F51DA6B445D69708FF6E /* FBSDKSystemAccountStoreAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = B29476575BC6F9F5CFB5F8DAF9604531 /* FBSDKSystemAccountStoreAdapter.m */; }; FD7525FCB49FB135D59559C8A7D13D65 /* FBSDKLikeButtonPopWAV.m in Sources */ = {isa = PBXBuildFile; fileRef = 07EF944EFB6018776E00F7FA75BF0D01 /* FBSDKLikeButtonPopWAV.m */; }; FF7EBF74284B1B1DEDD8687753467CA4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 70827AF45BE2EBCD723C40A04D7ECB46 /* Foundation.framework */; }; FFE20D61C3C5166CE50B2FA4BE2BC271 /* FBSDKShareOpenGraphObject.m in Sources */ = {isa = PBXBuildFile; fileRef = C18451DC83C885C1446AE0C026601489 /* FBSDKShareOpenGraphObject.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 04885811A1E85B2610448FED0600982B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; remoteGlobalIDString = 6EDC37F3FA92533C6AC3562458AA91F1; remoteInfo = FBSDKLoginKit; }; 10883D98BB53A5B0A4EF5071471F6244 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; remoteGlobalIDString = 1C3436CEA5C3D39764C5F54374794ECB; remoteInfo = AFNetworking; }; 1A8A0E3BE6FC4BDD4E2FFCAAB1F20283 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; remoteGlobalIDString = 9D0F2E5EA1B46A5D72FFD42B0B39DBBC; remoteInfo = Bolts; }; 270EA59E24CAB44BDCA7DB0DA7A6F1D1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; remoteGlobalIDString = DBA6001481CEA0EBA031CC5C94508FAA; remoteInfo = MBProgressHUD; }; 46FA7B947B9FCF27662BE469AFF096FB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; remoteGlobalIDString = 30D7FCF8072F5D59AE1C98D94F9A6EC9; remoteInfo = FBSDKShareKit; }; 4C73BEFB46A6D4619DFC813CAFC63D53 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; remoteGlobalIDString = 9D0F2E5EA1B46A5D72FFD42B0B39DBBC; remoteInfo = Bolts; }; 5C144475AA961A86DFD9B6E49984B8EA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; remoteGlobalIDString = 2E303C3CE7513908EE880D9CA833AFAE; remoteInfo = FBSDKCoreKit; }; A12C5FB126E9FA1F5F9109342191175A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; remoteGlobalIDString = 5DA0B374CB34642F0B891ACE7F3ED50F; remoteInfo = SwiftyJSON; }; C13E21E46BB08E336B9E99E2F4692737 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; remoteGlobalIDString = 9D0F2E5EA1B46A5D72FFD42B0B39DBBC; remoteInfo = Bolts; }; CFD970D7ADCC55CB11A7402ECAE02E55 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; remoteGlobalIDString = 2E303C3CE7513908EE880D9CA833AFAE; remoteInfo = FBSDKCoreKit; }; DFB7D8638BEFDCC4CCF33BEB67F1B89B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; remoteGlobalIDString = 9D0F2E5EA1B46A5D72FFD42B0B39DBBC; remoteInfo = Bolts; }; ED9B8F8F8F84D09DE8A86E81383E7B0D /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; remoteGlobalIDString = 2E303C3CE7513908EE880D9CA833AFAE; remoteInfo = FBSDKCoreKit; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 00676AF610DA21956BC730C01D7298FD /* FBSDKShareVideo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKShareVideo.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareVideo.m; sourceTree = ""; }; 02CACB6F83DC041FD72EAB30A93637E5 /* FIRInstanceID.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstanceID.h; path = Sources/FIRInstanceID.h; sourceTree = ""; }; 0349FF89F9C33365619790DEDBA08F70 /* FBSDKAppLinkResolver.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAppLinkResolver.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKAppLinkResolver.m; sourceTree = ""; }; 050BDEAD1916698E214AFB26A79288B0 /* FBSDKGraphRequestMetadata.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKGraphRequestMetadata.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestMetadata.h; sourceTree = ""; }; 0705221C472B862B8D97A7E30C67C5C3 /* FBSDKGraphRequest+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKGraphRequest+Internal.h"; path = "FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequest+Internal.h"; sourceTree = ""; }; 071D9291B24AAEC6A06D97DC10C701E7 /* FBSDKTooltipView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKTooltipView.h; path = FBSDKLoginKit/FBSDKLoginKit/FBSDKTooltipView.h; sourceTree = ""; }; 0755A353614ED13BF9C7DFF951D0E953 /* AFNetworking.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = AFNetworking.modulemap; sourceTree = ""; }; 07EF944EFB6018776E00F7FA75BF0D01 /* FBSDKLikeButtonPopWAV.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLikeButtonPopWAV.m; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeButtonPopWAV.m; sourceTree = ""; }; 092A7AF28E09B340E2144F1A7C3DB11D /* FBSDKShareKit.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FBSDKShareKit.xcconfig; sourceTree = ""; }; 09CCCCC909E043460B5C164D04C39DCE /* FBSDKLoginCompletion+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKLoginCompletion+Internal.h"; path = "FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion+Internal.h"; sourceTree = ""; }; 09F160AC488F6438F48A20FA5494D9D5 /* FirebaseDatabase.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseDatabase.framework; path = Frameworks/FirebaseDatabase.framework; sourceTree = ""; }; 09FCBDC873BEAA3952579FB53590F48F /* FBSDKLoginError.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLoginError.h; path = FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.h; sourceTree = ""; }; 0A076680535D6C630B144572313F884B /* FBSDKWebDialogView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKWebDialogView.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialogView.h; sourceTree = ""; }; 0A125CDAF09D1BA4CC6380D652520C21 /* BFMeasurementEvent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BFMeasurementEvent.m; path = Bolts/iOS/BFMeasurementEvent.m; sourceTree = ""; }; 0A2D4836EB6721814767F5F092407237 /* Bolts.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Bolts.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 0A58FC28910ED59F914BAC490A56EAEB /* GoogleUtilities.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleUtilities.framework; path = Frameworks/frameworks/GoogleUtilities.framework; sourceTree = ""; }; 0A7D9A300470671F595569D849059CAA /* SwiftyJSON-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftyJSON-prefix.pch"; sourceTree = ""; }; 0AD5FFE35DAAACBC54403D264F0BE44C /* UIImageView+AFNetworking.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImageView+AFNetworking.m"; path = "UIKit+AFNetworking/UIImageView+AFNetworking.m"; sourceTree = ""; }; 0D2BDE42CEA153BF1D92D881993DE575 /* FBSDKBridgeAPIResponse.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKBridgeAPIResponse.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.h; sourceTree = ""; }; 0DAF20656ED36E53470D2DBF6D0FBD4C /* FBSDKLikeDialog.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLikeDialog.m; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeDialog.m; sourceTree = ""; }; 0DF2B5FCF45BF2A41A287E6BB8214F99 /* FBSDKAppEvents.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAppEvents.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKAppEvents.h; sourceTree = ""; }; 0E1FB642714DF285B00B1FBC79ABCDA8 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 0E573958B4A3ED69E35F873DEF94A025 /* FBSDKMath.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKMath.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMath.m; sourceTree = ""; }; 10DB4B38151CCF261FB5B725FC3C1759 /* FBSDKAppEventsState.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAppEventsState.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsState.h; sourceTree = ""; }; 10E426D732CEC0BDD792FCFFDFC725C3 /* Bolts.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Bolts.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 124B31DDC1B0856244E71C50AF92CF6B /* FBSDKUtility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKUtility.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKUtility.h; sourceTree = ""; }; 13EB02F3205B2D58148E051D3FE0495C /* FBSDKContainerViewController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKContainerViewController.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKContainerViewController.h; sourceTree = ""; }; 14FF537E964BE5C76DF4B233527AD0CF /* FBSDKSharePhoto.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKSharePhoto.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKSharePhoto.m; sourceTree = ""; }; 15316CB5F2E0A74B37A4B65C34168EAD /* FBSDKShareOpenGraphAction.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKShareOpenGraphAction.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphAction.m; sourceTree = ""; }; 15B643D9CA5F7D4DF2406B76D08469DA /* BFMeasurementEvent_Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFMeasurementEvent_Internal.h; path = Bolts/iOS/Internal/BFMeasurementEvent_Internal.h; sourceTree = ""; }; 16E1CFB4C583CB72BEA38953BF63E291 /* FBSDKURLSessionTask.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKURLSessionTask.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKURLSessionTask.m; sourceTree = ""; }; 1798F04401CF6DDA8F03E7D82898E416 /* FBSDKShareKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKShareKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 179F15CC373EBC2355183B3C2136DE83 /* FBSDKURLConnection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKURLConnection.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKURLConnection.h; sourceTree = ""; }; 17A80EE44E29E6E08FB9D28A2EBF7B4D /* FBSDKShareVideoContent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareVideoContent.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareVideoContent.h; sourceTree = ""; }; 17CD4565C4615C5E205842C287BE17C7 /* Pods-PotterPicsTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-PotterPicsTests-acknowledgements.markdown"; sourceTree = ""; }; 17F4407284C3041C1FB4B7B9946068A6 /* FBSDKLoginManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLoginManager.m; path = FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.m; sourceTree = ""; }; 18232EEB415F885FD50804B08FAA7118 /* BFCancellationTokenRegistration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BFCancellationTokenRegistration.m; path = Bolts/Common/BFCancellationTokenRegistration.m; sourceTree = ""; }; 1A542E25A53E3F8A0E0CF2B68F2F0B29 /* FBSDKMonotonicTime.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKMonotonicTime.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMonotonicTime.m; sourceTree = ""; }; 1B28531CB7D39F0479D319C3355285B2 /* FBSDKBridgeAPIProtocolWebV2.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKBridgeAPIProtocolWebV2.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV2.m; sourceTree = ""; }; 1B74E1FBB9A29E0DA697CE9244BA863E /* FBSDKUIUtility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKUIUtility.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKUIUtility.h; sourceTree = ""; }; 1BD23CFB4A0B2C21AB6643701F7A53D7 /* _FBSDKTemporaryErrorRecoveryAttempter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _FBSDKTemporaryErrorRecoveryAttempter.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/_FBSDKTemporaryErrorRecoveryAttempter.h; sourceTree = ""; }; 1BD82AD0020AF025735DBEE92D90EC9B /* AFSecurityPolicy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = AFSecurityPolicy.m; path = AFNetworking/AFSecurityPolicy.m; sourceTree = ""; }; 1D9675CE2687A056DD6C5B6D2FE1612F /* SwiftyJSON.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SwiftyJSON.xcconfig; sourceTree = ""; }; 1DA1AF8EE4E1991D2A0DF7BCD823E758 /* FBSDKAccessTokenCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAccessTokenCache.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCache.m; sourceTree = ""; }; 1E415A3350D8CF5BECE3063DDAA0BE6D /* FBSDKShareOpenGraphAction.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareOpenGraphAction.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphAction.h; sourceTree = ""; }; 1F71BFA8EDBB8BE5A3A1072C32B5DD3A /* Pods-PotterPicsTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-PotterPicsTests-dummy.m"; sourceTree = ""; }; 205386F477BF64F1FF7054572AB0EC3C /* FBSDKLoginKit-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FBSDKLoginKit-umbrella.h"; sourceTree = ""; }; 20CE7239B1D2FDDB8288044920159A7D /* UIProgressView+AFNetworking.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIProgressView+AFNetworking.m"; path = "UIKit+AFNetworking/UIProgressView+AFNetworking.m"; sourceTree = ""; }; 2257964A3F9373499E0DA0099EEB778E /* AFImageDownloader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = AFImageDownloader.m; path = "UIKit+AFNetworking/AFImageDownloader.m"; sourceTree = ""; }; 234EEAD5437409F3A7C37D7ADFB11D39 /* FBSDKShareOpenGraphContent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKShareOpenGraphContent.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphContent.m; sourceTree = ""; }; 23A27F6D575E25C312B65E8A9904B718 /* FBSDKLikeActionControllerCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLikeActionControllerCache.h; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionControllerCache.h; sourceTree = ""; }; 23D3CB6E9A2578A033EBBD68B00CC950 /* FBSDKCoreKit.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FBSDKCoreKit.xcconfig; sourceTree = ""; }; 24B9BC43CDA1316D5C29C2814F5B936F /* FBSDKViewImpressionTracker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKViewImpressionTracker.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKViewImpressionTracker.h; sourceTree = ""; }; 24E2DAB6E1D48DC025ACCFE8FACEE3B7 /* GoogleNetworkingUtilities.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleNetworkingUtilities.framework; path = Frameworks/frameworks/GoogleNetworkingUtilities.framework; sourceTree = ""; }; 26053F1FAB9B2DA8CE98D25FD7F7F394 /* FBSDKErrorRecoveryConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKErrorRecoveryConfiguration.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorRecoveryConfiguration.h; sourceTree = ""; }; 26FED6B2BD5A31C35B34A0BC3F52A09F /* FBSDKLoginKit.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = FBSDKLoginKit.modulemap; sourceTree = ""; }; 285EA1C5DE8FD4B3F7946555AA602481 /* FBSDKAppEventsUtility.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAppEventsUtility.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsUtility.m; sourceTree = ""; }; 289E794C1F5558F52ACC04E4BFE43EB8 /* FBSDKDialogConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKDialogConfiguration.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKDialogConfiguration.h; sourceTree = ""; }; 28EB58143BEE37AB589682ABF4EC785D /* FBSDKCoreKit-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FBSDKCoreKit-prefix.pch"; sourceTree = ""; }; 296C259F6F86ABD6D4D15162E262E0B1 /* FBSDKLikeActionController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLikeActionController.h; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionController.h; sourceTree = ""; }; 296E51807D61C9A541B3F4E81594BC16 /* FBSDKShareOpenGraphValueContainer+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKShareOpenGraphValueContainer+Internal.h"; path = "FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareOpenGraphValueContainer+Internal.h"; sourceTree = ""; }; 296F6C441E737F5D403A52D4A6659679 /* FBSDKShareDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareDefines.h; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareDefines.h; sourceTree = ""; }; 2993229BA329377C244F962B75E1414E /* FBSDKWebDialog.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKWebDialog.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialog.m; sourceTree = ""; }; 2A032B4D7063E2F7F39E624712161E3C /* UIProgressView+AFNetworking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIProgressView+AFNetworking.h"; path = "UIKit+AFNetworking/UIProgressView+AFNetworking.h"; sourceTree = ""; }; 2A45B69EB5BAB1BBE74F78F69B839C90 /* FBSDKProfile.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKProfile.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.h; sourceTree = ""; }; 2C643A8A0CDCBDC00ECAB15922C9DA24 /* FBSDKAccessTokenCacheV4.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAccessTokenCacheV4.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV4.h; sourceTree = ""; }; 2CC1A69AD010CB80F7ECC513E4343904 /* FBSDKShareVideo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareVideo.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareVideo.h; sourceTree = ""; }; 2CDA368B9F67E0B774EA1AC6F3142A78 /* SwiftyJSON-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SwiftyJSON-dummy.m"; sourceTree = ""; }; 2E1AB7D493DCC2425913A6C4876BE077 /* BFAppLink.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BFAppLink.m; path = Bolts/iOS/BFAppLink.m; sourceTree = ""; }; 30277D302B666A9583A67ADEE4829C79 /* FBSDKAppInviteContent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAppInviteContent.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKAppInviteContent.h; sourceTree = ""; }; 302F33D66A77991641D9EABE527E2020 /* FBSDKSystemAccountStoreAdapter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKSystemAccountStoreAdapter.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSystemAccountStoreAdapter.h; sourceTree = ""; }; 30604910CF1BC094BCC4758C0D9FFAC1 /* AFNetworking.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = AFNetworking.xcconfig; sourceTree = ""; }; 3104FCCA4195E114CCF8D258D1081BDE /* GoogleSymbolUtilities.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleSymbolUtilities.framework; path = Frameworks/frameworks/GoogleSymbolUtilities.framework; sourceTree = ""; }; 31381C7B24A5039BBB6CCF74EB2C2EF5 /* FBSDKMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKMacros.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKMacros.h; sourceTree = ""; }; 317894220C20B4473C3E8A4ECCFEA2C0 /* FBSDKShareKit-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FBSDKShareKit-prefix.pch"; sourceTree = ""; }; 320EC985715765292F038461B143AAD1 /* FBSDKAppInviteContent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAppInviteContent.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKAppInviteContent.m; sourceTree = ""; }; 322BD0C3BEA3B1E5C0531B171EB81035 /* FBSDKShareUtility.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKShareUtility.m; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.m; sourceTree = ""; }; 325A848210CDC11F2737F04B83826DB3 /* AFURLResponseSerialization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = AFURLResponseSerialization.m; path = AFNetworking/AFURLResponseSerialization.m; sourceTree = ""; }; 3368C70225DA4184943E1A027F4C750E /* FBSDKLogo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLogo.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKLogo.m; sourceTree = ""; }; 338833E9EEBA4312501F310EA0F85CFD /* FBSDKSharing.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKSharing.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKSharing.h; sourceTree = ""; }; 3419D37B887BC1CE701D49ED228E9436 /* UIImageView+AFNetworking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImageView+AFNetworking.h"; path = "UIKit+AFNetworking/UIImageView+AFNetworking.h"; sourceTree = ""; }; 3492694E100163219853B812C221B158 /* FirebaseAnalytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseAnalytics.framework; path = Frameworks/frameworks/FirebaseAnalytics.framework; sourceTree = ""; }; 355EAFC2BF57DCFF081CC4F62BEFA490 /* FBSDKLoginManagerLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLoginManagerLogger.m; path = FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.m; sourceTree = ""; }; 3564E4DE0349A19993E8610CC040CC9A /* FBSDKGraphRequestConnection.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKGraphRequestConnection.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphRequestConnection.m; sourceTree = ""; }; 356DB9AFF70A7328E4141C2B7805D5C2 /* FBSDKShareVideoContent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKShareVideoContent.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareVideoContent.m; sourceTree = ""; }; 3600C3929B2E962EBC7189EC010FC34B /* FBSDKShareMediaContent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKShareMediaContent.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareMediaContent.m; sourceTree = ""; }; 362743812A3C9D8AF7C3140A261E9CD8 /* FBSDKLoginKit-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FBSDKLoginKit-prefix.pch"; sourceTree = ""; }; 373558AB5D05183762C694E29BDD49DF /* FBSDKShareOpenGraphContent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareOpenGraphContent.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphContent.h; sourceTree = ""; }; 37B9FAD0B18BDDA91409715A1166C5CB /* FBSDKCoreKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3818796F76375FAF3283D90B9B1B6172 /* FBSDKInternalUtility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKInternalUtility.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.h; sourceTree = ""; }; 391526EE3F5F71D24870BE3950952E60 /* Pods-PotterPicsUITests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-PotterPicsUITests-acknowledgements.plist"; sourceTree = ""; }; 394DEC0187D9C4DD3025FCBDEE64E147 /* FBSDKTriStateBOOL.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKTriStateBOOL.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.h; sourceTree = ""; }; 3ABB7E09BE20FAE0E0F42F34FBD487CC /* BFAppLinkReturnToRefererView_Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFAppLinkReturnToRefererView_Internal.h; path = Bolts/iOS/Internal/BFAppLinkReturnToRefererView_Internal.h; sourceTree = ""; }; 3B7482B2E7186DBE28DA80B8BBEFE69D /* FBSDKLikeControl.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLikeControl.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKLikeControl.h; sourceTree = ""; }; 3BA89B7CB74DAA591F92581FD6474C01 /* FBSDKAppInviteDialog.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAppInviteDialog.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKAppInviteDialog.m; sourceTree = ""; }; 3C5FC5BC8940E982554939347A24EFFF /* SwiftyJSON-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SwiftyJSON-umbrella.h"; sourceTree = ""; }; 3D46190A40A28D9477301E0E9F818EA8 /* FBSDKTimeSpentData.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKTimeSpentData.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKTimeSpentData.m; sourceTree = ""; }; 3D9DB3883D692B0606CD7C950B471957 /* FBSDKTestUsersManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKTestUsersManager.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKTestUsersManager.m; sourceTree = ""; }; 3DF483014F5F35035670878A8FEC5C0D /* FBSDKBridgeAPIProtocolWebV2.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKBridgeAPIProtocolWebV2.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV2.h; sourceTree = ""; }; 3E5817463D8E6C05AE18A2727EE775AB /* FBSDKErrorRecoveryAttempter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKErrorRecoveryAttempter.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/FBSDKErrorRecoveryAttempter.h; sourceTree = ""; }; 3EA26D4657F56ED7C7AD3C7CF40938DF /* FBSDKConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKConstants.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKConstants.h; sourceTree = ""; }; 3F727643E3C6321D531B62D7A265941C /* FBSDKAudioResourceLoader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAudioResourceLoader.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAudioResourceLoader.h; sourceTree = ""; }; 3FD407E320BE66588168BEB8DAFB77B8 /* FBSDKAppEventsStateManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAppEventsStateManager.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsStateManager.m; sourceTree = ""; }; 3FE115C8BE13A55F5DF0A63878484024 /* Pods-PotterPicsTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-PotterPicsTests.debug.xcconfig"; sourceTree = ""; }; 3FE6EB1A3A06BF08C38149DE373F02D6 /* FBSDKShareDialogMode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareDialogMode.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareDialogMode.h; sourceTree = ""; }; 401B98C26CCE7BAC7B06C52BF65218A3 /* FBSDKShareLinkContent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareLinkContent.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareLinkContent.h; sourceTree = ""; }; 404F63CB215FA69CA32209AE8B409949 /* AFNetworkReachabilityManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = AFNetworkReachabilityManager.h; path = AFNetworking/AFNetworkReachabilityManager.h; sourceTree = ""; }; 40A0330BAC9BB3AA5026B8F00AC08079 /* _FBSDKLoginRecoveryAttempter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _FBSDKLoginRecoveryAttempter.m; path = FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.m; sourceTree = ""; }; 40EB7017FCE21EF267F33905494BFE43 /* FBSDKBridgeAPIRequest.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKBridgeAPIRequest.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest.m; sourceTree = ""; }; 410531D8C1D4D3F7F42F12F7ED9D9951 /* FBSDKShareError.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKShareError.m; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareError.m; sourceTree = ""; }; 417010D9205941599775F7E5B437FA89 /* BFAppLinkReturnToRefererView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BFAppLinkReturnToRefererView.m; path = Bolts/iOS/BFAppLinkReturnToRefererView.m; sourceTree = ""; }; 418F149D3D82EED551FD8535B54E541D /* FBSDKAppLinkUtility.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAppLinkUtility.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKAppLinkUtility.m; sourceTree = ""; }; 442A884AB0F3C44425BEF2E15FD50E0C /* AFHTTPSessionManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = AFHTTPSessionManager.m; path = AFNetworking/AFHTTPSessionManager.m; sourceTree = ""; }; 46CA2814DBE4937069A37145DEA3F89F /* FBSDKDynamicFrameworkLoader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKDynamicFrameworkLoader.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKDynamicFrameworkLoader.h; sourceTree = ""; }; 4747C6A0E75EBEDCF1246631896B81A2 /* UIActivityIndicatorView+AFNetworking.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIActivityIndicatorView+AFNetworking.m"; path = "UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.m"; sourceTree = ""; }; 49FB2AE04082C4817E34C765D0CC168A /* FBSDKCopying.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKCopying.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKCopying.h; sourceTree = ""; }; 4A39E686532C21963B8155F97482BCF6 /* FBSDKLoginUtility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLoginUtility.h; path = FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.h; sourceTree = ""; }; 4BA07E6014E4446BC05C4593902E8FED /* AFNetworkActivityIndicatorManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = AFNetworkActivityIndicatorManager.h; path = "UIKit+AFNetworking/AFNetworkActivityIndicatorManager.h"; sourceTree = ""; }; 4BF4F0A153C80690869A35B06385A66D /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; }; 4D2BCE0C3DC1E7FB0BE6E02ECEC19F2B /* FBSDKLikeButton.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLikeButton.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKLikeButton.m; sourceTree = ""; }; 4D509173ECC78BD99B42F22A17D81FB5 /* BFCancellationToken.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFCancellationToken.h; path = Bolts/Common/BFCancellationToken.h; sourceTree = ""; }; 4E0B8656F789272A8FBBDF797EEFF2E9 /* FBSDKShareLinkContent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKShareLinkContent.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareLinkContent.m; sourceTree = ""; }; 4E85A2F1733B0E0D31747F4281783C80 /* FBSDKLoginKit.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FBSDKLoginKit.xcconfig; sourceTree = ""; }; 4EAD10D545ACA391D87A813DC8B29B9B /* FBSDKMath.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKMath.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMath.h; sourceTree = ""; }; 4F9824B0ED4577D5374BC2CB42CD0687 /* BFAppLinkReturnToRefererController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFAppLinkReturnToRefererController.h; path = Bolts/iOS/BFAppLinkReturnToRefererController.h; sourceTree = ""; }; 500C49C75006CC6F013D43A00F9E43BA /* FBSDKAccessTokenCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAccessTokenCache.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCache.h; sourceTree = ""; }; 50589C937F0DD29347C47E4872783BF5 /* FirebaseAuth.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseAuth.framework; path = Frameworks/frameworks/FirebaseAuth.framework; sourceTree = ""; }; 50795EF8289E03FFD8A3E6F9B76FAE25 /* FBSDKCoreKit+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKCoreKit+Internal.h"; path = "FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKCoreKit+Internal.h"; sourceTree = ""; }; 51A9C43D488BB575BBE0FD9964B712BD /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; 51E7B36DB5767A90185B3AAE2038FB81 /* Pods-PotterPicsUITests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-PotterPicsUITests-umbrella.h"; sourceTree = ""; }; 52103E91501D5814A590442E9FDBE139 /* FBSDKLoginTooltipView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLoginTooltipView.h; path = FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginTooltipView.h; sourceTree = ""; }; 53434689A20D327D05B13DD331C4F27D /* FBSDKAccessToken.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAccessToken.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.h; sourceTree = ""; }; 53989C78F19889101ABE4E633CA7AB5E /* FBSDKBridgeAPIProtocolType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKBridgeAPIProtocolType.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIProtocolType.h; sourceTree = ""; }; 543C86122D60B63563B33DACF4683FC8 /* FBSDKWebDialog.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKWebDialog.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialog.h; sourceTree = ""; }; 55E1F587AC7AD403D01F7E956416682E /* FBSDKServerConfigurationManager+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKServerConfigurationManager+Internal.h"; path = "FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfigurationManager+Internal.h"; sourceTree = ""; }; 55F1ED0FA41DA559ACA70075456C78E0 /* BFAppLink.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFAppLink.h; path = Bolts/iOS/BFAppLink.h; sourceTree = ""; }; 56A18B2B02035244FF1C4670E485B31D /* FBSDKBase64.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKBase64.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.m; sourceTree = ""; }; 56B016FB0CBDC0DB06D82BAA62305478 /* FBSDKServerConfiguration+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKServerConfiguration+Internal.h"; path = "FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration+Internal.h"; sourceTree = ""; }; 57412D699CFA7F312241E647FC9D19A4 /* FBSDKLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLogger.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKLogger.h; sourceTree = ""; }; 57A52633C9C0C5FA2191B342B8DBB6D7 /* FBSDKLikeBoxView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLikeBoxView.m; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxView.m; sourceTree = ""; }; 5845C018E4DD128CECEBF0909F0741FD /* FBSDKBridgeAPIProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKBridgeAPIProtocol.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIProtocol.h; sourceTree = ""; }; 5B08B8F4C78247FC48A72B438A6CBBB6 /* FBSDKLoginKit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLoginKit.h; path = FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginKit.h; sourceTree = ""; }; 5B23364F56723A25F90AABD8FF435C50 /* FBSDKGameRequestDialog.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKGameRequestDialog.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestDialog.m; sourceTree = ""; }; 5BB3A3C6F9289BF7974B50EBA7966EA2 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 5BF80BA302324AC6AEF69A593C8DEF28 /* FBSDKLikeControl+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKLikeControl+Internal.h"; path = "FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeControl+Internal.h"; sourceTree = ""; }; 5BFD3450928A0D3AB4430B03901CFCAB /* FBSDKKeychainStoreViaBundleID.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKKeychainStoreViaBundleID.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStoreViaBundleID.h; sourceTree = ""; }; 5C66B4D4D88E19B41C4EF1475A1477D3 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/System/Library/Frameworks/MobileCoreServices.framework; sourceTree = DEVELOPER_DIR; }; 5C87CFBB77AFE7ED5094F696A20E00DD /* FBSDKAccessTokenCacheV3.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAccessTokenCacheV3.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV3.h; sourceTree = ""; }; 5E83BA00BAE5A68D7C4ACDB9A328E249 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/System/Library/Frameworks/CoreGraphics.framework; sourceTree = DEVELOPER_DIR; }; 5F4133D976E5AC5E829D1D76612C9AB8 /* FBSDKAppLinkUtility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAppLinkUtility.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKAppLinkUtility.h; sourceTree = ""; }; 60140D24CE91D843865E0ACF7ABC0810 /* FBSDKServerConfigurationManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKServerConfigurationManager.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfigurationManager.m; sourceTree = ""; }; 605285DA6D71717B3D3ABF2FD7A667EC /* Pods-PotterPicsTests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-PotterPicsTests-frameworks.sh"; sourceTree = ""; }; 60AC0A7B43501C2A1D4BAF0FC1A03769 /* FBSDKURLConnection.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKURLConnection.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKURLConnection.m; sourceTree = ""; }; 60BA4F2856A8EE256F5FD5D10DB27395 /* FBSDKCoreKit-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FBSDKCoreKit-umbrella.h"; sourceTree = ""; }; 60EEE6453B96E7C95C343AC97A90FC50 /* FBSDKAppGroupJoinDialog.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAppGroupJoinDialog.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupJoinDialog.m; sourceTree = ""; }; 614120AD63FA0D77588B740BBB2F70B0 /* FBSDKURLSessionTask.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKURLSessionTask.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKURLSessionTask.h; sourceTree = ""; }; 6154A9766C3A3BCA58EF4EBA4038751C /* AFAutoPurgingImageCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = AFAutoPurgingImageCache.m; path = "UIKit+AFNetworking/AFAutoPurgingImageCache.m"; sourceTree = ""; }; 61D174F17C7058A08EC9658CFBC014B0 /* Pods-PotterPics-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-PotterPics-dummy.m"; sourceTree = ""; }; 61D578A4D092674413B4F810B65617E8 /* FBSDKMessengerIcon.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKMessengerIcon.h; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKMessengerIcon.h; sourceTree = ""; }; 62B37D4CFD22718E76C6DA0307E7C9E1 /* Pods-PotterPicsUITests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-PotterPicsUITests.modulemap"; sourceTree = ""; }; 63803F001E344958E2374A6E2CF2D3B2 /* FBSDKGraphErrorRecoveryProcessor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKGraphErrorRecoveryProcessor.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphErrorRecoveryProcessor.m; sourceTree = ""; }; 64A1D0C796E579900E531F219DE71031 /* Pods_PotterPics.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PotterPics.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 64BC906D3B3F04EF99E4F99888D14BFD /* AFAutoPurgingImageCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = AFAutoPurgingImageCache.h; path = "UIKit+AFNetworking/AFAutoPurgingImageCache.h"; sourceTree = ""; }; 64CC903CB9F6197DD6C870CF0672B6D3 /* FBSDKAppInviteDialog.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAppInviteDialog.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKAppInviteDialog.h; sourceTree = ""; }; 64F241D129894E6FBF8D9AC83C2333EA /* BFURL.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BFURL.m; path = Bolts/iOS/BFURL.m; sourceTree = ""; }; 6594B26F7080EF6B56DCB5ED6395DF1E /* _FBSDKTemporaryErrorRecoveryAttempter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = _FBSDKTemporaryErrorRecoveryAttempter.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/_FBSDKTemporaryErrorRecoveryAttempter.m; sourceTree = ""; }; 674612913AD6C74859A7D27EA17410D4 /* FBSDKLoginManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLoginManager.h; path = FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManager.h; sourceTree = ""; }; 678FFAFC127E69071CB03622EA32A27C /* FBSDKMaleSilhouetteIcon.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKMaleSilhouetteIcon.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKMaleSilhouetteIcon.m; sourceTree = ""; }; 67B6CEFEAC287216153D11E9CA2AB080 /* FBSDKBridgeAPICrypto.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKBridgeAPICrypto.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPICrypto.m; sourceTree = ""; }; 67E43505100A6295D31ADED7C5FC9A1D /* FBSDKAccessToken.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAccessToken.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKAccessToken.m; sourceTree = ""; }; 69768F59318EE677B9D13A269EFC5AAD /* FBSDKError.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKError.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKError.m; sourceTree = ""; }; 69839F01D9DD138316CE78B1444C6523 /* Pods-PotterPics-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-PotterPics-acknowledgements.markdown"; sourceTree = ""; }; 6987C863B1CEBBD311F5CE3FB5DAEF3E /* FBSDKErrorConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKErrorConfiguration.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorConfiguration.h; sourceTree = ""; }; 69B93026B22A6256BC91593D0060E4A7 /* FBSDKLikeDialog.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLikeDialog.h; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeDialog.h; sourceTree = ""; }; 69FF9E1FA7A8337DF653E048F2CD3165 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 6A7898F3536B5C094F621EC7E3310342 /* BFCancellationTokenRegistration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFCancellationTokenRegistration.h; path = Bolts/Common/BFCancellationTokenRegistration.h; sourceTree = ""; }; 6AF1AB60322572242167BDB50A1044A8 /* BFTaskCompletionSource.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFTaskCompletionSource.h; path = Bolts/Common/BFTaskCompletionSource.h; sourceTree = ""; }; 6B50E574550A9353C447811E34C10086 /* FBSDKTriStateBOOL.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKTriStateBOOL.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTriStateBOOL.m; sourceTree = ""; }; 6B70566318E571FC681C81172C2736AE /* FBSDKAppGroupContent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAppGroupContent.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupContent.h; sourceTree = ""; }; 6B74CD72A2D1FDBE15600ED4D1792E2B /* SwiftyJSON.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftyJSON.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 6C1978C4AD325134B2AD063BAB3B5FAA /* Pods-PotterPics-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-PotterPics-acknowledgements.plist"; sourceTree = ""; }; 6C3C0A132E0782A93A180B945919D8AB /* FBSDKShareButton.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareButton.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareButton.h; sourceTree = ""; }; 6D292EA73AB2F774E99365CA751E06BF /* FBSDKLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLogger.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKLogger.m; sourceTree = ""; }; 6D76B8BE53FDB639900DA4D06EA2E84F /* Bolts.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = Bolts.modulemap; sourceTree = ""; }; 6D91C36CE02C714CF6686A657B9979E0 /* FBSDKMonotonicTime.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKMonotonicTime.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKMonotonicTime.h; sourceTree = ""; }; 6E8C117351A53CF2CF897455EC1A43E0 /* FBSDKGraphRequestDataAttachment.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKGraphRequestDataAttachment.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphRequestDataAttachment.m; sourceTree = ""; }; 6E9C62EB5AB13006083EC3A1F3519FC4 /* FBSDKCoreKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKCoreKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 6F4DEE2AB3EC71BDEDF7872D4DFBAD6B /* FBSDKSharingButton.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKSharingButton.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKSharingButton.h; sourceTree = ""; }; 6F82BA38F430E19B732A14AFC9F6FA07 /* Pods-PotterPics.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-PotterPics.modulemap"; sourceTree = ""; }; 70827AF45BE2EBCD723C40A04D7ECB46 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 7184C94179AA7BAB332BAEDD3A85C0D0 /* Pods-PotterPicsUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-PotterPicsUITests.debug.xcconfig"; sourceTree = ""; }; 718B950C70F3134649C4AFE37F4F807F /* AFNetworking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = AFNetworking.h; path = AFNetworking/AFNetworking.h; sourceTree = ""; }; 718E2D10A7A72D21C487CA83B3F5A13F /* BFTask.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFTask.h; path = Bolts/Common/BFTask.h; sourceTree = ""; }; 7231BFB6B059FC20AB187BBFAA6543EA /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 73CC49F1A238A9C23974D3948CD7BC41 /* Bolts.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = Bolts.m; path = Bolts/Common/Bolts.m; sourceTree = ""; }; 7535232E21B0FD5DCB966BA692B0A851 /* FBSDKAppGroupAddDialog.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAppGroupAddDialog.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupAddDialog.h; sourceTree = ""; }; 7619958FDC7FDB339812E4C7FA92EA62 /* FBSDKProfilePictureView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKProfilePictureView.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.h; sourceTree = ""; }; 76319A57979578EDB7F1DA23EDD1AC64 /* FBSDKGameRequestFrictionlessRecipientCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKGameRequestFrictionlessRecipientCache.h; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKGameRequestFrictionlessRecipientCache.h; sourceTree = ""; }; 7645ABECFC91260CE63FE96F1F0F938A /* BFTask+Exceptions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "BFTask+Exceptions.h"; path = "Bolts/Common/BFTask+Exceptions.h"; sourceTree = ""; }; 7799E170550970BBF284103DCCAB56B4 /* FBSDKLoginTooltipView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLoginTooltipView.m; path = FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginTooltipView.m; sourceTree = ""; }; 77DF7E41DDF2589B622A39388DE0E1B8 /* Pods-PotterPicsUITests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-PotterPicsUITests-acknowledgements.markdown"; sourceTree = ""; }; 77F9752E0AC323470089489606BD1CF5 /* FBSDKLoginKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSDKLoginKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 785F63E278C09554AFFFCF5F7CDF4A84 /* Bolts-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Bolts-umbrella.h"; sourceTree = ""; }; 78E89BE08BF96B56B9C8BB7C1A0134E0 /* AFNetworking-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "AFNetworking-umbrella.h"; sourceTree = ""; }; 798886A25C16CC5888D2F649523DAFEA /* Pods_PotterPicsUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PotterPicsUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7A210A47B0DF6B6CBBBFB5FEA7C82DD2 /* FBSDKTooltipView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKTooltipView.m; path = FBSDKLoginKit/FBSDKLoginKit/FBSDKTooltipView.m; sourceTree = ""; }; 7B6976E4ED6C9EFA96E5199EC7E1C667 /* FBSDKInternalUtility.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKInternalUtility.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKInternalUtility.m; sourceTree = ""; }; 7B81D75978055EB91A7F320BEA156D53 /* BFAppLinkNavigation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFAppLinkNavigation.h; path = Bolts/iOS/BFAppLinkNavigation.h; sourceTree = ""; }; 7C480B91C78A94655BECB08834F46BF3 /* AFNetworking-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "AFNetworking-prefix.pch"; sourceTree = ""; }; 7C4CD1BAB77A875F0B791189A9DF7A89 /* AFURLSessionManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = AFURLSessionManager.m; path = AFNetworking/AFURLSessionManager.m; sourceTree = ""; }; 7CD2C6B54FE2F8E9C9C0D350E8BAA1BA /* FBSDKTimeSpentData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKTimeSpentData.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKTimeSpentData.h; sourceTree = ""; }; 7CD63C5B47C7DD78B701AFE52A61B10C /* FBSDKMessengerIcon.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKMessengerIcon.m; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKMessengerIcon.m; sourceTree = ""; }; 7D10491C882280228A0100282683FB39 /* MBProgressHUD-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "MBProgressHUD-dummy.m"; sourceTree = ""; }; 7D7F52C33CAA98AAFDC7C1F9BB8DB72D /* FBSDKAppGroupJoinDialog.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAppGroupJoinDialog.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupJoinDialog.h; sourceTree = ""; }; 7DB5DEB6C6536F5E4950DAFE15ADD32B /* Bolts.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Bolts.xcconfig; sourceTree = ""; }; 7EB7BD93203502485FD103872BC356F3 /* BFCancellationToken.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BFCancellationToken.m; path = Bolts/Common/BFCancellationToken.m; sourceTree = ""; }; 7F2F1C57FA99F5807769A238263BD45D /* UIRefreshControl+AFNetworking.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIRefreshControl+AFNetworking.m"; path = "UIKit+AFNetworking/UIRefreshControl+AFNetworking.m"; sourceTree = ""; }; 7F33E2D7EB6A1A15DFA3E425BE4CDBC1 /* FBSDKTypeUtility.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKTypeUtility.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTypeUtility.m; sourceTree = ""; }; 7F6EDE97780B565FFB1B4DBE05562EBB /* FBSDKHashtag.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKHashtag.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKHashtag.h; sourceTree = ""; }; 800B0D395871B2D1804E151D5EC2B4DD /* FBSDKConstants.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKConstants.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKConstants.m; sourceTree = ""; }; 822A1AFEADDF1069BE0A1DBBCAD88637 /* FBSDKSettings.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKSettings.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.m; sourceTree = ""; }; 8232C20793F566FF30C03A94BDA3EE78 /* FBSDKWebDialogView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKWebDialogView.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/WebDialog/FBSDKWebDialogView.m; sourceTree = ""; }; 83ACD3E40857AE4A1FC5610CA37B8363 /* FBSDKCoreKit.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = FBSDKCoreKit.modulemap; sourceTree = ""; }; 83B9FE5A6E28DEC5A912C0035C98DEC1 /* MBProgressHUD.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MBProgressHUD.xcconfig; sourceTree = ""; }; 83ED9F692E90D19913DC15CF4A142A24 /* MBProgressHUD-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MBProgressHUD-prefix.pch"; sourceTree = ""; }; 84D7111970DA475CC83DBD97DB62803D /* FBSDKGraphRequest.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKGraphRequest.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphRequest.m; sourceTree = ""; }; 855D8A1728D8820964F4D6A0312D7A5D /* FBSDKKeychainStore.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKKeychainStore.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStore.m; sourceTree = ""; }; 8576C6B324FE7A205D9EE0109D560DEB /* BFExecutor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFExecutor.h; path = Bolts/Common/BFExecutor.h; sourceTree = ""; }; 85DA2F1CED9B84902AB69D909A20804A /* FBSDKLoginKit-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FBSDKLoginKit-dummy.m"; sourceTree = ""; }; 86F122C0918E12CF55D9A81F9A003998 /* FBSDKGraphRequestConnection.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKGraphRequestConnection.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphRequestConnection.h; sourceTree = ""; }; 8702D6DAE8FA08F9C1F699C735EA42F9 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 8919F3FC23A317CC4BF4E8285929398A /* FBSDKServerConfiguration.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKServerConfiguration.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.h; sourceTree = ""; }; 89D7C0A0BD6013F82B4B5D8EBBDC4A98 /* FBSDKLikeActionControllerCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLikeActionControllerCache.m; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionControllerCache.m; sourceTree = ""; }; 8B2ED1D72549630B27FCC801CDBA02AF /* Pods-PotterPicsUITests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-PotterPicsUITests-resources.sh"; sourceTree = ""; }; 8BCB92F107DC90466A905DFE5FCDA41E /* FBSDKBoltsMeasurementEventListener.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKBoltsMeasurementEventListener.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/AppLink/FBSDKBoltsMeasurementEventListener.h; sourceTree = ""; }; 8C76DA62C32050738F372FB86436B630 /* FBSDKDynamicFrameworkLoader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKDynamicFrameworkLoader.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal_NoARC/FBSDKDynamicFrameworkLoader.m; sourceTree = ""; }; 8CF7F766822A475D8B194105C5BD3E81 /* FBSDKLikeBoxView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLikeBoxView.h; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxView.h; sourceTree = ""; }; 8E08664A53F5655D415B1FE8A309FA30 /* FBSDKMessageDialog.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKMessageDialog.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKMessageDialog.m; sourceTree = ""; }; 8FAB4FB8B643AEEA0D54BBB11648434D /* AFNetworking.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AFNetworking.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 8FD04A0F50673290125B8C62ED8506C4 /* FBSDKButton.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKButton.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKButton.m; sourceTree = ""; }; 8FE9770DE6951597524C4EE305EAACD3 /* FBSDKShareUtility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareUtility.h; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareUtility.h; sourceTree = ""; }; 9032105C5C5AA8354FCE77960A9887D5 /* FBSDKAccessTokenCacheV4.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAccessTokenCacheV4.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV4.m; sourceTree = ""; }; 916F359EF719D81C62ED80EE052EC6AB /* FBSDKGraphRequestPiggybackManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKGraphRequestPiggybackManager.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.h; sourceTree = ""; }; 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 93C77F3F8273FA0EDE7F082BB7C6BE6C /* FBSDKShareMediaContent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareMediaContent.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareMediaContent.h; sourceTree = ""; }; 949E48FA38B27F20B10797133DACC6B1 /* FBSDKShareDialogMode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKShareDialogMode.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareDialogMode.m; sourceTree = ""; }; 956EDC51481C99DF614CB014E3A6B339 /* FBSDKGameRequestDialog.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKGameRequestDialog.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestDialog.h; sourceTree = ""; }; 95F51D818439DB35C2333ECF580CEAD7 /* FBSDKGraphRequestMetadata.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKGraphRequestMetadata.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestMetadata.m; sourceTree = ""; }; 969A5B09EED30468F88F2401AAEF5758 /* FBSDKAppEvents.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAppEvents.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKAppEvents.m; sourceTree = ""; }; 98D2BF226F3B31B1A062BF6C4D02E928 /* FBSDKSettings.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKSettings.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKSettings.h; sourceTree = ""; }; 9A0E3C506E620CE2E7D9EE7EA6F2E5AD /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; }; 9A11B62A187E7DF271BED1C24DE60AD2 /* FBSDKShareKit+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKShareKit+Internal.h"; path = "FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareKit+Internal.h"; sourceTree = ""; }; 9A55A04F0794E3AED3095BF9F3F91384 /* AFSecurityPolicy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = AFSecurityPolicy.h; path = AFNetworking/AFSecurityPolicy.h; sourceTree = ""; }; 9B849A31AF3D7B0536BAF097C883CE83 /* FBSDKLoginManagerLoginResult+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKLoginManagerLoginResult+Internal.h"; path = "FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLoginResult+Internal.h"; sourceTree = ""; }; 9C02168CB9621997A0F79BB3489C79BD /* FBSDKGraphRequestBody.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKGraphRequestBody.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestBody.h; sourceTree = ""; }; 9C085C3A1C9636BF6C842DE91E406454 /* FBSDKLoginManagerLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLoginManagerLogger.h; path = FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManagerLogger.h; sourceTree = ""; }; 9C1BD126961E83CEEFB3526EC233B08F /* FBSDKURLOpening.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKURLOpening.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKURLOpening.h; sourceTree = ""; }; 9CBF89B1639B480078C319B893452776 /* MBProgressHUD.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = MBProgressHUD.h; sourceTree = ""; }; 9D47EAC837C24B66E7DF055BB3F46694 /* FBSDKLoginButton.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLoginButton.h; path = FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.h; sourceTree = ""; }; 9E079AE02625BC14DAD98571BEBEB8BF /* SwiftyJSON.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftyJSON.swift; path = Source/SwiftyJSON.swift; sourceTree = ""; }; 9EB37E92D58767FCF62D088DC62ED5C2 /* FBSDKLikeBoxBorderView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLikeBoxBorderView.h; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxBorderView.h; sourceTree = ""; }; 9F6224EB54AEB5C2DE1DE420F9A43596 /* FBSDKBridgeAPIResponse.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKBridgeAPIResponse.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIResponse.m; sourceTree = ""; }; A0B37EFD471FF5DEECEE4775C9AC24A7 /* FBSDKLoginButton.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLoginButton.m; path = FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginButton.m; sourceTree = ""; }; A0EC3FABD68D980F29E217F43B8E7531 /* FBSDKLikeActionController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLikeActionController.m; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeActionController.m; sourceTree = ""; }; A24D533C6F87D953E9D4167CE6CCBD31 /* FBSDKGraphRequestConnection+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKGraphRequestConnection+Internal.h"; path = "FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestConnection+Internal.h"; sourceTree = ""; }; A2526D92C805D78393CCA38F2F559B1A /* MBProgressHUD-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MBProgressHUD-umbrella.h"; sourceTree = ""; }; A25F1AD85C4CA314BD8B8126647894D8 /* Pods-PotterPicsTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-PotterPicsTests-acknowledgements.plist"; sourceTree = ""; }; A294C9820557DFCF402698559CD8EEFE /* FBSDKBoltsMeasurementEventListener.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKBoltsMeasurementEventListener.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/AppLink/FBSDKBoltsMeasurementEventListener.m; sourceTree = ""; }; A2F3964515C2693109855A15979E3DE9 /* FBSDKLoginCompletion.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLoginCompletion.m; path = FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.m; sourceTree = ""; }; A4DA14531EDBF80122B1186502DF438A /* Pods-PotterPics.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-PotterPics.debug.xcconfig"; sourceTree = ""; }; A57D7246BF58D3474B15611646CF3E11 /* FBSDKAppGroupAddDialog.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAppGroupAddDialog.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupAddDialog.m; sourceTree = ""; }; A5D4C2A33C852492DAF27E4A23F3DC33 /* FBSDKColor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKColor.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKColor.m; sourceTree = ""; }; A5E4C2CB0C115FCE208B405B681F1189 /* BFTaskCompletionSource.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BFTaskCompletionSource.m; path = Bolts/Common/BFTaskCompletionSource.m; sourceTree = ""; }; A63C29CD93EA418D5FD134CBB77B5099 /* Pods-PotterPicsUITests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-PotterPicsUITests-dummy.m"; sourceTree = ""; }; A72EBD6B3894AA3DCD35DA7D490A9270 /* FBSDKSharingContent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKSharingContent.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKSharingContent.h; sourceTree = ""; }; A8AE2299D370304260AD0BE1EE2F4799 /* FBSDKAppLinkResolver.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAppLinkResolver.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKAppLinkResolver.h; sourceTree = ""; }; A8D64AE9FE48CBC32B35A212E4B461C6 /* MBProgressHUD.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = MBProgressHUD.m; sourceTree = ""; }; A8D85DD7E80E7208649B23CAD32AAE0A /* FBSDKShareKit.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = FBSDKShareKit.modulemap; sourceTree = ""; }; A8E2E6394893FE46321D0A87D90E8774 /* FBSDKMutableCopying.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKMutableCopying.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKMutableCopying.h; sourceTree = ""; }; A93C272A5F5F3856EDD3567597A6F6B0 /* FBSDKShareAPI.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareAPI.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareAPI.h; sourceTree = ""; }; A9D0227C8AF275CF95C09168D0B754B9 /* AFNetworkActivityIndicatorManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = AFNetworkActivityIndicatorManager.m; path = "UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m"; sourceTree = ""; }; AA72FA1E6640E44D8AF0EA9B06FF3FF3 /* FBSDKPaymentObserver.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKPaymentObserver.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKPaymentObserver.m; sourceTree = ""; }; AC1EF366A578B87EA50F8772B5F8FB3F /* FBSDKAppEvents+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKAppEvents+Internal.h"; path = "FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEvents+Internal.h"; sourceTree = ""; }; ACA8F295B43D163B70210857413B38D2 /* AFURLRequestSerialization.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = AFURLRequestSerialization.m; path = AFNetworking/AFURLRequestSerialization.m; sourceTree = ""; }; ACB414CD0EAEE64256401BCD8A426020 /* FBSDKIcon.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKIcon.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKIcon.m; sourceTree = ""; }; AD33ECD19031FEF0B81D507EB39BD02D /* FBSDKTypeUtility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKTypeUtility.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKTypeUtility.h; sourceTree = ""; }; AD53C2272608B872C324855ECB5511D9 /* BFMeasurementEvent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFMeasurementEvent.h; path = Bolts/iOS/BFMeasurementEvent.h; sourceTree = ""; }; AE6CADA5CA6B23D2715AC2D9938757C7 /* FBSDKBridgeAPIProtocolWebV1.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKBridgeAPIProtocolWebV1.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV1.h; sourceTree = ""; }; AE89EBA20669231D87F412BE0080CF31 /* FBSDKAccessTokenCacheV3_21.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAccessTokenCacheV3_21.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV3_21.h; sourceTree = ""; }; AF6C35358530931A262498189B73AD23 /* BFCancellationTokenSource.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BFCancellationTokenSource.m; path = Bolts/Common/BFCancellationTokenSource.m; sourceTree = ""; }; B08AC453B44CE1E8B261D54410E3F0B9 /* FBSDKShareConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareConstants.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareConstants.h; sourceTree = ""; }; B09B5367079E398942D665788719ED06 /* FBSDKShareLinkContent+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKShareLinkContent+Internal.h"; path = "FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareLinkContent+Internal.h"; sourceTree = ""; }; B0C5CC746ED5CBE775F12C5660AD1541 /* FBSDKShareButton.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKShareButton.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareButton.m; sourceTree = ""; }; B11CD9C22ABED727DBA3C605481D722B /* BFAppLinkTarget.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFAppLinkTarget.h; path = Bolts/iOS/BFAppLinkTarget.h; sourceTree = ""; }; B13B01C1E5FD1A5170F6BF0ADA24F303 /* BFWebViewAppLinkResolver.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BFWebViewAppLinkResolver.m; path = Bolts/iOS/BFWebViewAppLinkResolver.m; sourceTree = ""; }; B1699EFE891F2CEBC1D7AFE5B9D55701 /* FBSDKCoreKit-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FBSDKCoreKit-dummy.m"; sourceTree = ""; }; B22FDA84998D1688B0DD780C38A80F0E /* FBSDKSharePhotoContent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKSharePhotoContent.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKSharePhotoContent.m; sourceTree = ""; }; B29476575BC6F9F5CFB5F8DAF9604531 /* FBSDKSystemAccountStoreAdapter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKSystemAccountStoreAdapter.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSystemAccountStoreAdapter.m; sourceTree = ""; }; B2E603D2319B68E69E2A216E62709325 /* FBSDKGameRequestFrictionlessRecipientCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKGameRequestFrictionlessRecipientCache.m; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKGameRequestFrictionlessRecipientCache.m; sourceTree = ""; }; B333B404501B047047F3294F00FC52A8 /* BFAppLinkTarget.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BFAppLinkTarget.m; path = Bolts/iOS/BFAppLinkTarget.m; sourceTree = ""; }; B34CC697BCB8B6B4341DE153961C35D5 /* FBSDKServerConfigurationManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKServerConfigurationManager.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfigurationManager.h; sourceTree = ""; }; B3683A411238FDFA46DCBE5D636EFEEA /* Firebase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Firebase.h; path = Core/Sources/Firebase.h; sourceTree = ""; }; B3BF0923C01840E90921E5BCD8CEC87E /* UIWebView+AFNetworking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIWebView+AFNetworking.h"; path = "UIKit+AFNetworking/UIWebView+AFNetworking.h"; sourceTree = ""; }; B4023741CB92EC46CEB293AF1BF5F718 /* FBSDKBridgeAPIProtocolWebV1.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKBridgeAPIProtocolWebV1.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolWebV1.m; sourceTree = ""; }; B415354078EAF066BEEA2A2941FB7DDD /* FBSDKShareAPI.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKShareAPI.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareAPI.m; sourceTree = ""; }; B43763897ABF0E93E17BF93AB719E3F8 /* FBSDKLoginManagerLoginResult.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLoginManagerLoginResult.h; path = FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.h; sourceTree = ""; }; B47A1F95345E84BC07B8AC72EBA943D5 /* FBSDKShareOpenGraphValueContainer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKShareOpenGraphValueContainer.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphValueContainer.m; sourceTree = ""; }; B4BD47DBB5D86200A94802EA1CC0A77D /* Pods-PotterPics.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-PotterPics.release.xcconfig"; sourceTree = ""; }; B4CA25A29D26AF8E66E28490C969AF5B /* FBSDKIcon.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKIcon.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKIcon.h; sourceTree = ""; }; B4D3BA24C465B15F981E476FD5D9E3B4 /* FBSDKServerConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKServerConfiguration.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKServerConfiguration.m; sourceTree = ""; }; B5BABD9E98394148DDF630511B7E8095 /* UIActivityIndicatorView+AFNetworking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIActivityIndicatorView+AFNetworking.h"; path = "UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.h"; sourceTree = ""; }; B6038486C630F3839521911A8E33D5A0 /* FBSDKProfilePictureView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKProfilePictureView.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKProfilePictureView.m; sourceTree = ""; }; B68D7B05294DC4B65D14D28CB5312A52 /* FBSDKAppEventsUtility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAppEventsUtility.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsUtility.h; sourceTree = ""; }; B6AC322AFE8269208192FA62AD2A219F /* UIRefreshControl+AFNetworking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIRefreshControl+AFNetworking.h"; path = "UIKit+AFNetworking/UIRefreshControl+AFNetworking.h"; sourceTree = ""; }; B6C4053DC4067A1964C8D3A08AB1AA0A /* BFWebViewAppLinkResolver.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFWebViewAppLinkResolver.h; path = Bolts/iOS/BFWebViewAppLinkResolver.h; sourceTree = ""; }; B7FB3070FF4872061FB66A25E85BF7CE /* FBSDKAppEventsDeviceInfo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAppEventsDeviceInfo.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsDeviceInfo.h; sourceTree = ""; }; B818C9A9E4A1A3A6D7F30D62A87281EA /* FirebaseStorage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseStorage.framework; path = Frameworks/frameworks/FirebaseStorage.framework; sourceTree = ""; }; B8E5EDD2E5CE2CD25F918C7F6C0E6CB2 /* UIButton+AFNetworking.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIButton+AFNetworking.m"; path = "UIKit+AFNetworking/UIButton+AFNetworking.m"; sourceTree = ""; }; B90052B3335BE6C11194A4B1B3EB1F69 /* UIWebView+AFNetworking.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIWebView+AFNetworking.m"; path = "UIKit+AFNetworking/UIWebView+AFNetworking.m"; sourceTree = ""; }; BA472FAE62F4170052081A3990353BCE /* FBSDKBridgeAPIRequest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKBridgeAPIRequest.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest.h; sourceTree = ""; }; BA7945F87AC9D33609535DF4E917D6D5 /* FBSDKErrorConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKErrorConfiguration.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorConfiguration.m; sourceTree = ""; }; BAE798271E874DBB143FD87F7C9B5009 /* FBSDKGraphRequest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKGraphRequest.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphRequest.h; sourceTree = ""; }; BB144CFDE6AF6A88F63BC0B5D75AD5F3 /* UIButton+AFNetworking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIButton+AFNetworking.h"; path = "UIKit+AFNetworking/UIButton+AFNetworking.h"; sourceTree = ""; }; BD13EABB51615CBC9F07BB5ABD554881 /* BFTask+Exceptions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "BFTask+Exceptions.m"; path = "Bolts/Common/BFTask+Exceptions.m"; sourceTree = ""; }; BEDB9F06356271BE836C1075461A2E5F /* FBSDKVideoUploader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKVideoUploader.m; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.m; sourceTree = ""; }; BEE123787F3B550805CD837E4984E8FC /* FBSDKGameRequestContent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKGameRequestContent.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestContent.h; sourceTree = ""; }; BF6124C6F3541980379CB23661270EE2 /* FBSDKShareOpenGraphObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareOpenGraphObject.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphObject.h; sourceTree = ""; }; BFB22238BD35F9F2CB6B4C4B72394FD2 /* FBSDKBridgeAPIProtocolNativeV1.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKBridgeAPIProtocolNativeV1.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolNativeV1.m; sourceTree = ""; }; C03EA17AC9B7FA3EF6873BD9015ECF79 /* FBSDKCloseIcon.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKCloseIcon.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKCloseIcon.h; sourceTree = ""; }; C060D6E271F89351A2BB235894E4E44E /* FirebaseInstanceID.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseInstanceID.framework; path = Frameworks/frameworks/FirebaseInstanceID.framework; sourceTree = ""; }; C1777F9C07CE6501DB231C2A30C7BFE0 /* FBSDKGraphRequestBody.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKGraphRequestBody.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestBody.m; sourceTree = ""; }; C18451DC83C885C1446AE0C026601489 /* FBSDKShareOpenGraphObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKShareOpenGraphObject.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphObject.m; sourceTree = ""; }; C1A016781B2CFFF3675BBD3E47ECBEEF /* BFAppLink_Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFAppLink_Internal.h; path = Bolts/iOS/Internal/BFAppLink_Internal.h; sourceTree = ""; }; C1BAA4B321D5F11E1C62671BEA4CC582 /* FBSDKAccessTokenCacheV3.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAccessTokenCacheV3.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV3.m; sourceTree = ""; }; C1D2C05DC29BBFFBED4CFBED1C5A6E12 /* FBSDKLikeButton.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLikeButton.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKLikeButton.h; sourceTree = ""; }; C2CCD702DFCD015849180F62A26CFD95 /* FBSDKKeychainStore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKKeychainStore.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStore.h; sourceTree = ""; }; C34835953FB9E3EE76D3990C85A3BD09 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; C34A702F2DD7C4CF61FD075393BE6CAC /* FBSDKAppEventsState.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAppEventsState.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsState.m; sourceTree = ""; }; C3F452F59B8B4EF25DC574BB1D66471F /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; C43A78A5372F75EB57D137461A709703 /* FBSDKShareDialog.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareDialog.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.h; sourceTree = ""; }; C450A354F9C39F28DDC4916ADFA5FA41 /* FBSDKTestUsersManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKTestUsersManager.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKTestUsersManager.h; sourceTree = ""; }; C56454497F44EC43E8AD4122182BA797 /* FBSDKAccessTokenCacheV3_21.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAccessTokenCacheV3_21.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV3_21.m; sourceTree = ""; }; C58C011E0A74E340CC9F79605F65D85A /* FBSDKShareKit-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FBSDKShareKit-dummy.m"; sourceTree = ""; }; C5CD1E73DFD39E5D339E021817B9DA2F /* BFURL.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFURL.h; path = Bolts/iOS/BFURL.h; sourceTree = ""; }; C65B8B4258A289D02EEB422B96A89EF4 /* FBSDKLikeObjectType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLikeObjectType.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKLikeObjectType.h; sourceTree = ""; }; C67B3396039B22A161B9FFC678BEF36C /* FBSDKLoginConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLoginConstants.h; path = FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConstants.h; sourceTree = ""; }; C6A497B03B5633DDD9411F414F9F6373 /* FBSDKSharePhoto.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKSharePhoto.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKSharePhoto.h; sourceTree = ""; }; C6D6274B3F544F77220B92171CF9F919 /* FBSDKErrorRecoveryConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKErrorRecoveryConfiguration.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKErrorRecoveryConfiguration.m; sourceTree = ""; }; C8AA990ECA07A22AF023B8A8DCF96F15 /* Pods-PotterPicsTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-PotterPicsTests.release.xcconfig"; sourceTree = ""; }; C8F73117E940B605910F515665016FA9 /* BFAppLinkReturnToRefererController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BFAppLinkReturnToRefererController.m; path = Bolts/iOS/BFAppLinkReturnToRefererController.m; sourceTree = ""; }; C93EDE5838549A4DDAF2016C59DD7FA0 /* FBSDKColor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKColor.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKColor.h; sourceTree = ""; }; C95CF36B007E563455F5296F4BF0218D /* FBSDKAccessTokenCacheV3_17.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAccessTokenCacheV3_17.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV3_17.h; sourceTree = ""; }; C9AECD149DAA9CBBE44D0552225C4FFF /* FBSDKApplicationDelegate+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKApplicationDelegate+Internal.h"; path = "FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKApplicationDelegate+Internal.h"; sourceTree = ""; }; CA407D693530EF67FBB1EA3D2C81B497 /* FBSDKLoginUtility.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLoginUtility.m; path = FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginUtility.m; sourceTree = ""; }; CA75839331F42194ED8BABCA637B61DC /* FBSDKCheckmarkIcon.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKCheckmarkIcon.m; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCheckmarkIcon.m; sourceTree = ""; }; CAA129C29843E84557F30FA22E3BD93C /* FBSDKLoginCompletion.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLoginCompletion.h; path = FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginCompletion.h; sourceTree = ""; }; CAB8C2BC02B7B8B4514A64428FA9B03F /* FirebaseCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FirebaseCore.framework; path = Frameworks/frameworks/FirebaseCore.framework; sourceTree = ""; }; CAC188BFAD7FD3006FDEAA6F11B98188 /* BFURL_Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFURL_Internal.h; path = Bolts/iOS/Internal/BFURL_Internal.h; sourceTree = ""; }; CAF2E3BCF8134ECFEBAD9A4DAB39EB06 /* FBSDKSendButton.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKSendButton.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKSendButton.m; sourceTree = ""; }; CC012CCA1D0FFDDFF34638747D3E00B5 /* FBSDKHashtag.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKHashtag.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKHashtag.m; sourceTree = ""; }; CC141E7006767F72BFBBA10C3EF7924D /* BFAppLinkReturnToRefererView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFAppLinkReturnToRefererView.h; path = Bolts/iOS/BFAppLinkReturnToRefererView.h; sourceTree = ""; }; CC1E31B7EF7D80815F0DF17659122C16 /* BFExecutor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BFExecutor.m; path = Bolts/Common/BFExecutor.m; sourceTree = ""; }; CC26118D0CC247921A80E8AD1177894A /* MBProgressHUD.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MBProgressHUD.framework; sourceTree = BUILT_PRODUCTS_DIR; }; CC7EDD6E1F6211E24E396BF86C89B5B0 /* FBSDKDialogConfiguration.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKDialogConfiguration.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/ServerConfiguration/FBSDKDialogConfiguration.m; sourceTree = ""; }; CCD86D5BDACC24412DF3B69EFA3F6C1E /* BFCancellationTokenSource.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFCancellationTokenSource.h; path = Bolts/Common/BFCancellationTokenSource.h; sourceTree = ""; }; CD8846B8FF6EE2E1CA42E78339D4AA6D /* FBSDKBridgeAPIProtocolNativeV1.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKBridgeAPIProtocolNativeV1.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/ProtocolVersions/FBSDKBridgeAPIProtocolNativeV1.h; sourceTree = ""; }; CDDE60295A376CD8BB037C7A798D32CE /* FacebookSDKStrings.bundle */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "wrapper.plug-in"; path = FacebookSDKStrings.bundle; sourceTree = ""; }; D06DF8B0C5E620647EF9C1A634661190 /* FBSDKLoginManager+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKLoginManager+Internal.h"; path = "FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginManager+Internal.h"; sourceTree = ""; }; D0EF04BF188BEED43329404FE99E480A /* FBSDKLoginManagerLoginResult.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLoginManagerLoginResult.m; path = FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginManagerLoginResult.m; sourceTree = ""; }; D1EF1935E3B0AFCF73AC1E5676BC3307 /* FBSDKLikeButton+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKLikeButton+Internal.h"; path = "FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeButton+Internal.h"; sourceTree = ""; }; D2298735034342AA6ADB4F009EEFBF84 /* FBSDKProfile+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKProfile+Internal.h"; path = "FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKProfile+Internal.h"; sourceTree = ""; }; D28EF19A899EA7B11BFB90D1F8F63312 /* Bolts-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Bolts-dummy.m"; sourceTree = ""; }; D2B0320B381026451CC830A8AC04FD6C /* FBSDKAudioResourceLoader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAudioResourceLoader.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKAudioResourceLoader.m; sourceTree = ""; }; D37DBF6D698BB99BFFC4CB01A283B435 /* AFNetworking-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "AFNetworking-dummy.m"; sourceTree = ""; }; D3A66E713AB37C108C97F78960268162 /* Pods-PotterPicsUITests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-PotterPicsUITests-frameworks.sh"; sourceTree = ""; }; D4D7A0BB6AA817122DC09D746FB66A67 /* FBSDKViewImpressionTracker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKViewImpressionTracker.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKViewImpressionTracker.m; sourceTree = ""; }; D5EB9C9B78B77B89CEEB5F087D46C5D1 /* FBSDKShareKit-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FBSDKShareKit-umbrella.h"; sourceTree = ""; }; D66F787B8DEE80A4542BD8B221A29756 /* FBSDKShareDialog.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKShareDialog.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareDialog.m; sourceTree = ""; }; D6858FA37A34E608E6179A5EE01A9D62 /* FBSDKLikeControl.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLikeControl.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKLikeControl.m; sourceTree = ""; }; D6C5B5EE3BEAC1E82C7AEC21832CAECD /* Pods-PotterPicsTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-PotterPicsTests.modulemap"; sourceTree = ""; }; D6D5AD1E8060B45D6A24CF893CB9EDD2 /* Pods-PotterPicsUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-PotterPicsUITests.release.xcconfig"; sourceTree = ""; }; D6DEC30656F6CB2F37C4C8127F8A6B19 /* BFAppLinkResolving.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = BFAppLinkResolving.h; path = Bolts/iOS/BFAppLinkResolving.h; sourceTree = ""; }; D72C11AF3A74FB5E0B69AC82FD7BEB76 /* FBSDKBase64.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKBase64.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/Base64/FBSDKBase64.h; sourceTree = ""; }; D73633CF90D5AAD0C11B22324BF69CE1 /* FBSDKUtility.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKUtility.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKUtility.m; sourceTree = ""; }; D7498DE1F0631DBC817CBEBF48DEE4D1 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; D751570D07A6198A619045C589D426A9 /* Pods-PotterPicsTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-PotterPicsTests-umbrella.h"; sourceTree = ""; }; D8532C3DE9D5AC1EEDFADF9E33A8CA51 /* FBSDKGameRequestContent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKGameRequestContent.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKGameRequestContent.m; sourceTree = ""; }; D995EC9D92E9EEE5967826BB1E1BECB5 /* Pods_PotterPicsTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PotterPicsTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D9F3A3FD7BD2508F05C8FBF147009DA3 /* FBSDKButton.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKButton.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKButton.h; sourceTree = ""; }; DA2F8969582848AC7C57D2530917927E /* FBSDKProfile.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKProfile.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKProfile.m; sourceTree = ""; }; DBB02E482BD1DF480E6409A036C5FC12 /* FBSDKButton+Subclass.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKButton+Subclass.h"; path = "FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKButton+Subclass.h"; sourceTree = ""; }; DBBFC9D33690BE5B8CD94F27485FD494 /* FBSDKShareError.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareError.h; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKShareError.h; sourceTree = ""; }; DC96BE4A20B07F3244063DF2220E0AB4 /* AFURLResponseSerialization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = AFURLResponseSerialization.h; path = AFNetworking/AFURLResponseSerialization.h; sourceTree = ""; }; DD33F0EE59FF3C4E50A5C36521C987FB /* Pods-PotterPics-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-PotterPics-resources.sh"; sourceTree = ""; }; DDB6041D8F8F89D75572007DECCF98B4 /* Pods-PotterPics-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-PotterPics-frameworks.sh"; sourceTree = ""; }; DDB995465AE9F9D7AFA7C1E10FD68131 /* FBSDKCrypto.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKCrypto.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/Cryptography/FBSDKCrypto.h; sourceTree = ""; }; DDCA2DD0D90DEA85D29FC3C7A43E10DD /* FBSDKGraphRequestDataAttachment.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKGraphRequestDataAttachment.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphRequestDataAttachment.h; sourceTree = ""; }; DE14C7CF1D6A0C2E591C30AB03E3A304 /* FBSDKBridgeAPICrypto.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKBridgeAPICrypto.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPICrypto.h; sourceTree = ""; }; DEA2562FC7F4C75E4E3C454A1A88CF70 /* UIImage+AFNetworking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+AFNetworking.h"; path = "UIKit+AFNetworking/UIImage+AFNetworking.h"; sourceTree = ""; }; DEA93732FBB84B8F7041EACCC7E04C28 /* SwiftyJSON.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = SwiftyJSON.modulemap; sourceTree = ""; }; E0B676F7AE322CC9E13D2570ABF0D500 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; E10862047BD35340133D45D62E993711 /* GoogleInterchangeUtilities.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GoogleInterchangeUtilities.framework; path = Frameworks/frameworks/GoogleInterchangeUtilities.framework; sourceTree = ""; }; E120AA6183A04CF6357B5A672B44C9B7 /* FBSDKLoginConstants.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLoginConstants.m; path = FBSDKLoginKit/FBSDKLoginKit/FBSDKLoginConstants.m; sourceTree = ""; }; E27FF6725E1FBBC2A5EC8FA3557A9246 /* FBSDKCheckmarkIcon.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKCheckmarkIcon.h; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKCheckmarkIcon.h; sourceTree = ""; }; E327066FFF0F45B24255C9027C06334F /* FBSDKApplicationDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKApplicationDelegate.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.h; sourceTree = ""; }; E358A56A466C2082917A1BD0273080ED /* FBSDKAppGroupContent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAppGroupContent.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKAppGroupContent.m; sourceTree = ""; }; E3775D041D8EEC8ED6D0BBA93F4FDE46 /* FBSDKAppEventsStateManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAppEventsStateManager.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsStateManager.h; sourceTree = ""; }; E3B0B71896AC656CAFFDBC3027C80295 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; E464801267CE346683BC078B76EF31AF /* FBSDKGraphErrorRecoveryProcessor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKGraphErrorRecoveryProcessor.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKGraphErrorRecoveryProcessor.h; sourceTree = ""; }; E47F8F57287DE302CE0477B586E91983 /* Bolts.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Bolts.h; path = Bolts/Common/Bolts.h; sourceTree = ""; }; E4A9423C5315B0FFA7996239E7E13BC1 /* FBSDKLoginError.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLoginError.m; path = FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginError.m; sourceTree = ""; }; E5499B12C2B8CAC69028FF98296B9B10 /* _FBSDKLoginRecoveryAttempter.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = _FBSDKLoginRecoveryAttempter.h; path = FBSDKLoginKit/FBSDKLoginKit/Internal/_FBSDKLoginRecoveryAttempter.h; sourceTree = ""; }; E5A7F39C006211ABC22FC3E7431BD43E /* FBSDKLogo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLogo.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKLogo.h; sourceTree = ""; }; E5C2EE94032E562AA6883D2FE9C5201C /* AFURLRequestSerialization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = AFURLRequestSerialization.h; path = AFNetworking/AFURLRequestSerialization.h; sourceTree = ""; }; E5F6F9EDBCDDE76BDC6C33E0669EF224 /* FBSDKSettings+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKSettings+Internal.h"; path = "FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKSettings+Internal.h"; sourceTree = ""; }; E6715DAD6D0684A20A87622BF8E0A551 /* FBSDKShareOpenGraphValueContainer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareOpenGraphValueContainer.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareOpenGraphValueContainer.h; sourceTree = ""; }; E75958EF9F3DB83089704F6DF0207418 /* AFHTTPSessionManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = AFHTTPSessionManager.h; path = AFNetworking/AFHTTPSessionManager.h; sourceTree = ""; }; E76E62E37B5FC6CA07F3E99A07FF64FA /* FBSDKLikeObjectType.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLikeObjectType.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKLikeObjectType.m; sourceTree = ""; }; E8E73443DC19BD45AC2BE2F1D5DA6FEB /* FBSDKGraphRequestPiggybackManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKGraphRequestPiggybackManager.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/Network/FBSDKGraphRequestPiggybackManager.m; sourceTree = ""; }; EA7FBCFFA76DC9969D1C804EC5A2DF5E /* FBSDKCoreKit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKCoreKit.h; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKCoreKit.h; sourceTree = ""; }; EAD69571A07FB3D8D3FB6191BCDB7F69 /* FBSDKShareConstants.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKShareConstants.m; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareConstants.m; sourceTree = ""; }; EB25923A3C24D72670801C96252FF023 /* FBSDKMessageDialog.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKMessageDialog.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKMessageDialog.h; sourceTree = ""; }; EB3472AD9F8972FD61773DA8DF704869 /* FBSDKErrorRecoveryAttempter.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKErrorRecoveryAttempter.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/ErrorRecovery/FBSDKErrorRecoveryAttempter.m; sourceTree = ""; }; EC41976D2B74FA9072C676F86517427B /* AFNetworkReachabilityManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = AFNetworkReachabilityManager.m; path = AFNetworking/AFNetworkReachabilityManager.m; sourceTree = ""; }; EC52AD4D8DBD5728FE40009628C28BDC /* BFAppLinkNavigation.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BFAppLinkNavigation.m; path = Bolts/iOS/BFAppLinkNavigation.m; sourceTree = ""; }; ED0F0038D42615B65492BEFC1D3A5FC0 /* Pods-PotterPicsTests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-PotterPicsTests-resources.sh"; sourceTree = ""; }; EE74E13A61B4A768AA0B8FFACF358EFF /* FBSDKApplicationDelegate.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKApplicationDelegate.m; path = FBSDKCoreKit/FBSDKCoreKit/FBSDKApplicationDelegate.m; sourceTree = ""; }; EF5C3346B26F744DBD314D4284287A88 /* Pods-PotterPics-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-PotterPics-umbrella.h"; sourceTree = ""; }; EF7BC936D9DC70BBB915217A9BC6AAF5 /* FBSDKPaymentObserver.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKPaymentObserver.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKPaymentObserver.h; sourceTree = ""; }; EFA1CD6866EC21FCF10919413F1D2141 /* FBSDKCrypto.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKCrypto.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/Cryptography/FBSDKCrypto.m; sourceTree = ""; }; F0AC2705D48C5A4C7DE0885AB3E06FB1 /* UIKit+AFNetworking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIKit+AFNetworking.h"; path = "UIKit+AFNetworking/UIKit+AFNetworking.h"; sourceTree = ""; }; F138F36ECB86181177EF7EF47562C6C6 /* Bolts-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Bolts-prefix.pch"; sourceTree = ""; }; F1AF5D1C5557D2E36ACA410EE645160C /* FBSDKCloseIcon.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKCloseIcon.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKCloseIcon.m; sourceTree = ""; }; F1C7C6ED4FC099A65098F800F96701A3 /* FBSDKLiking.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLiking.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKLiking.h; sourceTree = ""; }; F4F13DEEC78A2EA3065FF203E4660B55 /* FBSDKLikeBoxBorderView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKLikeBoxBorderView.m; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeBoxBorderView.m; sourceTree = ""; }; F4F30481231EF67BD4487BBF6C5D1CB1 /* FBSDKShareKit.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKShareKit.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKShareKit.h; sourceTree = ""; }; F51662A395C193FC0CD95DF4D613BCDA /* FBSDKContainerViewController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKContainerViewController.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKContainerViewController.m; sourceTree = ""; }; F54A2AA54749108AF1EE5F405A33322F /* FBSDKSendButton.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKSendButton.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKSendButton.h; sourceTree = ""; }; F5B5D8ADAEF759D6862C19B408FC4C58 /* FBSDKMaleSilhouetteIcon.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKMaleSilhouetteIcon.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/UI/FBSDKMaleSilhouetteIcon.h; sourceTree = ""; }; F6324761E83B8DF5653AD7DFBAD00A5F /* MBProgressHUD.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = MBProgressHUD.modulemap; sourceTree = ""; }; F696FAB825675820258C0860126EB967 /* AFImageDownloader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = AFImageDownloader.h; path = "UIKit+AFNetworking/AFImageDownloader.h"; sourceTree = ""; }; F75911B1C5FA2475BFF11249796F94D2 /* FBSDKKeychainStoreViaBundleID.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKKeychainStoreViaBundleID.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKKeychainStoreViaBundleID.m; sourceTree = ""; }; F76024F6A89EEA91F3F7CE0033C71B96 /* FBSDKSharePhotoContent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKSharePhotoContent.h; path = FBSDKShareKit/FBSDKShareKit/FBSDKSharePhotoContent.h; sourceTree = ""; }; F8168C0CD4D0232D99DAFC627DD18468 /* FBSDKAppEventsDeviceInfo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAppEventsDeviceInfo.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/AppEvents/FBSDKAppEventsDeviceInfo.m; sourceTree = ""; }; FA00C1C3274A7E11FF27A45C4CE750C2 /* BFTask.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = BFTask.m; path = Bolts/Common/BFTask.m; sourceTree = ""; }; FA1F9F6B6D37F39C85DB019B87701253 /* FBSDKVideoUploader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKVideoUploader.h; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKVideoUploader.h; sourceTree = ""; }; FAA41E1A3AB2CDE00AC2A074261AA18B /* FBSDKAccessTokenCacheV3_17.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSDKAccessTokenCacheV3_17.m; path = FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCacheV3_17.m; sourceTree = ""; }; FB4B3634A661281E58317EADEB114C90 /* FBSDKLikeButtonPopWAV.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKLikeButtonPopWAV.h; path = FBSDKShareKit/FBSDKShareKit/Internal/FBSDKLikeButtonPopWAV.h; sourceTree = ""; }; FBF5EC3AC894B9183DB7EDA870D9A9CB /* FBSDKAccessTokenCaching.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKAccessTokenCaching.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/TokenCaching/FBSDKAccessTokenCaching.h; sourceTree = ""; }; FC56D94F5E6790B727E2400EF769F104 /* FBSDKError.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSDKError.h; path = FBSDKCoreKit/FBSDKCoreKit/Internal/FBSDKError.h; sourceTree = ""; }; FCE73BF6B4E09090F8B4D7EAE911A6EB /* FBSDKBridgeAPIRequest+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKBridgeAPIRequest+Private.h"; path = "FBSDKCoreKit/FBSDKCoreKit/Internal/BridgeAPI/FBSDKBridgeAPIRequest+Private.h"; sourceTree = ""; }; FD8FD30657D301CAC2E078975D5035FD /* FBSDKLoginKit+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBSDKLoginKit+Internal.h"; path = "FBSDKLoginKit/FBSDKLoginKit/Internal/FBSDKLoginKit+Internal.h"; sourceTree = ""; }; FFB5F1ED229E2F69AA805EDD810F893A /* AFURLSessionManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = AFURLSessionManager.h; path = AFNetworking/AFURLSessionManager.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 03E8CCDA32AA42D3F8C9E0956F925223 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 42F44AD72DA11C66072D46BEC5DF08B2 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 0A3F9698C4DAAA9A77B44DAFE231B96B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( D96FC2C9AB1D0FB9891F97920F5C5059 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 2A21945ADA3A841F44A1AF8E5ECAFC87 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( C77BADC0FD562402E2E30759A5F17CFA /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 2E7E8F9C361AB09ED21E3ACCBDE5522A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 75BAFB5D292A5AC28EBAC6EA8D73CFC6 /* Bolts.framework in Frameworks */, 443CD693458E72E577CD457C3F55D9DD /* FBSDKCoreKit.framework in Frameworks */, B80E99999E2A245B701DC0731CB02ABC /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 4C4161B0612BDBF5BD49DBC28E0EC20B /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 28765B10E7DCB9D8DF17F0F480743152 /* CoreGraphics.framework in Frameworks */, 5B32EA8AB19F49234A383200A5135921 /* Foundation.framework in Frameworks */, 41637DA371D84C3DD6CE1A2BAD23DFE2 /* QuartzCore.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 54D8C3611A54C9E38BC9E3D5591E6EF8 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( FF7EBF74284B1B1DEDD8687753467CA4 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 858CFE365F90A45EF980BA032C96E8C1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 84DAB5206F3A2091F6E750821F398C09 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; BB4E7410D48C44A7F803DFFB5F71C494 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 6CB8F54E16ED334F8114F012E41D6B94 /* Bolts.framework in Frameworks */, F42198560289E76E8550D33440165462 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; C151364F15F39F7CC60CBF9A3AB49B44 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 4ECA9BE68D373E094EFA019CC4EA1720 /* CoreGraphics.framework in Frameworks */, B99FAFBBC58F176BCBAA61124A21C14B /* Foundation.framework in Frameworks */, 4FE3D0FC60D1370E831CBFF9680FA8EB /* MobileCoreServices.framework in Frameworks */, 192AC43D2F848129D2CAC66DAAF6CA35 /* Security.framework in Frameworks */, 688E37A2E29646148D380D9034875174 /* SystemConfiguration.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; FE01B5BC92977FB1F14A8C73D8F6D05C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 3708AA48F1D26CB56F88BB6FEC72DE36 /* Bolts.framework in Frameworks */, 89B59BD52908BA3B2EEED23398CF79E6 /* FBSDKCoreKit.framework in Frameworks */, 6200682BC2425BD28680140B8EF3851E /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 0B39A7A390233854DC5FDE5F564DD019 /* Frameworks */ = { isa = PBXGroup; children = ( 24E2DAB6E1D48DC025ACCFE8FACEE3B7 /* GoogleNetworkingUtilities.framework */, ); name = Frameworks; sourceTree = ""; }; 140210B87FE481206F76E74AE73F1DCC /* Pods */ = { isa = PBXGroup; children = ( 866255CBF307F3FBDC75888A6384A697 /* AFNetworking */, D4B233D9904E69F21CFFCAF8D4B8E96E /* Bolts */, 4982E05396FE7258BFEEC9650B1E12BB /* FBSDKCoreKit */, C6F585FA1AA87D4ABCD6AC37C84A8E6E /* FBSDKLoginKit */, 4039874FCB33C8F219A5EBC386BB42FA /* FBSDKShareKit */, 4724E6210A8CA4320BA6232F2DB1B6CE /* Firebase */, E1045DA9889AB5BB5861077CF8672EE6 /* FirebaseAnalytics */, 24F8149CE19E6B63EFE2E0AA857491EB /* FirebaseAuth */, FC0BF23738CFB88D051A22669372DF5F /* FirebaseCore */, 8ADA64AA3B0C1806273BFB004119BC6A /* FirebaseDatabase */, A83101FA1ACFE648E790A6EB30044817 /* FirebaseInstanceID */, D0F500766380E6CC333E532F0E5BB708 /* FirebaseStorage */, E01C9E7F6FFCF138B86B1D72F282C269 /* GoogleInterchangeUtilities */, 8322BF8243B7C632009ED4D343AC4E2D /* GoogleNetworkingUtilities */, 8346E198A1B7CDF557568DBB988D2D62 /* GoogleSymbolUtilities */, 70A6921175D4A8308DE8EF7CBE3BD6A3 /* GoogleUtilities */, BCEEF5CCF7B62C07835D784540E4815E /* MBProgressHUD */, EE676BF0157B1EAC147C75FD41346566 /* SwiftyJSON */, ); name = Pods; sourceTree = ""; }; 1C0D0508620AB7E64EFA91671764A778 /* Core */ = { isa = PBXGroup; children = ( B3683A411238FDFA46DCBE5D636EFEEA /* Firebase.h */, ); name = Core; sourceTree = ""; }; 1FEE8DFFE6246E8C21E874D6A14E27D4 /* Pods-PotterPicsUITests */ = { isa = PBXGroup; children = ( C3F452F59B8B4EF25DC574BB1D66471F /* Info.plist */, 62B37D4CFD22718E76C6DA0307E7C9E1 /* Pods-PotterPicsUITests.modulemap */, 77DF7E41DDF2589B622A39388DE0E1B8 /* Pods-PotterPicsUITests-acknowledgements.markdown */, 391526EE3F5F71D24870BE3950952E60 /* Pods-PotterPicsUITests-acknowledgements.plist */, A63C29CD93EA418D5FD134CBB77B5099 /* Pods-PotterPicsUITests-dummy.m */, D3A66E713AB37C108C97F78960268162 /* Pods-PotterPicsUITests-frameworks.sh */, 8B2ED1D72549630B27FCC801CDBA02AF /* Pods-PotterPicsUITests-resources.sh */, 51E7B36DB5767A90185B3AAE2038FB81 /* Pods-PotterPicsUITests-umbrella.h */, 7184C94179AA7BAB332BAEDD3A85C0D0 /* Pods-PotterPicsUITests.debug.xcconfig */, D6D5AD1E8060B45D6A24CF893CB9EDD2 /* Pods-PotterPicsUITests.release.xcconfig */, ); name = "Pods-PotterPicsUITests"; path = "Target Support Files/Pods-PotterPicsUITests"; sourceTree = ""; }; 24F8149CE19E6B63EFE2E0AA857491EB /* FirebaseAuth */ = { isa = PBXGroup; children = ( 7F79E197FB2DB8A2BDFB65EAA4C994C4 /* Frameworks */, ); path = FirebaseAuth; sourceTree = ""; }; 250FF8298CECE72D65369DC0C1774C98 /* iOS */ = { isa = PBXGroup; children = ( 5E83BA00BAE5A68D7C4ACDB9A328E249 /* CoreGraphics.framework */, 70827AF45BE2EBCD723C40A04D7ECB46 /* Foundation.framework */, 5C66B4D4D88E19B41C4EF1475A1477D3 /* MobileCoreServices.framework */, 9A0E3C506E620CE2E7D9EE7EA6F2E5AD /* QuartzCore.framework */, 51A9C43D488BB575BBE0FD9964B712BD /* Security.framework */, 4BF4F0A153C80690869A35B06385A66D /* SystemConfiguration.framework */, ); name = iOS; sourceTree = ""; }; 3904B437DC1AEF620A02F799280ED74F /* Frameworks */ = { isa = PBXGroup; children = ( E10862047BD35340133D45D62E993711 /* GoogleInterchangeUtilities.framework */, ); name = Frameworks; sourceTree = ""; }; 3E4671CBB7BD8B00D615EE0A19EA2DB0 /* Frameworks */ = { isa = PBXGroup; children = ( CAB8C2BC02B7B8B4514A64428FA9B03F /* FirebaseCore.framework */, ); name = Frameworks; sourceTree = ""; }; 4039874FCB33C8F219A5EBC386BB42FA /* FBSDKShareKit */ = { isa = PBXGroup; children = ( 7535232E21B0FD5DCB966BA692B0A851 /* FBSDKAppGroupAddDialog.h */, A57D7246BF58D3474B15611646CF3E11 /* FBSDKAppGroupAddDialog.m */, 6B70566318E571FC681C81172C2736AE /* FBSDKAppGroupContent.h */, E358A56A466C2082917A1BD0273080ED /* FBSDKAppGroupContent.m */, 7D7F52C33CAA98AAFDC7C1F9BB8DB72D /* FBSDKAppGroupJoinDialog.h */, 60EEE6453B96E7C95C343AC97A90FC50 /* FBSDKAppGroupJoinDialog.m */, 30277D302B666A9583A67ADEE4829C79 /* FBSDKAppInviteContent.h */, 320EC985715765292F038461B143AAD1 /* FBSDKAppInviteContent.m */, 64CC903CB9F6197DD6C870CF0672B6D3 /* FBSDKAppInviteDialog.h */, 3BA89B7CB74DAA591F92581FD6474C01 /* FBSDKAppInviteDialog.m */, E27FF6725E1FBBC2A5EC8FA3557A9246 /* FBSDKCheckmarkIcon.h */, CA75839331F42194ED8BABCA637B61DC /* FBSDKCheckmarkIcon.m */, BEE123787F3B550805CD837E4984E8FC /* FBSDKGameRequestContent.h */, D8532C3DE9D5AC1EEDFADF9E33A8CA51 /* FBSDKGameRequestContent.m */, 956EDC51481C99DF614CB014E3A6B339 /* FBSDKGameRequestDialog.h */, 5B23364F56723A25F90AABD8FF435C50 /* FBSDKGameRequestDialog.m */, 76319A57979578EDB7F1DA23EDD1AC64 /* FBSDKGameRequestFrictionlessRecipientCache.h */, B2E603D2319B68E69E2A216E62709325 /* FBSDKGameRequestFrictionlessRecipientCache.m */, 7F6EDE97780B565FFB1B4DBE05562EBB /* FBSDKHashtag.h */, CC012CCA1D0FFDDFF34638747D3E00B5 /* FBSDKHashtag.m */, 296C259F6F86ABD6D4D15162E262E0B1 /* FBSDKLikeActionController.h */, A0EC3FABD68D980F29E217F43B8E7531 /* FBSDKLikeActionController.m */, 23A27F6D575E25C312B65E8A9904B718 /* FBSDKLikeActionControllerCache.h */, 89D7C0A0BD6013F82B4B5D8EBBDC4A98 /* FBSDKLikeActionControllerCache.m */, 9EB37E92D58767FCF62D088DC62ED5C2 /* FBSDKLikeBoxBorderView.h */, F4F13DEEC78A2EA3065FF203E4660B55 /* FBSDKLikeBoxBorderView.m */, 8CF7F766822A475D8B194105C5BD3E81 /* FBSDKLikeBoxView.h */, 57A52633C9C0C5FA2191B342B8DBB6D7 /* FBSDKLikeBoxView.m */, C1D2C05DC29BBFFBED4CFBED1C5A6E12 /* FBSDKLikeButton.h */, 4D2BCE0C3DC1E7FB0BE6E02ECEC19F2B /* FBSDKLikeButton.m */, D1EF1935E3B0AFCF73AC1E5676BC3307 /* FBSDKLikeButton+Internal.h */, FB4B3634A661281E58317EADEB114C90 /* FBSDKLikeButtonPopWAV.h */, 07EF944EFB6018776E00F7FA75BF0D01 /* FBSDKLikeButtonPopWAV.m */, 3B7482B2E7186DBE28DA80B8BBEFE69D /* FBSDKLikeControl.h */, D6858FA37A34E608E6179A5EE01A9D62 /* FBSDKLikeControl.m */, 5BF80BA302324AC6AEF69A593C8DEF28 /* FBSDKLikeControl+Internal.h */, 69B93026B22A6256BC91593D0060E4A7 /* FBSDKLikeDialog.h */, 0DAF20656ED36E53470D2DBF6D0FBD4C /* FBSDKLikeDialog.m */, C65B8B4258A289D02EEB422B96A89EF4 /* FBSDKLikeObjectType.h */, E76E62E37B5FC6CA07F3E99A07FF64FA /* FBSDKLikeObjectType.m */, F1C7C6ED4FC099A65098F800F96701A3 /* FBSDKLiking.h */, EB25923A3C24D72670801C96252FF023 /* FBSDKMessageDialog.h */, 8E08664A53F5655D415B1FE8A309FA30 /* FBSDKMessageDialog.m */, 61D578A4D092674413B4F810B65617E8 /* FBSDKMessengerIcon.h */, 7CD63C5B47C7DD78B701AFE52A61B10C /* FBSDKMessengerIcon.m */, F54A2AA54749108AF1EE5F405A33322F /* FBSDKSendButton.h */, CAF2E3BCF8134ECFEBAD9A4DAB39EB06 /* FBSDKSendButton.m */, A93C272A5F5F3856EDD3567597A6F6B0 /* FBSDKShareAPI.h */, B415354078EAF066BEEA2A2941FB7DDD /* FBSDKShareAPI.m */, 6C3C0A132E0782A93A180B945919D8AB /* FBSDKShareButton.h */, B0C5CC746ED5CBE775F12C5660AD1541 /* FBSDKShareButton.m */, B08AC453B44CE1E8B261D54410E3F0B9 /* FBSDKShareConstants.h */, EAD69571A07FB3D8D3FB6191BCDB7F69 /* FBSDKShareConstants.m */, 296F6C441E737F5D403A52D4A6659679 /* FBSDKShareDefines.h */, C43A78A5372F75EB57D137461A709703 /* FBSDKShareDialog.h */, D66F787B8DEE80A4542BD8B221A29756 /* FBSDKShareDialog.m */, 3FE6EB1A3A06BF08C38149DE373F02D6 /* FBSDKShareDialogMode.h */, 949E48FA38B27F20B10797133DACC6B1 /* FBSDKShareDialogMode.m */, DBBFC9D33690BE5B8CD94F27485FD494 /* FBSDKShareError.h */, 410531D8C1D4D3F7F42F12F7ED9D9951 /* FBSDKShareError.m */, F4F30481231EF67BD4487BBF6C5D1CB1 /* FBSDKShareKit.h */, 9A11B62A187E7DF271BED1C24DE60AD2 /* FBSDKShareKit+Internal.h */, 401B98C26CCE7BAC7B06C52BF65218A3 /* FBSDKShareLinkContent.h */, 4E0B8656F789272A8FBBDF797EEFF2E9 /* FBSDKShareLinkContent.m */, B09B5367079E398942D665788719ED06 /* FBSDKShareLinkContent+Internal.h */, 93C77F3F8273FA0EDE7F082BB7C6BE6C /* FBSDKShareMediaContent.h */, 3600C3929B2E962EBC7189EC010FC34B /* FBSDKShareMediaContent.m */, 1E415A3350D8CF5BECE3063DDAA0BE6D /* FBSDKShareOpenGraphAction.h */, 15316CB5F2E0A74B37A4B65C34168EAD /* FBSDKShareOpenGraphAction.m */, 373558AB5D05183762C694E29BDD49DF /* FBSDKShareOpenGraphContent.h */, 234EEAD5437409F3A7C37D7ADFB11D39 /* FBSDKShareOpenGraphContent.m */, BF6124C6F3541980379CB23661270EE2 /* FBSDKShareOpenGraphObject.h */, C18451DC83C885C1446AE0C026601489 /* FBSDKShareOpenGraphObject.m */, E6715DAD6D0684A20A87622BF8E0A551 /* FBSDKShareOpenGraphValueContainer.h */, B47A1F95345E84BC07B8AC72EBA943D5 /* FBSDKShareOpenGraphValueContainer.m */, 296E51807D61C9A541B3F4E81594BC16 /* FBSDKShareOpenGraphValueContainer+Internal.h */, C6A497B03B5633DDD9411F414F9F6373 /* FBSDKSharePhoto.h */, 14FF537E964BE5C76DF4B233527AD0CF /* FBSDKSharePhoto.m */, F76024F6A89EEA91F3F7CE0033C71B96 /* FBSDKSharePhotoContent.h */, B22FDA84998D1688B0DD780C38A80F0E /* FBSDKSharePhotoContent.m */, 8FE9770DE6951597524C4EE305EAACD3 /* FBSDKShareUtility.h */, 322BD0C3BEA3B1E5C0531B171EB81035 /* FBSDKShareUtility.m */, 2CC1A69AD010CB80F7ECC513E4343904 /* FBSDKShareVideo.h */, 00676AF610DA21956BC730C01D7298FD /* FBSDKShareVideo.m */, 17A80EE44E29E6E08FB9D28A2EBF7B4D /* FBSDKShareVideoContent.h */, 356DB9AFF70A7328E4141C2B7805D5C2 /* FBSDKShareVideoContent.m */, 338833E9EEBA4312501F310EA0F85CFD /* FBSDKSharing.h */, 6F4DEE2AB3EC71BDEDF7872D4DFBAD6B /* FBSDKSharingButton.h */, A72EBD6B3894AA3DCD35DA7D490A9270 /* FBSDKSharingContent.h */, FA1F9F6B6D37F39C85DB019B87701253 /* FBSDKVideoUploader.h */, BEDB9F06356271BE836C1075461A2E5F /* FBSDKVideoUploader.m */, 976586FE0A40ED4122528DC7A076DE63 /* Support Files */, ); path = FBSDKShareKit; sourceTree = ""; }; 4724E6210A8CA4320BA6232F2DB1B6CE /* Firebase */ = { isa = PBXGroup; children = ( 1C0D0508620AB7E64EFA91671764A778 /* Core */, ); path = Firebase; sourceTree = ""; }; 4982E05396FE7258BFEEC9650B1E12BB /* FBSDKCoreKit */ = { isa = PBXGroup; children = ( 1BD23CFB4A0B2C21AB6643701F7A53D7 /* _FBSDKTemporaryErrorRecoveryAttempter.h */, 6594B26F7080EF6B56DCB5ED6395DF1E /* _FBSDKTemporaryErrorRecoveryAttempter.m */, 53434689A20D327D05B13DD331C4F27D /* FBSDKAccessToken.h */, 67E43505100A6295D31ADED7C5FC9A1D /* FBSDKAccessToken.m */, 500C49C75006CC6F013D43A00F9E43BA /* FBSDKAccessTokenCache.h */, 1DA1AF8EE4E1991D2A0DF7BCD823E758 /* FBSDKAccessTokenCache.m */, 5C87CFBB77AFE7ED5094F696A20E00DD /* FBSDKAccessTokenCacheV3.h */, C1BAA4B321D5F11E1C62671BEA4CC582 /* FBSDKAccessTokenCacheV3.m */, C95CF36B007E563455F5296F4BF0218D /* FBSDKAccessTokenCacheV3_17.h */, FAA41E1A3AB2CDE00AC2A074261AA18B /* FBSDKAccessTokenCacheV3_17.m */, AE89EBA20669231D87F412BE0080CF31 /* FBSDKAccessTokenCacheV3_21.h */, C56454497F44EC43E8AD4122182BA797 /* FBSDKAccessTokenCacheV3_21.m */, 2C643A8A0CDCBDC00ECAB15922C9DA24 /* FBSDKAccessTokenCacheV4.h */, 9032105C5C5AA8354FCE77960A9887D5 /* FBSDKAccessTokenCacheV4.m */, FBF5EC3AC894B9183DB7EDA870D9A9CB /* FBSDKAccessTokenCaching.h */, 0DF2B5FCF45BF2A41A287E6BB8214F99 /* FBSDKAppEvents.h */, 969A5B09EED30468F88F2401AAEF5758 /* FBSDKAppEvents.m */, AC1EF366A578B87EA50F8772B5F8FB3F /* FBSDKAppEvents+Internal.h */, B7FB3070FF4872061FB66A25E85BF7CE /* FBSDKAppEventsDeviceInfo.h */, F8168C0CD4D0232D99DAFC627DD18468 /* FBSDKAppEventsDeviceInfo.m */, 10DB4B38151CCF261FB5B725FC3C1759 /* FBSDKAppEventsState.h */, C34A702F2DD7C4CF61FD075393BE6CAC /* FBSDKAppEventsState.m */, E3775D041D8EEC8ED6D0BBA93F4FDE46 /* FBSDKAppEventsStateManager.h */, 3FD407E320BE66588168BEB8DAFB77B8 /* FBSDKAppEventsStateManager.m */, B68D7B05294DC4B65D14D28CB5312A52 /* FBSDKAppEventsUtility.h */, 285EA1C5DE8FD4B3F7946555AA602481 /* FBSDKAppEventsUtility.m */, E327066FFF0F45B24255C9027C06334F /* FBSDKApplicationDelegate.h */, EE74E13A61B4A768AA0B8FFACF358EFF /* FBSDKApplicationDelegate.m */, C9AECD149DAA9CBBE44D0552225C4FFF /* FBSDKApplicationDelegate+Internal.h */, A8AE2299D370304260AD0BE1EE2F4799 /* FBSDKAppLinkResolver.h */, 0349FF89F9C33365619790DEDBA08F70 /* FBSDKAppLinkResolver.m */, 5F4133D976E5AC5E829D1D76612C9AB8 /* FBSDKAppLinkUtility.h */, 418F149D3D82EED551FD8535B54E541D /* FBSDKAppLinkUtility.m */, 3F727643E3C6321D531B62D7A265941C /* FBSDKAudioResourceLoader.h */, D2B0320B381026451CC830A8AC04FD6C /* FBSDKAudioResourceLoader.m */, D72C11AF3A74FB5E0B69AC82FD7BEB76 /* FBSDKBase64.h */, 56A18B2B02035244FF1C4670E485B31D /* FBSDKBase64.m */, 8BCB92F107DC90466A905DFE5FCDA41E /* FBSDKBoltsMeasurementEventListener.h */, A294C9820557DFCF402698559CD8EEFE /* FBSDKBoltsMeasurementEventListener.m */, DE14C7CF1D6A0C2E591C30AB03E3A304 /* FBSDKBridgeAPICrypto.h */, 67B6CEFEAC287216153D11E9CA2AB080 /* FBSDKBridgeAPICrypto.m */, 5845C018E4DD128CECEBF0909F0741FD /* FBSDKBridgeAPIProtocol.h */, CD8846B8FF6EE2E1CA42E78339D4AA6D /* FBSDKBridgeAPIProtocolNativeV1.h */, BFB22238BD35F9F2CB6B4C4B72394FD2 /* FBSDKBridgeAPIProtocolNativeV1.m */, 53989C78F19889101ABE4E633CA7AB5E /* FBSDKBridgeAPIProtocolType.h */, AE6CADA5CA6B23D2715AC2D9938757C7 /* FBSDKBridgeAPIProtocolWebV1.h */, B4023741CB92EC46CEB293AF1BF5F718 /* FBSDKBridgeAPIProtocolWebV1.m */, 3DF483014F5F35035670878A8FEC5C0D /* FBSDKBridgeAPIProtocolWebV2.h */, 1B28531CB7D39F0479D319C3355285B2 /* FBSDKBridgeAPIProtocolWebV2.m */, BA472FAE62F4170052081A3990353BCE /* FBSDKBridgeAPIRequest.h */, 40EB7017FCE21EF267F33905494BFE43 /* FBSDKBridgeAPIRequest.m */, FCE73BF6B4E09090F8B4D7EAE911A6EB /* FBSDKBridgeAPIRequest+Private.h */, 0D2BDE42CEA153BF1D92D881993DE575 /* FBSDKBridgeAPIResponse.h */, 9F6224EB54AEB5C2DE1DE420F9A43596 /* FBSDKBridgeAPIResponse.m */, D9F3A3FD7BD2508F05C8FBF147009DA3 /* FBSDKButton.h */, 8FD04A0F50673290125B8C62ED8506C4 /* FBSDKButton.m */, DBB02E482BD1DF480E6409A036C5FC12 /* FBSDKButton+Subclass.h */, C03EA17AC9B7FA3EF6873BD9015ECF79 /* FBSDKCloseIcon.h */, F1AF5D1C5557D2E36ACA410EE645160C /* FBSDKCloseIcon.m */, C93EDE5838549A4DDAF2016C59DD7FA0 /* FBSDKColor.h */, A5D4C2A33C852492DAF27E4A23F3DC33 /* FBSDKColor.m */, 3EA26D4657F56ED7C7AD3C7CF40938DF /* FBSDKConstants.h */, 800B0D395871B2D1804E151D5EC2B4DD /* FBSDKConstants.m */, 13EB02F3205B2D58148E051D3FE0495C /* FBSDKContainerViewController.h */, F51662A395C193FC0CD95DF4D613BCDA /* FBSDKContainerViewController.m */, 49FB2AE04082C4817E34C765D0CC168A /* FBSDKCopying.h */, EA7FBCFFA76DC9969D1C804EC5A2DF5E /* FBSDKCoreKit.h */, 50795EF8289E03FFD8A3E6F9B76FAE25 /* FBSDKCoreKit+Internal.h */, DDB995465AE9F9D7AFA7C1E10FD68131 /* FBSDKCrypto.h */, EFA1CD6866EC21FCF10919413F1D2141 /* FBSDKCrypto.m */, 289E794C1F5558F52ACC04E4BFE43EB8 /* FBSDKDialogConfiguration.h */, CC7EDD6E1F6211E24E396BF86C89B5B0 /* FBSDKDialogConfiguration.m */, 46CA2814DBE4937069A37145DEA3F89F /* FBSDKDynamicFrameworkLoader.h */, 8C76DA62C32050738F372FB86436B630 /* FBSDKDynamicFrameworkLoader.m */, FC56D94F5E6790B727E2400EF769F104 /* FBSDKError.h */, 69768F59318EE677B9D13A269EFC5AAD /* FBSDKError.m */, 6987C863B1CEBBD311F5CE3FB5DAEF3E /* FBSDKErrorConfiguration.h */, BA7945F87AC9D33609535DF4E917D6D5 /* FBSDKErrorConfiguration.m */, 3E5817463D8E6C05AE18A2727EE775AB /* FBSDKErrorRecoveryAttempter.h */, EB3472AD9F8972FD61773DA8DF704869 /* FBSDKErrorRecoveryAttempter.m */, 26053F1FAB9B2DA8CE98D25FD7F7F394 /* FBSDKErrorRecoveryConfiguration.h */, C6D6274B3F544F77220B92171CF9F919 /* FBSDKErrorRecoveryConfiguration.m */, E464801267CE346683BC078B76EF31AF /* FBSDKGraphErrorRecoveryProcessor.h */, 63803F001E344958E2374A6E2CF2D3B2 /* FBSDKGraphErrorRecoveryProcessor.m */, BAE798271E874DBB143FD87F7C9B5009 /* FBSDKGraphRequest.h */, 84D7111970DA475CC83DBD97DB62803D /* FBSDKGraphRequest.m */, 0705221C472B862B8D97A7E30C67C5C3 /* FBSDKGraphRequest+Internal.h */, 9C02168CB9621997A0F79BB3489C79BD /* FBSDKGraphRequestBody.h */, C1777F9C07CE6501DB231C2A30C7BFE0 /* FBSDKGraphRequestBody.m */, 86F122C0918E12CF55D9A81F9A003998 /* FBSDKGraphRequestConnection.h */, 3564E4DE0349A19993E8610CC040CC9A /* FBSDKGraphRequestConnection.m */, A24D533C6F87D953E9D4167CE6CCBD31 /* FBSDKGraphRequestConnection+Internal.h */, DDCA2DD0D90DEA85D29FC3C7A43E10DD /* FBSDKGraphRequestDataAttachment.h */, 6E8C117351A53CF2CF897455EC1A43E0 /* FBSDKGraphRequestDataAttachment.m */, 050BDEAD1916698E214AFB26A79288B0 /* FBSDKGraphRequestMetadata.h */, 95F51D818439DB35C2333ECF580CEAD7 /* FBSDKGraphRequestMetadata.m */, 916F359EF719D81C62ED80EE052EC6AB /* FBSDKGraphRequestPiggybackManager.h */, E8E73443DC19BD45AC2BE2F1D5DA6FEB /* FBSDKGraphRequestPiggybackManager.m */, B4CA25A29D26AF8E66E28490C969AF5B /* FBSDKIcon.h */, ACB414CD0EAEE64256401BCD8A426020 /* FBSDKIcon.m */, 3818796F76375FAF3283D90B9B1B6172 /* FBSDKInternalUtility.h */, 7B6976E4ED6C9EFA96E5199EC7E1C667 /* FBSDKInternalUtility.m */, C2CCD702DFCD015849180F62A26CFD95 /* FBSDKKeychainStore.h */, 855D8A1728D8820964F4D6A0312D7A5D /* FBSDKKeychainStore.m */, 5BFD3450928A0D3AB4430B03901CFCAB /* FBSDKKeychainStoreViaBundleID.h */, F75911B1C5FA2475BFF11249796F94D2 /* FBSDKKeychainStoreViaBundleID.m */, 57412D699CFA7F312241E647FC9D19A4 /* FBSDKLogger.h */, 6D292EA73AB2F774E99365CA751E06BF /* FBSDKLogger.m */, E5A7F39C006211ABC22FC3E7431BD43E /* FBSDKLogo.h */, 3368C70225DA4184943E1A027F4C750E /* FBSDKLogo.m */, 31381C7B24A5039BBB6CCF74EB2C2EF5 /* FBSDKMacros.h */, F5B5D8ADAEF759D6862C19B408FC4C58 /* FBSDKMaleSilhouetteIcon.h */, 678FFAFC127E69071CB03622EA32A27C /* FBSDKMaleSilhouetteIcon.m */, 4EAD10D545ACA391D87A813DC8B29B9B /* FBSDKMath.h */, 0E573958B4A3ED69E35F873DEF94A025 /* FBSDKMath.m */, 6D91C36CE02C714CF6686A657B9979E0 /* FBSDKMonotonicTime.h */, 1A542E25A53E3F8A0E0CF2B68F2F0B29 /* FBSDKMonotonicTime.m */, A8E2E6394893FE46321D0A87D90E8774 /* FBSDKMutableCopying.h */, EF7BC936D9DC70BBB915217A9BC6AAF5 /* FBSDKPaymentObserver.h */, AA72FA1E6640E44D8AF0EA9B06FF3FF3 /* FBSDKPaymentObserver.m */, 2A45B69EB5BAB1BBE74F78F69B839C90 /* FBSDKProfile.h */, DA2F8969582848AC7C57D2530917927E /* FBSDKProfile.m */, D2298735034342AA6ADB4F009EEFBF84 /* FBSDKProfile+Internal.h */, 7619958FDC7FDB339812E4C7FA92EA62 /* FBSDKProfilePictureView.h */, B6038486C630F3839521911A8E33D5A0 /* FBSDKProfilePictureView.m */, 8919F3FC23A317CC4BF4E8285929398A /* FBSDKServerConfiguration.h */, B4D3BA24C465B15F981E476FD5D9E3B4 /* FBSDKServerConfiguration.m */, 56B016FB0CBDC0DB06D82BAA62305478 /* FBSDKServerConfiguration+Internal.h */, B34CC697BCB8B6B4341DE153961C35D5 /* FBSDKServerConfigurationManager.h */, 60140D24CE91D843865E0ACF7ABC0810 /* FBSDKServerConfigurationManager.m */, 55E1F587AC7AD403D01F7E956416682E /* FBSDKServerConfigurationManager+Internal.h */, 98D2BF226F3B31B1A062BF6C4D02E928 /* FBSDKSettings.h */, 822A1AFEADDF1069BE0A1DBBCAD88637 /* FBSDKSettings.m */, E5F6F9EDBCDDE76BDC6C33E0669EF224 /* FBSDKSettings+Internal.h */, 302F33D66A77991641D9EABE527E2020 /* FBSDKSystemAccountStoreAdapter.h */, B29476575BC6F9F5CFB5F8DAF9604531 /* FBSDKSystemAccountStoreAdapter.m */, C450A354F9C39F28DDC4916ADFA5FA41 /* FBSDKTestUsersManager.h */, 3D9DB3883D692B0606CD7C950B471957 /* FBSDKTestUsersManager.m */, 7CD2C6B54FE2F8E9C9C0D350E8BAA1BA /* FBSDKTimeSpentData.h */, 3D46190A40A28D9477301E0E9F818EA8 /* FBSDKTimeSpentData.m */, 394DEC0187D9C4DD3025FCBDEE64E147 /* FBSDKTriStateBOOL.h */, 6B50E574550A9353C447811E34C10086 /* FBSDKTriStateBOOL.m */, AD33ECD19031FEF0B81D507EB39BD02D /* FBSDKTypeUtility.h */, 7F33E2D7EB6A1A15DFA3E425BE4CDBC1 /* FBSDKTypeUtility.m */, 1B74E1FBB9A29E0DA697CE9244BA863E /* FBSDKUIUtility.h */, 179F15CC373EBC2355183B3C2136DE83 /* FBSDKURLConnection.h */, 60AC0A7B43501C2A1D4BAF0FC1A03769 /* FBSDKURLConnection.m */, 9C1BD126961E83CEEFB3526EC233B08F /* FBSDKURLOpening.h */, 614120AD63FA0D77588B740BBB2F70B0 /* FBSDKURLSessionTask.h */, 16E1CFB4C583CB72BEA38953BF63E291 /* FBSDKURLSessionTask.m */, 124B31DDC1B0856244E71C50AF92CF6B /* FBSDKUtility.h */, D73633CF90D5AAD0C11B22324BF69CE1 /* FBSDKUtility.m */, 24B9BC43CDA1316D5C29C2814F5B936F /* FBSDKViewImpressionTracker.h */, D4D7A0BB6AA817122DC09D746FB66A67 /* FBSDKViewImpressionTracker.m */, 543C86122D60B63563B33DACF4683FC8 /* FBSDKWebDialog.h */, 2993229BA329377C244F962B75E1414E /* FBSDKWebDialog.m */, 0A076680535D6C630B144572313F884B /* FBSDKWebDialogView.h */, 8232C20793F566FF30C03A94BDA3EE78 /* FBSDKWebDialogView.m */, 756C22836CE61B26999CD7BBF8253C66 /* Resources */, B273553EB900B0450514BC8B31463A52 /* Support Files */, ); path = FBSDKCoreKit; sourceTree = ""; }; 4E773E7C22B0E8883A3E1B4B74B742AD /* Products */ = { isa = PBXGroup; children = ( 8FAB4FB8B643AEEA0D54BBB11648434D /* AFNetworking.framework */, 0A2D4836EB6721814767F5F092407237 /* Bolts.framework */, 37B9FAD0B18BDDA91409715A1166C5CB /* FBSDKCoreKit.framework */, 77F9752E0AC323470089489606BD1CF5 /* FBSDKLoginKit.framework */, 1798F04401CF6DDA8F03E7D82898E416 /* FBSDKShareKit.framework */, CC26118D0CC247921A80E8AD1177894A /* MBProgressHUD.framework */, 64A1D0C796E579900E531F219DE71031 /* Pods_PotterPics.framework */, D995EC9D92E9EEE5967826BB1E1BECB5 /* Pods_PotterPicsTests.framework */, 798886A25C16CC5888D2F649523DAFEA /* Pods_PotterPicsUITests.framework */, 6B74CD72A2D1FDBE15600ED4D1792E2B /* SwiftyJSON.framework */, ); name = Products; sourceTree = ""; }; 52285A9721EDE5524150AF6EB00F7265 /* Pods-PotterPics */ = { isa = PBXGroup; children = ( 8702D6DAE8FA08F9C1F699C735EA42F9 /* Info.plist */, 6F82BA38F430E19B732A14AFC9F6FA07 /* Pods-PotterPics.modulemap */, 69839F01D9DD138316CE78B1444C6523 /* Pods-PotterPics-acknowledgements.markdown */, 6C1978C4AD325134B2AD063BAB3B5FAA /* Pods-PotterPics-acknowledgements.plist */, 61D174F17C7058A08EC9658CFBC014B0 /* Pods-PotterPics-dummy.m */, DDB6041D8F8F89D75572007DECCF98B4 /* Pods-PotterPics-frameworks.sh */, DD33F0EE59FF3C4E50A5C36521C987FB /* Pods-PotterPics-resources.sh */, EF5C3346B26F744DBD314D4284287A88 /* Pods-PotterPics-umbrella.h */, A4DA14531EDBF80122B1186502DF438A /* Pods-PotterPics.debug.xcconfig */, B4BD47DBB5D86200A94802EA1CC0A77D /* Pods-PotterPics.release.xcconfig */, ); name = "Pods-PotterPics"; path = "Target Support Files/Pods-PotterPics"; sourceTree = ""; }; 62B2180E4E732408E4988FCDB8CDD556 /* Frameworks */ = { isa = PBXGroup; children = ( B818C9A9E4A1A3A6D7F30D62A87281EA /* FirebaseStorage.framework */, ); name = Frameworks; sourceTree = ""; }; 6496B61004EB8DB7E1FB4CACD543F072 /* Tasks */ = { isa = PBXGroup; children = ( 4D509173ECC78BD99B42F22A17D81FB5 /* BFCancellationToken.h */, 7EB7BD93203502485FD103872BC356F3 /* BFCancellationToken.m */, 6A7898F3536B5C094F621EC7E3310342 /* BFCancellationTokenRegistration.h */, 18232EEB415F885FD50804B08FAA7118 /* BFCancellationTokenRegistration.m */, CCD86D5BDACC24412DF3B69EFA3F6C1E /* BFCancellationTokenSource.h */, AF6C35358530931A262498189B73AD23 /* BFCancellationTokenSource.m */, 8576C6B324FE7A205D9EE0109D560DEB /* BFExecutor.h */, CC1E31B7EF7D80815F0DF17659122C16 /* BFExecutor.m */, 718E2D10A7A72D21C487CA83B3F5A13F /* BFTask.h */, FA00C1C3274A7E11FF27A45C4CE750C2 /* BFTask.m */, 7645ABECFC91260CE63FE96F1F0F938A /* BFTask+Exceptions.h */, BD13EABB51615CBC9F07BB5ABD554881 /* BFTask+Exceptions.m */, 6AF1AB60322572242167BDB50A1044A8 /* BFTaskCompletionSource.h */, A5E4C2CB0C115FCE208B405B681F1189 /* BFTaskCompletionSource.m */, E47F8F57287DE302CE0477B586E91983 /* Bolts.h */, 73CC49F1A238A9C23974D3948CD7BC41 /* Bolts.m */, ); name = Tasks; sourceTree = ""; }; 657D9F0C96F7BD94D01B1CD45FADC9E5 /* Targets Support Files */ = { isa = PBXGroup; children = ( 52285A9721EDE5524150AF6EB00F7265 /* Pods-PotterPics */, CA01EB82A4E8527EF89988E8624F1EF2 /* Pods-PotterPicsTests */, 1FEE8DFFE6246E8C21E874D6A14E27D4 /* Pods-PotterPicsUITests */, ); name = "Targets Support Files"; sourceTree = ""; }; 70A6921175D4A8308DE8EF7CBE3BD6A3 /* GoogleUtilities */ = { isa = PBXGroup; children = ( 8EE180C29A0900F955EE77A155CC9FFA /* Frameworks */, ); path = GoogleUtilities; sourceTree = ""; }; 756C22836CE61B26999CD7BBF8253C66 /* Resources */ = { isa = PBXGroup; children = ( CDDE60295A376CD8BB037C7A798D32CE /* FacebookSDKStrings.bundle */, ); name = Resources; sourceTree = ""; }; 7DB346D0F39D3F0E887471402A8071AB = { isa = PBXGroup; children = ( 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, AD3858DFA1AA5CAAADB08BB8740E8FF2 /* Frameworks */, 140210B87FE481206F76E74AE73F1DCC /* Pods */, 4E773E7C22B0E8883A3E1B4B74B742AD /* Products */, 657D9F0C96F7BD94D01B1CD45FADC9E5 /* Targets Support Files */, ); sourceTree = ""; }; 7EFAFBAFA67E1BDEAD52514FDC30F060 /* Frameworks */ = { isa = PBXGroup; children = ( 09F160AC488F6438F48A20FA5494D9D5 /* FirebaseDatabase.framework */, ); name = Frameworks; sourceTree = ""; }; 7F79E197FB2DB8A2BDFB65EAA4C994C4 /* Frameworks */ = { isa = PBXGroup; children = ( 50589C937F0DD29347C47E4872783BF5 /* FirebaseAuth.framework */, ); name = Frameworks; sourceTree = ""; }; 8322BF8243B7C632009ED4D343AC4E2D /* GoogleNetworkingUtilities */ = { isa = PBXGroup; children = ( 0B39A7A390233854DC5FDE5F564DD019 /* Frameworks */, ); path = GoogleNetworkingUtilities; sourceTree = ""; }; 8346E198A1B7CDF557568DBB988D2D62 /* GoogleSymbolUtilities */ = { isa = PBXGroup; children = ( A6C3937E57CEAD5EF22A59E7BDAC45A8 /* Frameworks */, ); path = GoogleSymbolUtilities; sourceTree = ""; }; 866255CBF307F3FBDC75888A6384A697 /* AFNetworking */ = { isa = PBXGroup; children = ( 718B950C70F3134649C4AFE37F4F807F /* AFNetworking.h */, EBD2E7BB5F068DBAF2DD4FBD75C98197 /* NSURLSession */, 8A972C5634CD1A32D0D823A8A2433ABC /* Reachability */, AE176F3EFA5281F9E0FEBB28BE44A2A4 /* Security */, 88599BB7F25D0B0D30F85947532A374E /* Serialization */, B299337DCC854DE146EB9DB282028F51 /* Support Files */, B752EEB13E58CAA66DDFF9D09D82C1CC /* UIKit */, ); path = AFNetworking; sourceTree = ""; }; 88599BB7F25D0B0D30F85947532A374E /* Serialization */ = { isa = PBXGroup; children = ( E5C2EE94032E562AA6883D2FE9C5201C /* AFURLRequestSerialization.h */, ACA8F295B43D163B70210857413B38D2 /* AFURLRequestSerialization.m */, DC96BE4A20B07F3244063DF2220E0AB4 /* AFURLResponseSerialization.h */, 325A848210CDC11F2737F04B83826DB3 /* AFURLResponseSerialization.m */, ); name = Serialization; sourceTree = ""; }; 8A0A4975AC8D1E100CDF4EF9FF4366F1 /* Support Files */ = { isa = PBXGroup; children = ( E3B0B71896AC656CAFFDBC3027C80295 /* Info.plist */, F6324761E83B8DF5653AD7DFBAD00A5F /* MBProgressHUD.modulemap */, 83B9FE5A6E28DEC5A912C0035C98DEC1 /* MBProgressHUD.xcconfig */, 7D10491C882280228A0100282683FB39 /* MBProgressHUD-dummy.m */, 83ED9F692E90D19913DC15CF4A142A24 /* MBProgressHUD-prefix.pch */, A2526D92C805D78393CCA38F2F559B1A /* MBProgressHUD-umbrella.h */, ); name = "Support Files"; path = "../Target Support Files/MBProgressHUD"; sourceTree = ""; }; 8A972C5634CD1A32D0D823A8A2433ABC /* Reachability */ = { isa = PBXGroup; children = ( 404F63CB215FA69CA32209AE8B409949 /* AFNetworkReachabilityManager.h */, EC41976D2B74FA9072C676F86517427B /* AFNetworkReachabilityManager.m */, ); name = Reachability; sourceTree = ""; }; 8ADA64AA3B0C1806273BFB004119BC6A /* FirebaseDatabase */ = { isa = PBXGroup; children = ( 7EFAFBAFA67E1BDEAD52514FDC30F060 /* Frameworks */, ); path = FirebaseDatabase; sourceTree = ""; }; 8CBC998AFA79215C7C21E55565581E4F /* Support Files */ = { isa = PBXGroup; children = ( 26FED6B2BD5A31C35B34A0BC3F52A09F /* FBSDKLoginKit.modulemap */, 4E85A2F1733B0E0D31747F4281783C80 /* FBSDKLoginKit.xcconfig */, 85DA2F1CED9B84902AB69D909A20804A /* FBSDKLoginKit-dummy.m */, 362743812A3C9D8AF7C3140A261E9CD8 /* FBSDKLoginKit-prefix.pch */, 205386F477BF64F1FF7054572AB0EC3C /* FBSDKLoginKit-umbrella.h */, 0E1FB642714DF285B00B1FBC79ABCDA8 /* Info.plist */, ); name = "Support Files"; path = "../Target Support Files/FBSDKLoginKit"; sourceTree = ""; }; 8EE180C29A0900F955EE77A155CC9FFA /* Frameworks */ = { isa = PBXGroup; children = ( 0A58FC28910ED59F914BAC490A56EAEB /* GoogleUtilities.framework */, ); name = Frameworks; sourceTree = ""; }; 976586FE0A40ED4122528DC7A076DE63 /* Support Files */ = { isa = PBXGroup; children = ( A8D85DD7E80E7208649B23CAD32AAE0A /* FBSDKShareKit.modulemap */, 092A7AF28E09B340E2144F1A7C3DB11D /* FBSDKShareKit.xcconfig */, C58C011E0A74E340CC9F79605F65D85A /* FBSDKShareKit-dummy.m */, 317894220C20B4473C3E8A4ECCFEA2C0 /* FBSDKShareKit-prefix.pch */, D5EB9C9B78B77B89CEEB5F087D46C5D1 /* FBSDKShareKit-umbrella.h */, C34835953FB9E3EE76D3990C85A3BD09 /* Info.plist */, ); name = "Support Files"; path = "../Target Support Files/FBSDKShareKit"; sourceTree = ""; }; A6C3937E57CEAD5EF22A59E7BDAC45A8 /* Frameworks */ = { isa = PBXGroup; children = ( 3104FCCA4195E114CCF8D258D1081BDE /* GoogleSymbolUtilities.framework */, ); name = Frameworks; sourceTree = ""; }; A83101FA1ACFE648E790A6EB30044817 /* FirebaseInstanceID */ = { isa = PBXGroup; children = ( 02CACB6F83DC041FD72EAB30A93637E5 /* FIRInstanceID.h */, D4EC6D240F64C8E3BC61764BBAF0BFF7 /* Frameworks */, ); path = FirebaseInstanceID; sourceTree = ""; }; AD3858DFA1AA5CAAADB08BB8740E8FF2 /* Frameworks */ = { isa = PBXGroup; children = ( 10E426D732CEC0BDD792FCFFDFC725C3 /* Bolts.framework */, 6E9C62EB5AB13006083EC3A1F3519FC4 /* FBSDKCoreKit.framework */, 250FF8298CECE72D65369DC0C1774C98 /* iOS */, ); name = Frameworks; sourceTree = ""; }; AE176F3EFA5281F9E0FEBB28BE44A2A4 /* Security */ = { isa = PBXGroup; children = ( 9A55A04F0794E3AED3095BF9F3F91384 /* AFSecurityPolicy.h */, 1BD82AD0020AF025735DBEE92D90EC9B /* AFSecurityPolicy.m */, ); name = Security; sourceTree = ""; }; B273553EB900B0450514BC8B31463A52 /* Support Files */ = { isa = PBXGroup; children = ( 83ACD3E40857AE4A1FC5610CA37B8363 /* FBSDKCoreKit.modulemap */, 23D3CB6E9A2578A033EBBD68B00CC950 /* FBSDKCoreKit.xcconfig */, B1699EFE891F2CEBC1D7AFE5B9D55701 /* FBSDKCoreKit-dummy.m */, 28EB58143BEE37AB589682ABF4EC785D /* FBSDKCoreKit-prefix.pch */, 60BA4F2856A8EE256F5FD5D10DB27395 /* FBSDKCoreKit-umbrella.h */, 69FF9E1FA7A8337DF653E048F2CD3165 /* Info.plist */, ); name = "Support Files"; path = "../Target Support Files/FBSDKCoreKit"; sourceTree = ""; }; B299337DCC854DE146EB9DB282028F51 /* Support Files */ = { isa = PBXGroup; children = ( 0755A353614ED13BF9C7DFF951D0E953 /* AFNetworking.modulemap */, 30604910CF1BC094BCC4758C0D9FFAC1 /* AFNetworking.xcconfig */, D37DBF6D698BB99BFFC4CB01A283B435 /* AFNetworking-dummy.m */, 7C480B91C78A94655BECB08834F46BF3 /* AFNetworking-prefix.pch */, 78E89BE08BF96B56B9C8BB7C1A0134E0 /* AFNetworking-umbrella.h */, 5BB3A3C6F9289BF7974B50EBA7966EA2 /* Info.plist */, ); name = "Support Files"; path = "../Target Support Files/AFNetworking"; sourceTree = ""; }; B752EEB13E58CAA66DDFF9D09D82C1CC /* UIKit */ = { isa = PBXGroup; children = ( 64BC906D3B3F04EF99E4F99888D14BFD /* AFAutoPurgingImageCache.h */, 6154A9766C3A3BCA58EF4EBA4038751C /* AFAutoPurgingImageCache.m */, F696FAB825675820258C0860126EB967 /* AFImageDownloader.h */, 2257964A3F9373499E0DA0099EEB778E /* AFImageDownloader.m */, 4BA07E6014E4446BC05C4593902E8FED /* AFNetworkActivityIndicatorManager.h */, A9D0227C8AF275CF95C09168D0B754B9 /* AFNetworkActivityIndicatorManager.m */, B5BABD9E98394148DDF630511B7E8095 /* UIActivityIndicatorView+AFNetworking.h */, 4747C6A0E75EBEDCF1246631896B81A2 /* UIActivityIndicatorView+AFNetworking.m */, BB144CFDE6AF6A88F63BC0B5D75AD5F3 /* UIButton+AFNetworking.h */, B8E5EDD2E5CE2CD25F918C7F6C0E6CB2 /* UIButton+AFNetworking.m */, DEA2562FC7F4C75E4E3C454A1A88CF70 /* UIImage+AFNetworking.h */, 3419D37B887BC1CE701D49ED228E9436 /* UIImageView+AFNetworking.h */, 0AD5FFE35DAAACBC54403D264F0BE44C /* UIImageView+AFNetworking.m */, F0AC2705D48C5A4C7DE0885AB3E06FB1 /* UIKit+AFNetworking.h */, 2A032B4D7063E2F7F39E624712161E3C /* UIProgressView+AFNetworking.h */, 20CE7239B1D2FDDB8288044920159A7D /* UIProgressView+AFNetworking.m */, B6AC322AFE8269208192FA62AD2A219F /* UIRefreshControl+AFNetworking.h */, 7F2F1C57FA99F5807769A238263BD45D /* UIRefreshControl+AFNetworking.m */, B3BF0923C01840E90921E5BCD8CEC87E /* UIWebView+AFNetworking.h */, B90052B3335BE6C11194A4B1B3EB1F69 /* UIWebView+AFNetworking.m */, ); name = UIKit; sourceTree = ""; }; BCEEF5CCF7B62C07835D784540E4815E /* MBProgressHUD */ = { isa = PBXGroup; children = ( 9CBF89B1639B480078C319B893452776 /* MBProgressHUD.h */, A8D64AE9FE48CBC32B35A212E4B461C6 /* MBProgressHUD.m */, 8A0A4975AC8D1E100CDF4EF9FF4366F1 /* Support Files */, ); path = MBProgressHUD; sourceTree = ""; }; BEA2CDD5E8EBC7C06822C6FB5E091445 /* Support Files */ = { isa = PBXGroup; children = ( D7498DE1F0631DBC817CBEBF48DEE4D1 /* Info.plist */, DEA93732FBB84B8F7041EACCC7E04C28 /* SwiftyJSON.modulemap */, 1D9675CE2687A056DD6C5B6D2FE1612F /* SwiftyJSON.xcconfig */, 2CDA368B9F67E0B774EA1AC6F3142A78 /* SwiftyJSON-dummy.m */, 0A7D9A300470671F595569D849059CAA /* SwiftyJSON-prefix.pch */, 3C5FC5BC8940E982554939347A24EFFF /* SwiftyJSON-umbrella.h */, ); name = "Support Files"; path = "../Target Support Files/SwiftyJSON"; sourceTree = ""; }; C6F585FA1AA87D4ABCD6AC37C84A8E6E /* FBSDKLoginKit */ = { isa = PBXGroup; children = ( E5499B12C2B8CAC69028FF98296B9B10 /* _FBSDKLoginRecoveryAttempter.h */, 40A0330BAC9BB3AA5026B8F00AC08079 /* _FBSDKLoginRecoveryAttempter.m */, 9D47EAC837C24B66E7DF055BB3F46694 /* FBSDKLoginButton.h */, A0B37EFD471FF5DEECEE4775C9AC24A7 /* FBSDKLoginButton.m */, CAA129C29843E84557F30FA22E3BD93C /* FBSDKLoginCompletion.h */, A2F3964515C2693109855A15979E3DE9 /* FBSDKLoginCompletion.m */, 09CCCCC909E043460B5C164D04C39DCE /* FBSDKLoginCompletion+Internal.h */, C67B3396039B22A161B9FFC678BEF36C /* FBSDKLoginConstants.h */, E120AA6183A04CF6357B5A672B44C9B7 /* FBSDKLoginConstants.m */, 09FCBDC873BEAA3952579FB53590F48F /* FBSDKLoginError.h */, E4A9423C5315B0FFA7996239E7E13BC1 /* FBSDKLoginError.m */, 5B08B8F4C78247FC48A72B438A6CBBB6 /* FBSDKLoginKit.h */, FD8FD30657D301CAC2E078975D5035FD /* FBSDKLoginKit+Internal.h */, 674612913AD6C74859A7D27EA17410D4 /* FBSDKLoginManager.h */, 17F4407284C3041C1FB4B7B9946068A6 /* FBSDKLoginManager.m */, D06DF8B0C5E620647EF9C1A634661190 /* FBSDKLoginManager+Internal.h */, 9C085C3A1C9636BF6C842DE91E406454 /* FBSDKLoginManagerLogger.h */, 355EAFC2BF57DCFF081CC4F62BEFA490 /* FBSDKLoginManagerLogger.m */, B43763897ABF0E93E17BF93AB719E3F8 /* FBSDKLoginManagerLoginResult.h */, D0EF04BF188BEED43329404FE99E480A /* FBSDKLoginManagerLoginResult.m */, 9B849A31AF3D7B0536BAF097C883CE83 /* FBSDKLoginManagerLoginResult+Internal.h */, 52103E91501D5814A590442E9FDBE139 /* FBSDKLoginTooltipView.h */, 7799E170550970BBF284103DCCAB56B4 /* FBSDKLoginTooltipView.m */, 4A39E686532C21963B8155F97482BCF6 /* FBSDKLoginUtility.h */, CA407D693530EF67FBB1EA3D2C81B497 /* FBSDKLoginUtility.m */, 071D9291B24AAEC6A06D97DC10C701E7 /* FBSDKTooltipView.h */, 7A210A47B0DF6B6CBBBFB5FEA7C82DD2 /* FBSDKTooltipView.m */, 8CBC998AFA79215C7C21E55565581E4F /* Support Files */, ); path = FBSDKLoginKit; sourceTree = ""; }; CA01EB82A4E8527EF89988E8624F1EF2 /* Pods-PotterPicsTests */ = { isa = PBXGroup; children = ( E0B676F7AE322CC9E13D2570ABF0D500 /* Info.plist */, D6C5B5EE3BEAC1E82C7AEC21832CAECD /* Pods-PotterPicsTests.modulemap */, 17CD4565C4615C5E205842C287BE17C7 /* Pods-PotterPicsTests-acknowledgements.markdown */, A25F1AD85C4CA314BD8B8126647894D8 /* Pods-PotterPicsTests-acknowledgements.plist */, 1F71BFA8EDBB8BE5A3A1072C32B5DD3A /* Pods-PotterPicsTests-dummy.m */, 605285DA6D71717B3D3ABF2FD7A667EC /* Pods-PotterPicsTests-frameworks.sh */, ED0F0038D42615B65492BEFC1D3A5FC0 /* Pods-PotterPicsTests-resources.sh */, D751570D07A6198A619045C589D426A9 /* Pods-PotterPicsTests-umbrella.h */, 3FE115C8BE13A55F5DF0A63878484024 /* Pods-PotterPicsTests.debug.xcconfig */, C8AA990ECA07A22AF023B8A8DCF96F15 /* Pods-PotterPicsTests.release.xcconfig */, ); name = "Pods-PotterPicsTests"; path = "Target Support Files/Pods-PotterPicsTests"; sourceTree = ""; }; D0F500766380E6CC333E532F0E5BB708 /* FirebaseStorage */ = { isa = PBXGroup; children = ( 62B2180E4E732408E4988FCDB8CDD556 /* Frameworks */, ); path = FirebaseStorage; sourceTree = ""; }; D4B233D9904E69F21CFFCAF8D4B8E96E /* Bolts */ = { isa = PBXGroup; children = ( E35EB92E016F8CCC8136512B42FA8084 /* AppLinks */, F5CECFB3C8474A03D52DD7705851CC69 /* Support Files */, 6496B61004EB8DB7E1FB4CACD543F072 /* Tasks */, ); path = Bolts; sourceTree = ""; }; D4EC6D240F64C8E3BC61764BBAF0BFF7 /* Frameworks */ = { isa = PBXGroup; children = ( C060D6E271F89351A2BB235894E4E44E /* FirebaseInstanceID.framework */, ); name = Frameworks; sourceTree = ""; }; DDF3ED8303E9FD16180F54ED417E3603 /* Frameworks */ = { isa = PBXGroup; children = ( 3492694E100163219853B812C221B158 /* FirebaseAnalytics.framework */, ); name = Frameworks; sourceTree = ""; }; E01C9E7F6FFCF138B86B1D72F282C269 /* GoogleInterchangeUtilities */ = { isa = PBXGroup; children = ( 3904B437DC1AEF620A02F799280ED74F /* Frameworks */, ); path = GoogleInterchangeUtilities; sourceTree = ""; }; E1045DA9889AB5BB5861077CF8672EE6 /* FirebaseAnalytics */ = { isa = PBXGroup; children = ( DDF3ED8303E9FD16180F54ED417E3603 /* Frameworks */, ); path = FirebaseAnalytics; sourceTree = ""; }; E35EB92E016F8CCC8136512B42FA8084 /* AppLinks */ = { isa = PBXGroup; children = ( 55F1ED0FA41DA559ACA70075456C78E0 /* BFAppLink.h */, 2E1AB7D493DCC2425913A6C4876BE077 /* BFAppLink.m */, C1A016781B2CFFF3675BBD3E47ECBEEF /* BFAppLink_Internal.h */, 7B81D75978055EB91A7F320BEA156D53 /* BFAppLinkNavigation.h */, EC52AD4D8DBD5728FE40009628C28BDC /* BFAppLinkNavigation.m */, D6DEC30656F6CB2F37C4C8127F8A6B19 /* BFAppLinkResolving.h */, 4F9824B0ED4577D5374BC2CB42CD0687 /* BFAppLinkReturnToRefererController.h */, C8F73117E940B605910F515665016FA9 /* BFAppLinkReturnToRefererController.m */, CC141E7006767F72BFBBA10C3EF7924D /* BFAppLinkReturnToRefererView.h */, 417010D9205941599775F7E5B437FA89 /* BFAppLinkReturnToRefererView.m */, 3ABB7E09BE20FAE0E0F42F34FBD487CC /* BFAppLinkReturnToRefererView_Internal.h */, B11CD9C22ABED727DBA3C605481D722B /* BFAppLinkTarget.h */, B333B404501B047047F3294F00FC52A8 /* BFAppLinkTarget.m */, AD53C2272608B872C324855ECB5511D9 /* BFMeasurementEvent.h */, 0A125CDAF09D1BA4CC6380D652520C21 /* BFMeasurementEvent.m */, 15B643D9CA5F7D4DF2406B76D08469DA /* BFMeasurementEvent_Internal.h */, C5CD1E73DFD39E5D339E021817B9DA2F /* BFURL.h */, 64F241D129894E6FBF8D9AC83C2333EA /* BFURL.m */, CAC188BFAD7FD3006FDEAA6F11B98188 /* BFURL_Internal.h */, B6C4053DC4067A1964C8D3A08AB1AA0A /* BFWebViewAppLinkResolver.h */, B13B01C1E5FD1A5170F6BF0ADA24F303 /* BFWebViewAppLinkResolver.m */, ); name = AppLinks; sourceTree = ""; }; EBD2E7BB5F068DBAF2DD4FBD75C98197 /* NSURLSession */ = { isa = PBXGroup; children = ( E75958EF9F3DB83089704F6DF0207418 /* AFHTTPSessionManager.h */, 442A884AB0F3C44425BEF2E15FD50E0C /* AFHTTPSessionManager.m */, FFB5F1ED229E2F69AA805EDD810F893A /* AFURLSessionManager.h */, 7C4CD1BAB77A875F0B791189A9DF7A89 /* AFURLSessionManager.m */, ); name = NSURLSession; sourceTree = ""; }; EE676BF0157B1EAC147C75FD41346566 /* SwiftyJSON */ = { isa = PBXGroup; children = ( 9E079AE02625BC14DAD98571BEBEB8BF /* SwiftyJSON.swift */, BEA2CDD5E8EBC7C06822C6FB5E091445 /* Support Files */, ); path = SwiftyJSON; sourceTree = ""; }; F5CECFB3C8474A03D52DD7705851CC69 /* Support Files */ = { isa = PBXGroup; children = ( 6D76B8BE53FDB639900DA4D06EA2E84F /* Bolts.modulemap */, 7DB5DEB6C6536F5E4950DAFE15ADD32B /* Bolts.xcconfig */, D28EF19A899EA7B11BFB90D1F8F63312 /* Bolts-dummy.m */, F138F36ECB86181177EF7EF47562C6C6 /* Bolts-prefix.pch */, 785F63E278C09554AFFFCF5F7CDF4A84 /* Bolts-umbrella.h */, 7231BFB6B059FC20AB187BBFAA6543EA /* Info.plist */, ); name = "Support Files"; path = "../Target Support Files/Bolts"; sourceTree = ""; }; FC0BF23738CFB88D051A22669372DF5F /* FirebaseCore */ = { isa = PBXGroup; children = ( 3E4671CBB7BD8B00D615EE0A19EA2DB0 /* Frameworks */, ); path = FirebaseCore; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ 097FC3C42F055F1EADF246AAC10B811B /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 0EBC761E8EDAA546EC6F17F60255D437 /* Pods-PotterPics-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 0A96B59D57F3AC923626746E801DDE9C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 4DA130F813859583C3363088029A470E /* _FBSDKLoginRecoveryAttempter.h in Headers */, F294B75539C74EDB0B55D2350874A225 /* FBSDKLoginButton.h in Headers */, 14CCB9B9C95EBBD456D7E4EABD82E0BF /* FBSDKLoginCompletion+Internal.h in Headers */, C9B57D939AB4480C7A93482A12D87C4B /* FBSDKLoginCompletion.h in Headers */, AD52B349A273F0EB40F823990A40D2CD /* FBSDKLoginConstants.h in Headers */, 3249F988C94C1B64192C42A11902D850 /* FBSDKLoginError.h in Headers */, C583FF6D5F3A73498E46D8D80B21E3DB /* FBSDKLoginKit+Internal.h in Headers */, F7581524FBA63576F76650BAC9B15C04 /* FBSDKLoginKit-umbrella.h in Headers */, D80E3A1971AF7FDCE82F3241BA53B59B /* FBSDKLoginKit.h in Headers */, 334A9EB0A89E519A4CD425EF39DCDA2F /* FBSDKLoginManager+Internal.h in Headers */, 86C7B4DC7245C1E31565C74EBC34B5A8 /* FBSDKLoginManager.h in Headers */, 1200A152A08388893BFA023980C2CF48 /* FBSDKLoginManagerLogger.h in Headers */, 683FC99BAEA8DDE9EBEE2EC93F949B36 /* FBSDKLoginManagerLoginResult+Internal.h in Headers */, 828A250670EEC2897DACA767080A8CA7 /* FBSDKLoginManagerLoginResult.h in Headers */, 6817DE148CDBD0D314AFC83255A645E4 /* FBSDKLoginTooltipView.h in Headers */, 0FB1CE9AB76B77BEFC2F5DD025EB6032 /* FBSDKLoginUtility.h in Headers */, 49239C6CF815B92F2DF5B5D79FB9B5AF /* FBSDKTooltipView.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 1F5CDCB9D8E0BB0975E3797EDC45AB2F /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( D711EBBB664A6ED7779B62B8710FB875 /* MBProgressHUD-umbrella.h in Headers */, EAF4063C5D3C8C1AE3C7513759BA9D0B /* MBProgressHUD.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 3511C1F36FCF6C4EC47AA2DC29120550 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( D54C8902B21F00E3539FC2E2A1645077 /* Pods-PotterPicsUITests-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 6D09F8779E5E745FE223A9CA1BCE1535 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( C6BED30D7A2A56482A411EDAECCEDCBF /* Pods-PotterPicsTests-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 75B2517624D989B002D158AD8353146C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( F759176BF99FB3C01BA3EEE8C6A40D2A /* BFAppLink.h in Headers */, A3CE342B34D0DAA7BE2AA45BEF94CAFC /* BFAppLink_Internal.h in Headers */, E39ED3657FEE321A20AE105D8BE1A340 /* BFAppLinkNavigation.h in Headers */, 7BB98E50240143972C28AA9A13EBC3D5 /* BFAppLinkResolving.h in Headers */, 5F26B65B4A4711EB4BC2BC9BC48FF041 /* BFAppLinkReturnToRefererController.h in Headers */, CDE764570B1C9BED83BD2F23533A3097 /* BFAppLinkReturnToRefererView.h in Headers */, AE88CF4A135C8C1E79FEBB43EE2B38F8 /* BFAppLinkReturnToRefererView_Internal.h in Headers */, D8E3EF0B890201C0DD54E9CF5527F88C /* BFAppLinkTarget.h in Headers */, 5493E80E04D895A735853EA349C4AAE3 /* BFCancellationToken.h in Headers */, 7333194276505D454DACD2603FEE0271 /* BFCancellationTokenRegistration.h in Headers */, 1DCFCA14CBF89C36D853B87417E126E6 /* BFCancellationTokenSource.h in Headers */, 24600483CE2FB9BBDED179CCC892F3F8 /* BFExecutor.h in Headers */, 6E2B6054F217E3D01C59665D011B09B1 /* BFMeasurementEvent.h in Headers */, F83D82020F9347F75495D09AA4F295AE /* BFMeasurementEvent_Internal.h in Headers */, 6A8B92B5BDFBEE6BD3F70901FB71A0B1 /* BFTask+Exceptions.h in Headers */, 7C7E248D341E116E1A7B8C16A8F58C6B /* BFTask.h in Headers */, A877EB9CF2930345DD962B4BC0D24959 /* BFTaskCompletionSource.h in Headers */, DFC3DF985B5065268315681B81A235DE /* BFURL.h in Headers */, BC82780C5FED62B06DC51F6DCA0491B5 /* BFURL_Internal.h in Headers */, 8170C4AC05E84ED31A9D33A4CD205D2C /* BFWebViewAppLinkResolver.h in Headers */, 9E40001D7D2CAC32039C59FC0208A7CA /* Bolts-umbrella.h in Headers */, 9B045FC64D2A32D380593AEA86A28904 /* Bolts.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; 7C6A0D99A9CC32A19A92A62F8A941139 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( CAC483EF637FB4A2C2E2FC75BA631B87 /* AFAutoPurgingImageCache.h in Headers */, AB39AC9746E7575D7449700475E41B0B /* AFHTTPSessionManager.h in Headers */, 5808B477EFF509D810B5CDCFDC944F80 /* AFImageDownloader.h in Headers */, 1480F4923DBBF217F60572EEECB4027C /* AFNetworkActivityIndicatorManager.h in Headers */, EC7CADE416A78A1CD6936018A6695126 /* AFNetworking-umbrella.h in Headers */, E7988678C81F7CCB95D239375FC6986D /* AFNetworking.h in Headers */, 68152D921ABF6A423C192C04FDF94F0F /* AFNetworkReachabilityManager.h in Headers */, C2DD28375E1F0B1D0D1D2E4E607C499F /* AFSecurityPolicy.h in Headers */, 20EE8030FCF2402DAC7F1C9B9DDAEF79 /* AFURLRequestSerialization.h in Headers */, 7332F15718920917F544F35CE2C038AA /* AFURLResponseSerialization.h in Headers */, 560698A4D707DCBCC1C8F98BC9B89B23 /* AFURLSessionManager.h in Headers */, 1E5B8F12ED7CC40ECDB9B1F755F387E5 /* UIActivityIndicatorView+AFNetworking.h in Headers */, 81B617F8D26BB10C5726D75E85D21EB7 /* UIButton+AFNetworking.h in Headers */, 9E1E90DED74B73ECE53C9AD76DE53E2D /* UIImage+AFNetworking.h in Headers */, 60E3009342BEE96D32C546BE2DB60052 /* UIImageView+AFNetworking.h in Headers */, 659960F7E28E993E08CCC1E8A383E710 /* UIKit+AFNetworking.h in Headers */, D9F4E833E37B611B432F6B5D7072DDA2 /* UIProgressView+AFNetworking.h in Headers */, C6354FEC7728A4C86DAD8092509BA7D4 /* UIRefreshControl+AFNetworking.h in Headers */, AE2A07407FB50BA249984DC0620E84C0 /* UIWebView+AFNetworking.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; C04D6378BBFBBFCD2C4246D7CF2B0E3B /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( D733DF9E662E26A7E088F42481BD4226 /* SwiftyJSON-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; C4D4C46F1749D8A334B16CADF82EEE9C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 0276287E0E8F78A9E56AB05E8DCD3DE1 /* FBSDKAppGroupAddDialog.h in Headers */, 406804221AD8D7EC71E4CC582AF7B1C2 /* FBSDKAppGroupContent.h in Headers */, 24DB7D4E986A59B0E032E4F83A69536A /* FBSDKAppGroupJoinDialog.h in Headers */, 66533D7A594AA93C8C43EF1BCE668A74 /* FBSDKAppInviteContent.h in Headers */, C39613DBB90FF65789612725FC595542 /* FBSDKAppInviteDialog.h in Headers */, 1A1DBDBFC387F891086033E7C529931C /* FBSDKCheckmarkIcon.h in Headers */, 180BFD5C4CF58060C6E4673D16922EF9 /* FBSDKGameRequestContent.h in Headers */, 4157F58C771B24EB545FBB57552535B2 /* FBSDKGameRequestDialog.h in Headers */, 385E8CF0234426575581CCA6F53DD434 /* FBSDKGameRequestFrictionlessRecipientCache.h in Headers */, C51B4865E5186E9BF6DB6BEFC9517EF1 /* FBSDKHashtag.h in Headers */, 06A4A4AF7AFC580A244A78B2C7999E94 /* FBSDKLikeActionController.h in Headers */, 0EEF80A8836783073DB22A229E6DA59E /* FBSDKLikeActionControllerCache.h in Headers */, 05FB221AC2755579479BBCD40E251230 /* FBSDKLikeBoxBorderView.h in Headers */, 97CD6CF37BB5BE78C2A234AC897802B7 /* FBSDKLikeBoxView.h in Headers */, 15EDAC05EB1C7ADBF13CDE7ECEB68CF7 /* FBSDKLikeButton+Internal.h in Headers */, B74D40AC59FF4E03D30024F6CFE94BD1 /* FBSDKLikeButton.h in Headers */, 76F96A14F0A8DBF44BD7E419DAF7B877 /* FBSDKLikeButtonPopWAV.h in Headers */, E2FF4576C5740EDF6E0E2A62495A9E5C /* FBSDKLikeControl+Internal.h in Headers */, 65AD76A5209F07993BCCF096FA03E254 /* FBSDKLikeControl.h in Headers */, 2C1DCEEF93879DDE6AD0C2F2BC350C0A /* FBSDKLikeDialog.h in Headers */, 6167D4C5CA1DF7E209EE66CD5E706DB5 /* FBSDKLikeObjectType.h in Headers */, 384AB7595557A39CB10CBD9CB467D24D /* FBSDKLiking.h in Headers */, 3F17A710798B958949B20EC8D0CCFAC0 /* FBSDKMessageDialog.h in Headers */, 0AAEA700978D1406CFC13FFEF8E72BB4 /* FBSDKMessengerIcon.h in Headers */, 007E3BF0BF2A2854408ACF7433E709E8 /* FBSDKSendButton.h in Headers */, BCAB58F8DE87B33E128B5C090EEB3E8E /* FBSDKShareAPI.h in Headers */, F6A635CE6CDD2D57711CCEC692128382 /* FBSDKShareButton.h in Headers */, D347F65DE4E6C432B5182A7376869D0C /* FBSDKShareConstants.h in Headers */, D5A52B04EF08F7245C8D6B9E42BB906A /* FBSDKShareDefines.h in Headers */, CFDAC1FC6D948576796D48F01601D00B /* FBSDKShareDialog.h in Headers */, C9239042BAF0562154A942D3598BEFAA /* FBSDKShareDialogMode.h in Headers */, 5A40CE0717F4DFAF776F12F835401D72 /* FBSDKShareError.h in Headers */, 5DB28EB181DDB2482EAB7052C0FFDD4A /* FBSDKShareKit+Internal.h in Headers */, 3FD0D93AD926C94818225AA013D70FDF /* FBSDKShareKit-umbrella.h in Headers */, FC7F0A1FFB2641FAB705A0CF9EFC1303 /* FBSDKShareKit.h in Headers */, CDECDF26D5914B5118DA15DC06FABFDF /* FBSDKShareLinkContent+Internal.h in Headers */, E2538D972FF83B2B65506DFEF1DBF704 /* FBSDKShareLinkContent.h in Headers */, 8C7CABBE4EC64C461AF9AE36EA44C050 /* FBSDKShareMediaContent.h in Headers */, 375E8C355CB9A979E9F03DAEE9703171 /* FBSDKShareOpenGraphAction.h in Headers */, CB67930A4314E6E46A903F3489EB7608 /* FBSDKShareOpenGraphContent.h in Headers */, D20BAF8A10A6F2B9E2A7B6DD82C056F6 /* FBSDKShareOpenGraphObject.h in Headers */, 188A670E26DA49268A133953AF0BF038 /* FBSDKShareOpenGraphValueContainer+Internal.h in Headers */, 0B8052279201BD94A1829862BFC57B2B /* FBSDKShareOpenGraphValueContainer.h in Headers */, F4F8771CF43018CF648DF325FD6546E5 /* FBSDKSharePhoto.h in Headers */, E0095D397882896F3871DC2E380152D1 /* FBSDKSharePhotoContent.h in Headers */, 3EA077D046DCD950DCAC4BCD2C1C3233 /* FBSDKShareUtility.h in Headers */, F968CDDC661EA2C602666CE712CEB7A4 /* FBSDKShareVideo.h in Headers */, 2FA0E03C590839B4243AB5B91DD749AF /* FBSDKShareVideoContent.h in Headers */, 99BCC2F48031C4DF19C25EC274DB057F /* FBSDKSharing.h in Headers */, E33C52610245504BC91ADA56E67826B3 /* FBSDKSharingButton.h in Headers */, 8FD9899D436F154F3491C5D308B57B32 /* FBSDKSharingContent.h in Headers */, F9B9A77D836E30A07D84E3C3AB5FAE7A /* FBSDKVideoUploader.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; D86E4D25B0C702733EEDADF92CD991E5 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( 7F0237413FACB7A3676D95631D9F3B0C /* _FBSDKTemporaryErrorRecoveryAttempter.h in Headers */, AEC88D8012A4396714B28985099C6EFF /* FBSDKAccessToken.h in Headers */, F6878FC9541012F94978CF46070D1301 /* FBSDKAccessTokenCache.h in Headers */, 17DBDC22CDC96ABAB7D15DC0B4252B95 /* FBSDKAccessTokenCacheV3.h in Headers */, 89DC0A9AEBB5F53137CAC02700F1EC77 /* FBSDKAccessTokenCacheV3_17.h in Headers */, E0D8CC2D833E62302F30B2FE5DACC3C9 /* FBSDKAccessTokenCacheV3_21.h in Headers */, 9A0B6587B7EDADD06D3ADD8F12ECA0C5 /* FBSDKAccessTokenCacheV4.h in Headers */, 54B55A60F4122485684FA7EC79C0FF32 /* FBSDKAccessTokenCaching.h in Headers */, E9E40449AFDF5DCD1B0E16F2993DE940 /* FBSDKAppEvents+Internal.h in Headers */, 5CA8E916EED0300D905FD4BCC1C336ED /* FBSDKAppEvents.h in Headers */, CDB7896D8D7B6198A8930A88526BAE3C /* FBSDKAppEventsDeviceInfo.h in Headers */, DD71FF7082841E53507DF58A816EF24A /* FBSDKAppEventsState.h in Headers */, 4FA93C7BE82E47E93B2186C08174D7F9 /* FBSDKAppEventsStateManager.h in Headers */, 3963AF83388A5E8A18C48332F35020D4 /* FBSDKAppEventsUtility.h in Headers */, F12AF773342F9806BE3A3E4BBAE8EE2C /* FBSDKApplicationDelegate+Internal.h in Headers */, EA92883DCDC909379715AAA47109F2B8 /* FBSDKApplicationDelegate.h in Headers */, A9650954E31B48DD860AFE2F0752C80A /* FBSDKAppLinkResolver.h in Headers */, 48FF5E216FDC53AA9802827D423EF8D3 /* FBSDKAppLinkUtility.h in Headers */, 30BC73BB0A3D2A9FD2416A00659023B0 /* FBSDKAudioResourceLoader.h in Headers */, 82D7BE28B1585DA660DE327BB496D656 /* FBSDKBase64.h in Headers */, 90EB41BDF3FE41A9FBFCBA9F77EDACE3 /* FBSDKBoltsMeasurementEventListener.h in Headers */, 2E855474A46D61569DF5CE7D2C7BC945 /* FBSDKBridgeAPICrypto.h in Headers */, 835DEC134806538B138A8837B3D24F70 /* FBSDKBridgeAPIProtocol.h in Headers */, E405BE065D3907EBEA6CA987F7B28970 /* FBSDKBridgeAPIProtocolNativeV1.h in Headers */, 20ABB95B04C837764640801509F64EF0 /* FBSDKBridgeAPIProtocolType.h in Headers */, 85D97B96B98C541629F6C6866DAFC1A2 /* FBSDKBridgeAPIProtocolWebV1.h in Headers */, 0A1A1B87F24903B40A84CA388C14F889 /* FBSDKBridgeAPIProtocolWebV2.h in Headers */, A8B64346A4A2013DFBD54486BFCE11A9 /* FBSDKBridgeAPIRequest+Private.h in Headers */, 91AFF1186F1BBFB010FE5A706961ECE0 /* FBSDKBridgeAPIRequest.h in Headers */, FBB79DC1BDCDDEA2FA5A5689B1F803EB /* FBSDKBridgeAPIResponse.h in Headers */, DFF1485B513E216D515C7B872145EC0A /* FBSDKButton+Subclass.h in Headers */, 4C1699BEA8B4E49D98292993C613994C /* FBSDKButton.h in Headers */, 79BE10093D731A2D4878DB7F8F46ADB3 /* FBSDKCloseIcon.h in Headers */, FD37427BF19B0520BCC86974E7FB9192 /* FBSDKColor.h in Headers */, 70A9ACFE11830087A2F515C2D9B83A36 /* FBSDKConstants.h in Headers */, F5862151DF7C94B129A3917F880F9985 /* FBSDKContainerViewController.h in Headers */, A8E0FCC37561E057927BC29EF5B99E02 /* FBSDKCopying.h in Headers */, D34DCA75165C72964785F46234C55617 /* FBSDKCoreKit+Internal.h in Headers */, F36A25CB7A3F6373D55CC4183C639E86 /* FBSDKCoreKit-umbrella.h in Headers */, 7D71E19849D32B258191F32920CE8C74 /* FBSDKCoreKit.h in Headers */, B23C036B9C9FE3E152A6BC3FA8F9828D /* FBSDKCrypto.h in Headers */, 2D00B6543D85CBD4B2650AFDC43D093B /* FBSDKDialogConfiguration.h in Headers */, 0733D08910977EC97E27B2375ED23E7C /* FBSDKDynamicFrameworkLoader.h in Headers */, 6C9A8D47F3B71046F320078FCF8E4B21 /* FBSDKError.h in Headers */, E946BACAA3326E2D9FC5C3BDCE897918 /* FBSDKErrorConfiguration.h in Headers */, BD58659499DB6E135229A124B3FC2EEF /* FBSDKErrorRecoveryAttempter.h in Headers */, 26D3A3843B30222F9A4E20F5C6C3F99E /* FBSDKErrorRecoveryConfiguration.h in Headers */, 8E4988A18BF13F6406E4D2E633027231 /* FBSDKGraphErrorRecoveryProcessor.h in Headers */, 76F6D75839266FB7F287B7DB0D378184 /* FBSDKGraphRequest+Internal.h in Headers */, 8E2D371C41A1C09CEF9F9BFCB630C0BE /* FBSDKGraphRequest.h in Headers */, F66676CD9BBA00D2169C4224BDE79829 /* FBSDKGraphRequestBody.h in Headers */, E89B7AA1C8A33AA609D3377A2146F960 /* FBSDKGraphRequestConnection+Internal.h in Headers */, 9404840E2A2064803E55062DD88154F7 /* FBSDKGraphRequestConnection.h in Headers */, C7E1185AD9DA7CDEF22CC10F4317E941 /* FBSDKGraphRequestDataAttachment.h in Headers */, 2C00247AC73BCEF8AFF662C9CA21A471 /* FBSDKGraphRequestMetadata.h in Headers */, 9ECB71F2FC66B85082C35CE4AEAAD509 /* FBSDKGraphRequestPiggybackManager.h in Headers */, C690CF49E6BA659D39725D34B0CC260B /* FBSDKIcon.h in Headers */, 9BBFEC80F690828CA401BE7E11345EE6 /* FBSDKInternalUtility.h in Headers */, 2D93C198F3B9D0B084C2DF2049EAAD53 /* FBSDKKeychainStore.h in Headers */, B9F622CCC8F218363ADC3D4B029279A2 /* FBSDKKeychainStoreViaBundleID.h in Headers */, 1065981079E04A302D057FF480D88144 /* FBSDKLogger.h in Headers */, 78EA084779CE7F9CED6ACF196B5EB607 /* FBSDKLogo.h in Headers */, 9CADD29609C9EAF87DB90BF1CF5233D7 /* FBSDKMacros.h in Headers */, BDA6B7E75F4E3C0233182FFD67F1DAA8 /* FBSDKMaleSilhouetteIcon.h in Headers */, 13608DABB5C9B433953DD7E64FDD352D /* FBSDKMath.h in Headers */, 747339FDBF19337791654E8E26A10995 /* FBSDKMonotonicTime.h in Headers */, 6A42401E163EF7DF7C8464E941864541 /* FBSDKMutableCopying.h in Headers */, 1429D6597964E51BF53D74E9A9B2E8C8 /* FBSDKPaymentObserver.h in Headers */, 2691F6D8E9EED6EFC03361C9DAEA65F5 /* FBSDKProfile+Internal.h in Headers */, EE36AB0C7B5DAF57B04542DFC5A02F92 /* FBSDKProfile.h in Headers */, 61E2DD53D9A1ED0A5DCE23326A57765C /* FBSDKProfilePictureView.h in Headers */, 097FBD368E967EB3E4B855ADE19422C7 /* FBSDKServerConfiguration+Internal.h in Headers */, 1E3648E58DE7A089A9399DED81DA2D6B /* FBSDKServerConfiguration.h in Headers */, 591FC299A2D9A1B4ED34D81F3A5B3364 /* FBSDKServerConfigurationManager+Internal.h in Headers */, 5DD204D3BDBEF19C2FFC64106A3BE225 /* FBSDKServerConfigurationManager.h in Headers */, 845719FAA2F09FF6781E7D43D3A6F5A3 /* FBSDKSettings+Internal.h in Headers */, BB0AA4F4FAF414D7D1317C96DC4B64E1 /* FBSDKSettings.h in Headers */, 41B52B3E513F62AB8BD7FE9FC08368E1 /* FBSDKSystemAccountStoreAdapter.h in Headers */, 1C96677B1A87F2938E2A28D5DE93D6A2 /* FBSDKTestUsersManager.h in Headers */, C2F01DAF3B61ED2055801480ABBF9B94 /* FBSDKTimeSpentData.h in Headers */, 04264C5208F69D58A5F11669B4CE4BD7 /* FBSDKTriStateBOOL.h in Headers */, 3A59407EA76E94E2F14A570B69CE739B /* FBSDKTypeUtility.h in Headers */, D526206FE0167F9A3C4292B0F3E4F337 /* FBSDKUIUtility.h in Headers */, 27B18B6B5E2943CF3B3CDD4812B7DB77 /* FBSDKURLConnection.h in Headers */, 51C1B7B60D51F4AEAA2036128E814BA0 /* FBSDKURLOpening.h in Headers */, 683F00DC5BC8E350C511CB04D6489A61 /* FBSDKURLSessionTask.h in Headers */, 1E1403542B5C6A90FFB0A5300BE7C01E /* FBSDKUtility.h in Headers */, 46D8BDB08F59CA6D31688A125F4C0E48 /* FBSDKViewImpressionTracker.h in Headers */, C2D51BA1EC47A0EAE713858A0EDEB951 /* FBSDKWebDialog.h in Headers */, 26F9695CA49AF7F6E6B2ECCA2EA9AD28 /* FBSDKWebDialogView.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ 1C3436CEA5C3D39764C5F54374794ECB /* AFNetworking */ = { isa = PBXNativeTarget; buildConfigurationList = 57800A0D1724774333EF09E83030AA81 /* Build configuration list for PBXNativeTarget "AFNetworking" */; buildPhases = ( 1F17F426378DF5EC8DFB10304B8C4BA4 /* Sources */, C151364F15F39F7CC60CBF9A3AB49B44 /* Frameworks */, 7C6A0D99A9CC32A19A92A62F8A941139 /* Headers */, ); buildRules = ( ); dependencies = ( ); name = AFNetworking; productName = AFNetworking; productReference = 8FAB4FB8B643AEEA0D54BBB11648434D /* AFNetworking.framework */; productType = "com.apple.product-type.framework"; }; 2E303C3CE7513908EE880D9CA833AFAE /* FBSDKCoreKit */ = { isa = PBXNativeTarget; buildConfigurationList = BE44A0803B9534732B5A6586C44D793C /* Build configuration list for PBXNativeTarget "FBSDKCoreKit" */; buildPhases = ( 2BA7960A3FE0E2793EF41E535ECF6448 /* Sources */, BB4E7410D48C44A7F803DFFB5F71C494 /* Frameworks */, D86E4D25B0C702733EEDADF92CD991E5 /* Headers */, 5EA29DC4F550FC93E4D1D07D56636705 /* Resources */, ); buildRules = ( ); dependencies = ( 4CE22CABA129BAE1348F4B36284D8127 /* PBXTargetDependency */, ); name = FBSDKCoreKit; productName = FBSDKCoreKit; productReference = 37B9FAD0B18BDDA91409715A1166C5CB /* FBSDKCoreKit.framework */; productType = "com.apple.product-type.framework"; }; 30D7FCF8072F5D59AE1C98D94F9A6EC9 /* FBSDKShareKit */ = { isa = PBXNativeTarget; buildConfigurationList = C6E7F424D9A74E5A77B81FDB91D47E00 /* Build configuration list for PBXNativeTarget "FBSDKShareKit" */; buildPhases = ( 397101E7A3A354B8D08463429517141E /* Sources */, 2E7E8F9C361AB09ED21E3ACCBDE5522A /* Frameworks */, C4D4C46F1749D8A334B16CADF82EEE9C /* Headers */, ); buildRules = ( ); dependencies = ( 84B3D926308714AC862F533D62D805DB /* PBXTargetDependency */, 4F3CF331AB806BC4E9978A9118632162 /* PBXTargetDependency */, ); name = FBSDKShareKit; productName = FBSDKShareKit; productReference = 1798F04401CF6DDA8F03E7D82898E416 /* FBSDKShareKit.framework */; productType = "com.apple.product-type.framework"; }; 5DA0B374CB34642F0B891ACE7F3ED50F /* SwiftyJSON */ = { isa = PBXNativeTarget; buildConfigurationList = 1B919EAB713C4FB469DCEAC27277542C /* Build configuration list for PBXNativeTarget "SwiftyJSON" */; buildPhases = ( A0170F55DC1A2859D27CD945BBF68194 /* Sources */, 858CFE365F90A45EF980BA032C96E8C1 /* Frameworks */, C04D6378BBFBBFCD2C4246D7CF2B0E3B /* Headers */, ); buildRules = ( ); dependencies = ( ); name = SwiftyJSON; productName = SwiftyJSON; productReference = 6B74CD72A2D1FDBE15600ED4D1792E2B /* SwiftyJSON.framework */; productType = "com.apple.product-type.framework"; }; 6EDC37F3FA92533C6AC3562458AA91F1 /* FBSDKLoginKit */ = { isa = PBXNativeTarget; buildConfigurationList = 32ED130D3F319966AE7EECBEC8F1A552 /* Build configuration list for PBXNativeTarget "FBSDKLoginKit" */; buildPhases = ( 6FA3A594589902DACA2A3CCCCFBEC8F9 /* Sources */, FE01B5BC92977FB1F14A8C73D8F6D05C /* Frameworks */, 0A96B59D57F3AC923626746E801DDE9C /* Headers */, ); buildRules = ( ); dependencies = ( F78FDB1EA04228A084EDD2BDDD2A09A5 /* PBXTargetDependency */, EE4106E226CB0BEB4B8D5572E612A79A /* PBXTargetDependency */, ); name = FBSDKLoginKit; productName = FBSDKLoginKit; productReference = 77F9752E0AC323470089489606BD1CF5 /* FBSDKLoginKit.framework */; productType = "com.apple.product-type.framework"; }; 818848D25FD4162CBB09675CC6EB2D7B /* Pods-PotterPics */ = { isa = PBXNativeTarget; buildConfigurationList = 6C3DF0533D78EEF9D06FF5B09ACE469C /* Build configuration list for PBXNativeTarget "Pods-PotterPics" */; buildPhases = ( 22DD82035E0F542C056AA7F5037076C5 /* Sources */, 54D8C3611A54C9E38BC9E3D5591E6EF8 /* Frameworks */, 097FC3C42F055F1EADF246AAC10B811B /* Headers */, ); buildRules = ( ); dependencies = ( D980AFCB2A4B8B4D1FC725E7261E4D77 /* PBXTargetDependency */, 77E641A0F4480E12163BBB54ADED6998 /* PBXTargetDependency */, 896047CEFBF1EFA2F8D8ABCB6ACD9443 /* PBXTargetDependency */, 6ACD044A3B887324FB6A92693812C59A /* PBXTargetDependency */, 139FBC21E1CB73F82F8B1743E52D1EF6 /* PBXTargetDependency */, 0850D958DDBB10C2CA7F3B379EDB1C76 /* PBXTargetDependency */, 99FADC94C30669B9B0BF540174328DBA /* PBXTargetDependency */, ); name = "Pods-PotterPics"; productName = "Pods-PotterPics"; productReference = 64A1D0C796E579900E531F219DE71031 /* Pods_PotterPics.framework */; productType = "com.apple.product-type.framework"; }; 9D0F2E5EA1B46A5D72FFD42B0B39DBBC /* Bolts */ = { isa = PBXNativeTarget; buildConfigurationList = 19E23EED00D7A70A3012305F0EAAC6F7 /* Build configuration list for PBXNativeTarget "Bolts" */; buildPhases = ( 8B92D7D2E5D502DBE23A5DE88454E404 /* Sources */, 03E8CCDA32AA42D3F8C9E0956F925223 /* Frameworks */, 75B2517624D989B002D158AD8353146C /* Headers */, ); buildRules = ( ); dependencies = ( ); name = Bolts; productName = Bolts; productReference = 0A2D4836EB6721814767F5F092407237 /* Bolts.framework */; productType = "com.apple.product-type.framework"; }; A8EA4D547DD69D495D200A703548D5F1 /* Pods-PotterPicsUITests */ = { isa = PBXNativeTarget; buildConfigurationList = 61A0B904D3869084422346EF6B14CEF1 /* Build configuration list for PBXNativeTarget "Pods-PotterPicsUITests" */; buildPhases = ( B7FECFC235F6E17926EAB8B005A3DD28 /* Sources */, 2A21945ADA3A841F44A1AF8E5ECAFC87 /* Frameworks */, 3511C1F36FCF6C4EC47AA2DC29120550 /* Headers */, ); buildRules = ( ); dependencies = ( ); name = "Pods-PotterPicsUITests"; productName = "Pods-PotterPicsUITests"; productReference = 798886A25C16CC5888D2F649523DAFEA /* Pods_PotterPicsUITests.framework */; productType = "com.apple.product-type.framework"; }; D30773D0BBD4340DB037F15A69FD567F /* Pods-PotterPicsTests */ = { isa = PBXNativeTarget; buildConfigurationList = 3C71ACC1F6C9EEE584A9BCA75FAAA8F8 /* Build configuration list for PBXNativeTarget "Pods-PotterPicsTests" */; buildPhases = ( 2482C5CDA91DAFF5120DD78C0AA55F85 /* Sources */, 0A3F9698C4DAAA9A77B44DAFE231B96B /* Frameworks */, 6D09F8779E5E745FE223A9CA1BCE1535 /* Headers */, ); buildRules = ( ); dependencies = ( ); name = "Pods-PotterPicsTests"; productName = "Pods-PotterPicsTests"; productReference = D995EC9D92E9EEE5967826BB1E1BECB5 /* Pods_PotterPicsTests.framework */; productType = "com.apple.product-type.framework"; }; DBA6001481CEA0EBA031CC5C94508FAA /* MBProgressHUD */ = { isa = PBXNativeTarget; buildConfigurationList = 1E2C012DEECFAAEF8B8A9CE1E8AAA03C /* Build configuration list for PBXNativeTarget "MBProgressHUD" */; buildPhases = ( 18E2532E62644868123A50D7CA3BA192 /* Sources */, 4C4161B0612BDBF5BD49DBC28E0EC20B /* Frameworks */, 1F5CDCB9D8E0BB0975E3797EDC45AB2F /* Headers */, ); buildRules = ( ); dependencies = ( ); name = MBProgressHUD; productName = MBProgressHUD; productReference = CC26118D0CC247921A80E8AD1177894A /* MBProgressHUD.framework */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; LastUpgradeCheck = 0700; }; buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, ); mainGroup = 7DB346D0F39D3F0E887471402A8071AB; productRefGroup = 4E773E7C22B0E8883A3E1B4B74B742AD /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 1C3436CEA5C3D39764C5F54374794ECB /* AFNetworking */, 9D0F2E5EA1B46A5D72FFD42B0B39DBBC /* Bolts */, 2E303C3CE7513908EE880D9CA833AFAE /* FBSDKCoreKit */, 6EDC37F3FA92533C6AC3562458AA91F1 /* FBSDKLoginKit */, 30D7FCF8072F5D59AE1C98D94F9A6EC9 /* FBSDKShareKit */, DBA6001481CEA0EBA031CC5C94508FAA /* MBProgressHUD */, 818848D25FD4162CBB09675CC6EB2D7B /* Pods-PotterPics */, D30773D0BBD4340DB037F15A69FD567F /* Pods-PotterPicsTests */, A8EA4D547DD69D495D200A703548D5F1 /* Pods-PotterPicsUITests */, 5DA0B374CB34642F0B891ACE7F3ED50F /* SwiftyJSON */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 5EA29DC4F550FC93E4D1D07D56636705 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 91461806305F16B4B68CC47B4FE551C3 /* FacebookSDKStrings.bundle in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 18E2532E62644868123A50D7CA3BA192 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( D6ABDFF81E566FFECF367E42C6333D79 /* MBProgressHUD-dummy.m in Sources */, 81AADA5ADE8535AD6F7678C6F3A06E89 /* MBProgressHUD.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 1F17F426378DF5EC8DFB10304B8C4BA4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 3F1BC9BAFFEEABB1ABC7614DF0FC97D5 /* AFAutoPurgingImageCache.m in Sources */, E0D4045AC4C1B41917FCA23A042D18B2 /* AFHTTPSessionManager.m in Sources */, CFA8D6B529A0EBFF0316F2629AB2556E /* AFImageDownloader.m in Sources */, A6C6019D45BE62C61210A9CC619368EF /* AFNetworkActivityIndicatorManager.m in Sources */, 3D2789FC760A97301909F0B1201626CD /* AFNetworking-dummy.m in Sources */, 68A38977EBAE334DC3C22386D00D2622 /* AFNetworkReachabilityManager.m in Sources */, 20607BE2B1E5F31765026E5AC64DB27D /* AFSecurityPolicy.m in Sources */, DFFA215EEAA8DDBD540076927535275C /* AFURLRequestSerialization.m in Sources */, B5852322ADE88AAD56EE042B80BA81E4 /* AFURLResponseSerialization.m in Sources */, 707B1A7541C8DBDDE8C27896A61370BE /* AFURLSessionManager.m in Sources */, 6ED4ABEE8A5F51F5ECB59FA1781D29C6 /* UIActivityIndicatorView+AFNetworking.m in Sources */, AF03C11A1FAC8132AD3749D8F541701A /* UIButton+AFNetworking.m in Sources */, 2E8A32ED46194EDBE22146271F6D26DE /* UIImageView+AFNetworking.m in Sources */, 5FF6453E55785669885F626B853FD2AA /* UIProgressView+AFNetworking.m in Sources */, 174202BD6AE0E4A41F5CE66E975EAE52 /* UIRefreshControl+AFNetworking.m in Sources */, A462945883F7729B185B64B679A6BFBE /* UIWebView+AFNetworking.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 22DD82035E0F542C056AA7F5037076C5 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 4F3E18A34A2779B9BA8070B9FFD8E091 /* Pods-PotterPics-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 2482C5CDA91DAFF5120DD78C0AA55F85 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 7363AA8C008065817E76B9388EAEDFF8 /* Pods-PotterPicsTests-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 2BA7960A3FE0E2793EF41E535ECF6448 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 2D8531AC642B560633B709121A1E5C0F /* _FBSDKTemporaryErrorRecoveryAttempter.m in Sources */, 243B4209461BA07590EAF27862C40B61 /* FBSDKAccessToken.m in Sources */, FBFC84F1732ECA4AC061AE15DB5F8404 /* FBSDKAccessTokenCache.m in Sources */, 7B0F099011442A12FE9794107B879B9C /* FBSDKAccessTokenCacheV3.m in Sources */, D47ED08B9196AE9B0A1D681207FF5789 /* FBSDKAccessTokenCacheV3_17.m in Sources */, 9E82EB8CB75FC077C589F4C52A24095F /* FBSDKAccessTokenCacheV3_21.m in Sources */, B3EF5F677DAF43756C055223BB16FC64 /* FBSDKAccessTokenCacheV4.m in Sources */, 755CAA0856609A25D4C138A0DF24B800 /* FBSDKAppEvents.m in Sources */, 20FEB85677DF043991A88A98291D01A4 /* FBSDKAppEventsDeviceInfo.m in Sources */, 1A76F6D34E402E6420FACDEC32E7A563 /* FBSDKAppEventsState.m in Sources */, A8B8AED7CC2CC62986985FC638A2547C /* FBSDKAppEventsStateManager.m in Sources */, FAFF0338DA0F7C773CE1E2813A9AD99E /* FBSDKAppEventsUtility.m in Sources */, 3F2458F552FB89EA66BFB571C276F845 /* FBSDKApplicationDelegate.m in Sources */, FAE007ED5F7CAEB03A3B3EF38A9A2749 /* FBSDKAppLinkResolver.m in Sources */, 762276A054BDBCD8DD9667D736190CF9 /* FBSDKAppLinkUtility.m in Sources */, 27D6CB001580A3864F7B7B18B5CA11D3 /* FBSDKAudioResourceLoader.m in Sources */, 928E3FA159592606B2D377B32D56934F /* FBSDKBase64.m in Sources */, D5BA74145C0DD3D7C2146DB73A378CB5 /* FBSDKBoltsMeasurementEventListener.m in Sources */, EC515D6442B6FDC3C7E12FDDFAABF756 /* FBSDKBridgeAPICrypto.m in Sources */, 5C5D17AB22A659C7A35FBDB5C8DEC1AE /* FBSDKBridgeAPIProtocolNativeV1.m in Sources */, 6BBB1458E4A923496BDABF7A13E00C27 /* FBSDKBridgeAPIProtocolWebV1.m in Sources */, 22F4E832A59064E51FBB64149BACAAB6 /* FBSDKBridgeAPIProtocolWebV2.m in Sources */, 9BBF52FCCBDF34280736F72483E33379 /* FBSDKBridgeAPIRequest.m in Sources */, 78E3B43BC8EA92B48B10612FBA17B02C /* FBSDKBridgeAPIResponse.m in Sources */, 9FE6105E7FF114DF7F9C43BF76A7B790 /* FBSDKButton.m in Sources */, 700A0C2CD36658F1B0C0B1F06B8EEB26 /* FBSDKCloseIcon.m in Sources */, 59834F5509421BF031C29B9CAFE404F0 /* FBSDKColor.m in Sources */, 6548721272A6621436915353754710A7 /* FBSDKConstants.m in Sources */, 4332DBEF82690666648C01092597A5CD /* FBSDKContainerViewController.m in Sources */, 09377F0215E2E436F04644D375173567 /* FBSDKCoreKit-dummy.m in Sources */, 6D18D3AD65417A5E1F5C62611794A141 /* FBSDKCrypto.m in Sources */, 73AD14D5BACD6BC0D90B444C458E8FD4 /* FBSDKDialogConfiguration.m in Sources */, 3979D814B1CB5D0DF8E18C3ABDD1E5EC /* FBSDKDynamicFrameworkLoader.m in Sources */, B73B1BCB2899627D421709275BA22697 /* FBSDKError.m in Sources */, 56FF2E7748A9026DEECE6CB0007037FA /* FBSDKErrorConfiguration.m in Sources */, 199E8BF13BE175C4DD97FEC3976D5F65 /* FBSDKErrorRecoveryAttempter.m in Sources */, E506115FCDC9F77D14E1C78466568D4C /* FBSDKErrorRecoveryConfiguration.m in Sources */, 25D47C6377A30926CA5FB9C542DE1878 /* FBSDKGraphErrorRecoveryProcessor.m in Sources */, 34734437C2FDA7D41AE9F77A3CD07ECA /* FBSDKGraphRequest.m in Sources */, 3B03433830A1679D96F443321F9E7CD2 /* FBSDKGraphRequestBody.m in Sources */, 4EBCD6EC15EDFC23EAB49AEFD48644FA /* FBSDKGraphRequestConnection.m in Sources */, 2EF92BC89987CA7A7F9D8EC80B115F1C /* FBSDKGraphRequestDataAttachment.m in Sources */, 57223DDD941FECB4AE83105F412AA598 /* FBSDKGraphRequestMetadata.m in Sources */, AA94F90D3D0EEA7792F9584C860ADD30 /* FBSDKGraphRequestPiggybackManager.m in Sources */, 0833AF4DC458C2A0345733BC9231B289 /* FBSDKIcon.m in Sources */, 121DBDB1187D26610D1AE715C72731B5 /* FBSDKInternalUtility.m in Sources */, 8D4CD2DC3A6A4B2AA3087AA5048399E7 /* FBSDKKeychainStore.m in Sources */, BC6E9E2792A93805AA69AD5E503E69DA /* FBSDKKeychainStoreViaBundleID.m in Sources */, 22BB41D5092D2F105C7C29CE5755846C /* FBSDKLogger.m in Sources */, 6CEEDECCE819709B38F3232102D4808B /* FBSDKLogo.m in Sources */, FC4664DAFACB0D557FED3B200AC6FE4F /* FBSDKMaleSilhouetteIcon.m in Sources */, 1011B357BB0B3BC60DA75A5BAC283B5E /* FBSDKMath.m in Sources */, 384AFBA2151B288649310D44078377DC /* FBSDKMonotonicTime.m in Sources */, 2FE8ED56BF39F0870039E6E837BE5C25 /* FBSDKPaymentObserver.m in Sources */, 7E7F5D5FECCC6BB4319C11A419E9BB09 /* FBSDKProfile.m in Sources */, 2989C26698615F83CF5ED2957271513C /* FBSDKProfilePictureView.m in Sources */, A73E5104E58344ECB5A8F7B162F4C988 /* FBSDKServerConfiguration.m in Sources */, 11DEDD08EE2FBF22E26F8E4277B8E7CF /* FBSDKServerConfigurationManager.m in Sources */, A6437070CF1C249685D69D693BB130F5 /* FBSDKSettings.m in Sources */, FD395FC2A672F51DA6B445D69708FF6E /* FBSDKSystemAccountStoreAdapter.m in Sources */, BD1FA39CEA9C5F52DA8E2729A7E366F4 /* FBSDKTestUsersManager.m in Sources */, BE537D3EDB5514160FD8CCD95B97F39B /* FBSDKTimeSpentData.m in Sources */, 62A48526C86AC1FD4D71E2A0C913AAB8 /* FBSDKTriStateBOOL.m in Sources */, B6A35457F14D3CCDEB68B8E69D71EAE5 /* FBSDKTypeUtility.m in Sources */, AF53BABEF4555D0436B0D6DAB01F75D2 /* FBSDKURLConnection.m in Sources */, EE5B930F9F26CBF2093E59FAF8DFAA2C /* FBSDKURLSessionTask.m in Sources */, 1D8F71B0155497482375953A5F0FF61B /* FBSDKUtility.m in Sources */, 4D07D0151693228D6281EDB319B448C0 /* FBSDKViewImpressionTracker.m in Sources */, 53DCAD2FF5018897F635A8F80D1B9A95 /* FBSDKWebDialog.m in Sources */, 65866EFFD741914649CE881BDDC24F60 /* FBSDKWebDialogView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 397101E7A3A354B8D08463429517141E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 8BF401C38065E3AC9BD840243F4DD820 /* FBSDKAppGroupAddDialog.m in Sources */, 27AFC2D1A21EAE366618898F50287183 /* FBSDKAppGroupContent.m in Sources */, 1360C072C79DBA6E4B292B7A05B73ACB /* FBSDKAppGroupJoinDialog.m in Sources */, E3AE71AF80F5D8A842E69202847A0710 /* FBSDKAppInviteContent.m in Sources */, 7E9100394CBFFADF64B26C6F4373F78E /* FBSDKAppInviteDialog.m in Sources */, 808E738E1648120C1045BB75BB8AC058 /* FBSDKCheckmarkIcon.m in Sources */, 6B7DD32A130E3052BBB254E95E8897F5 /* FBSDKGameRequestContent.m in Sources */, D05E51C8CEED91610DDE599FA220A58F /* FBSDKGameRequestDialog.m in Sources */, 3A01CE59DF9D68D5F2623F88E522A33E /* FBSDKGameRequestFrictionlessRecipientCache.m in Sources */, 2866B55F0B1E204001EF16753AFD3426 /* FBSDKHashtag.m in Sources */, C9BD44D9DC9D9E459BCB805875DC2306 /* FBSDKLikeActionController.m in Sources */, 9991B7ED54593BD5F26EF68DC59E1D4B /* FBSDKLikeActionControllerCache.m in Sources */, 1110C890C028A60D617B28184DFF9968 /* FBSDKLikeBoxBorderView.m in Sources */, 6BC497E6FA97D13CEFE6919C46F7EFF4 /* FBSDKLikeBoxView.m in Sources */, F1375F74031F3731A3D9F42A66A6327D /* FBSDKLikeButton.m in Sources */, FD7525FCB49FB135D59559C8A7D13D65 /* FBSDKLikeButtonPopWAV.m in Sources */, 885EA75AEF9C1C5631087D67494599F1 /* FBSDKLikeControl.m in Sources */, FA158C22016D2FC0737B76CFDDB52D0C /* FBSDKLikeDialog.m in Sources */, CE0233C459CA5BF1F081257EB3655004 /* FBSDKLikeObjectType.m in Sources */, 8E678F3A93AF7E81BD5B4DE16E9FAC71 /* FBSDKMessageDialog.m in Sources */, 0D9C01E9CFFF23D0BD3C3B9A73D48C16 /* FBSDKMessengerIcon.m in Sources */, D3B8A9EFB1AFEFE16BE8C7F4FE410F20 /* FBSDKSendButton.m in Sources */, 8BB11C8D9F58C1E81A26BD7EE74093D1 /* FBSDKShareAPI.m in Sources */, 0C11E95A97B2D6541603C23A850EC4EF /* FBSDKShareButton.m in Sources */, 812CC9954198FB632F3670E2D554898F /* FBSDKShareConstants.m in Sources */, 93CB179F47B5E343CCF361D181638E2E /* FBSDKShareDialog.m in Sources */, 52681368D4EB6EE79BE9FEF151AC185F /* FBSDKShareDialogMode.m in Sources */, C9A879CF614BAB80706EA977904B0BB9 /* FBSDKShareError.m in Sources */, 6F852F8B67F8A20BB296716E1AEE0AB7 /* FBSDKShareKit-dummy.m in Sources */, 86A4C9883826DA7856397C1EE3441257 /* FBSDKShareLinkContent.m in Sources */, A0DF7E397B57D50B5E89228082DB4361 /* FBSDKShareMediaContent.m in Sources */, 020A65A3E154C0B31D1B0351BD8FFEDA /* FBSDKShareOpenGraphAction.m in Sources */, 27591714E6846BFD95B8FBBEC15F97D1 /* FBSDKShareOpenGraphContent.m in Sources */, FFE20D61C3C5166CE50B2FA4BE2BC271 /* FBSDKShareOpenGraphObject.m in Sources */, 11D89502D964832FC217751339F7E7EF /* FBSDKShareOpenGraphValueContainer.m in Sources */, A54F557F6175E445E98C30B98B5A3AD6 /* FBSDKSharePhoto.m in Sources */, 98AF6E202E68E9B4F22202842DC0D619 /* FBSDKSharePhotoContent.m in Sources */, 387B78488B01402C1A6A04A4485972AA /* FBSDKShareUtility.m in Sources */, 77BF46EE1E54C91A7080408F8767A3DF /* FBSDKShareVideo.m in Sources */, 82008ED885D5AB3464812191AB960057 /* FBSDKShareVideoContent.m in Sources */, F12275031D131B6A70A0195761B1C7CA /* FBSDKVideoUploader.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 6FA3A594589902DACA2A3CCCCFBEC8F9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( F9BA81C41C3DDABA6BEC897850E45D8D /* _FBSDKLoginRecoveryAttempter.m in Sources */, B534C8C1D32294DB54F3C5CFFD5AAA9B /* FBSDKLoginButton.m in Sources */, F5F9597A3167E2AE7937E6CF4BD09AB8 /* FBSDKLoginCompletion.m in Sources */, 767C65F9CCCCA6B6E0A43C04594899BC /* FBSDKLoginConstants.m in Sources */, 78086867BF7BBED7E16245632C4E84CA /* FBSDKLoginError.m in Sources */, EDD254449CD8FF482448772C604D758A /* FBSDKLoginKit-dummy.m in Sources */, 0339052284A47A46E7821D754BB990DF /* FBSDKLoginManager.m in Sources */, 763F76FF18569C1C701FA8B251DA3AFE /* FBSDKLoginManagerLogger.m in Sources */, 27B378AAF73A1EBB45FFD7EA38D37247 /* FBSDKLoginManagerLoginResult.m in Sources */, A69128071A53DBC4882CC8DC76782334 /* FBSDKLoginTooltipView.m in Sources */, 08DAC2F4AEE5BBA86F713F32A79E24AF /* FBSDKLoginUtility.m in Sources */, 46E961BEA7247217652A5F012F82FECC /* FBSDKTooltipView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 8B92D7D2E5D502DBE23A5DE88454E404 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 3D6D69351FD8DF6501A8144FF882C074 /* BFAppLink.m in Sources */, 343843D298290E746FF42BFC7EEB9AA9 /* BFAppLinkNavigation.m in Sources */, 4DCE84710050E8583735F97ADC84FCA7 /* BFAppLinkReturnToRefererController.m in Sources */, C05225EA8ACCF663097C4EC96E8E9887 /* BFAppLinkReturnToRefererView.m in Sources */, 514B1324C72A235480C29BBC3AD1C250 /* BFAppLinkTarget.m in Sources */, 139FE4B378AF69FD65DF73C921B131AD /* BFCancellationToken.m in Sources */, D9B2E2CE9E2DF615FE197377486BB214 /* BFCancellationTokenRegistration.m in Sources */, 99FA28E0A77EBF35E1C94E6C5851DB44 /* BFCancellationTokenSource.m in Sources */, 652EE84BA55F2A6BD325768B753565D8 /* BFExecutor.m in Sources */, A411DDDACF2FE64E4123D2654049E331 /* BFMeasurementEvent.m in Sources */, 60CAF8D6E879B1585D61B55EE807A113 /* BFTask+Exceptions.m in Sources */, E3F3CBC9723823D11DCF58CDFA25AA77 /* BFTask.m in Sources */, 409F5BE5BDBB1D3850F4D62D5504D662 /* BFTaskCompletionSource.m in Sources */, 38EF43F03EBACFE40F480F4F8BC20FD5 /* BFURL.m in Sources */, 39E4FA2B5D0B8EFD4F9B953111DA1CFC /* BFWebViewAppLinkResolver.m in Sources */, C8A2479793F6D05DE6D8FA164EB7C00D /* Bolts-dummy.m in Sources */, 2C737796AAD49FE609E7FB0CCF8A263C /* Bolts.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; A0170F55DC1A2859D27CD945BBF68194 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( A9EF2B17DE733FCA4623A40A27F6ECC5 /* SwiftyJSON-dummy.m in Sources */, C56378807B25F03F1862E3E22E992A8D /* SwiftyJSON.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; B7FECFC235F6E17926EAB8B005A3DD28 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 65EF134F08720505DBCEEA7977CA7C55 /* Pods-PotterPicsUITests-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 0850D958DDBB10C2CA7F3B379EDB1C76 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = MBProgressHUD; target = DBA6001481CEA0EBA031CC5C94508FAA /* MBProgressHUD */; targetProxy = 270EA59E24CAB44BDCA7DB0DA7A6F1D1 /* PBXContainerItemProxy */; }; 139FBC21E1CB73F82F8B1743E52D1EF6 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = FBSDKShareKit; target = 30D7FCF8072F5D59AE1C98D94F9A6EC9 /* FBSDKShareKit */; targetProxy = 46FA7B947B9FCF27662BE469AFF096FB /* PBXContainerItemProxy */; }; 4CE22CABA129BAE1348F4B36284D8127 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Bolts; target = 9D0F2E5EA1B46A5D72FFD42B0B39DBBC /* Bolts */; targetProxy = C13E21E46BB08E336B9E99E2F4692737 /* PBXContainerItemProxy */; }; 4F3CF331AB806BC4E9978A9118632162 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = FBSDKCoreKit; target = 2E303C3CE7513908EE880D9CA833AFAE /* FBSDKCoreKit */; targetProxy = CFD970D7ADCC55CB11A7402ECAE02E55 /* PBXContainerItemProxy */; }; 6ACD044A3B887324FB6A92693812C59A /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = FBSDKLoginKit; target = 6EDC37F3FA92533C6AC3562458AA91F1 /* FBSDKLoginKit */; targetProxy = 04885811A1E85B2610448FED0600982B /* PBXContainerItemProxy */; }; 77E641A0F4480E12163BBB54ADED6998 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Bolts; target = 9D0F2E5EA1B46A5D72FFD42B0B39DBBC /* Bolts */; targetProxy = 1A8A0E3BE6FC4BDD4E2FFCAAB1F20283 /* PBXContainerItemProxy */; }; 84B3D926308714AC862F533D62D805DB /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Bolts; target = 9D0F2E5EA1B46A5D72FFD42B0B39DBBC /* Bolts */; targetProxy = 4C73BEFB46A6D4619DFC813CAFC63D53 /* PBXContainerItemProxy */; }; 896047CEFBF1EFA2F8D8ABCB6ACD9443 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = FBSDKCoreKit; target = 2E303C3CE7513908EE880D9CA833AFAE /* FBSDKCoreKit */; targetProxy = 5C144475AA961A86DFD9B6E49984B8EA /* PBXContainerItemProxy */; }; 99FADC94C30669B9B0BF540174328DBA /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = SwiftyJSON; target = 5DA0B374CB34642F0B891ACE7F3ED50F /* SwiftyJSON */; targetProxy = A12C5FB126E9FA1F5F9109342191175A /* PBXContainerItemProxy */; }; D980AFCB2A4B8B4D1FC725E7261E4D77 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = AFNetworking; target = 1C3436CEA5C3D39764C5F54374794ECB /* AFNetworking */; targetProxy = 10883D98BB53A5B0A4EF5071471F6244 /* PBXContainerItemProxy */; }; EE4106E226CB0BEB4B8D5572E612A79A /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = FBSDKCoreKit; target = 2E303C3CE7513908EE880D9CA833AFAE /* FBSDKCoreKit */; targetProxy = ED9B8F8F8F84D09DE8A86E81383E7B0D /* PBXContainerItemProxy */; }; F78FDB1EA04228A084EDD2BDDD2A09A5 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = Bolts; target = 9D0F2E5EA1B46A5D72FFD42B0B39DBBC /* Bolts */; targetProxy = DFB7D8638BEFDCC4CCF33BEB67F1B89B /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ 041BC100E31DF3ACE9767FAB788E8DD0 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 092A7AF28E09B340E2144F1A7C3DB11D /* FBSDKShareKit.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/FBSDKShareKit/FBSDKShareKit-prefix.pch"; INFOPLIST_FILE = "Target Support Files/FBSDKShareKit/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/FBSDKShareKit/FBSDKShareKit.modulemap"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = FBSDKShareKit; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; 09E46493E085E6E38E08137AA69E1BD9 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = B4BD47DBB5D86200A94802EA1CC0A77D /* Pods-PotterPics.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "Target Support Files/Pods-PotterPics/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 10; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-PotterPics/Pods-PotterPics.modulemap"; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = Pods_PotterPics; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; 0D14FDAAB7CC2EA7CF49E8F9FED4F7C3 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 1D9675CE2687A056DD6C5B6D2FE1612F /* SwiftyJSON.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/SwiftyJSON/SwiftyJSON-prefix.pch"; INFOPLIST_FILE = "Target Support Files/SwiftyJSON/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/SwiftyJSON/SwiftyJSON.modulemap"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = SwiftyJSON; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; 0E98EF9CD9FFD12A8C400554058C3DD2 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 30604910CF1BC094BCC4758C0D9FFAC1 /* AFNetworking.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/AFNetworking/AFNetworking-prefix.pch"; INFOPLIST_FILE = "Target Support Files/AFNetworking/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/AFNetworking/AFNetworking.modulemap"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = AFNetworking; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; 2460ACC06F532D3C8C5975B8A7386A25 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 83B9FE5A6E28DEC5A912C0035C98DEC1 /* MBProgressHUD.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/MBProgressHUD/MBProgressHUD-prefix.pch"; INFOPLIST_FILE = "Target Support Files/MBProgressHUD/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/MBProgressHUD/MBProgressHUD.modulemap"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = MBProgressHUD; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; 29FA920B37ACCB96F149EF2AEED7928B /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 4E85A2F1733B0E0D31747F4281783C80 /* FBSDKLoginKit.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/FBSDKLoginKit/FBSDKLoginKit-prefix.pch"; INFOPLIST_FILE = "Target Support Files/FBSDKLoginKit/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/FBSDKLoginKit/FBSDKLoginKit.modulemap"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = FBSDKLoginKit; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; 2D66363A9A084D6562A99C4C9239400F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGNING_REQUIRED = NO; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PREPROCESSOR_DEFINITIONS = ( "POD_CONFIGURATION_RELEASE=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 10; PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; STRIP_INSTALLED_PRODUCT = NO; SYMROOT = "${SRCROOT}/../build"; VALIDATE_PRODUCT = YES; }; name = Release; }; 32073F70E6AB7AE7033D0C706004125C /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7DB5DEB6C6536F5E4950DAFE15ADD32B /* Bolts.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/Bolts/Bolts-prefix.pch"; INFOPLIST_FILE = "Target Support Files/Bolts/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/Bolts/Bolts.modulemap"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = Bolts; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; 34C1D23DD2997E24C6462F7EE791E4EC /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGNING_REQUIRED = NO; COPY_PHASE_STRIP = NO; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "POD_CONFIGURATION_DEBUG=1", "DEBUG=1", "$(inherited)", ); GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 10; ONLY_ACTIVE_ARCH = YES; PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; STRIP_INSTALLED_PRODUCT = NO; SYMROOT = "${SRCROOT}/../build"; }; name = Debug; }; 3586171477BF915F3F1C23C60D1A5276 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = C8AA990ECA07A22AF023B8A8DCF96F15 /* Pods-PotterPicsTests.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "Target Support Files/Pods-PotterPicsTests/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 10; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-PotterPicsTests/Pods-PotterPicsTests.modulemap"; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = Pods_PotterPicsTests; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; 503F89E418DE170188142127F122E5CF /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 23D3CB6E9A2578A033EBBD68B00CC950 /* FBSDKCoreKit.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/FBSDKCoreKit/FBSDKCoreKit-prefix.pch"; INFOPLIST_FILE = "Target Support Files/FBSDKCoreKit/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/FBSDKCoreKit/FBSDKCoreKit.modulemap"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = FBSDKCoreKit; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; 6781882ADB9D32465BFFA168E40B47B0 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = A4DA14531EDBF80122B1186502DF438A /* Pods-PotterPics.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "Target Support Files/Pods-PotterPics/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 10; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-PotterPics/Pods-PotterPics.modulemap"; MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = Pods_PotterPics; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; 7FE6EE0E1D9220C2C52FF8D9391F2DFB /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 23D3CB6E9A2578A033EBBD68B00CC950 /* FBSDKCoreKit.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/FBSDKCoreKit/FBSDKCoreKit-prefix.pch"; INFOPLIST_FILE = "Target Support Files/FBSDKCoreKit/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/FBSDKCoreKit/FBSDKCoreKit.modulemap"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = FBSDKCoreKit; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; B3C681843D391FACCA50FF5A56949B5F /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7184C94179AA7BAB332BAEDD3A85C0D0 /* Pods-PotterPicsUITests.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "Target Support Files/Pods-PotterPicsUITests/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 10; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-PotterPicsUITests/Pods-PotterPicsUITests.modulemap"; MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = Pods_PotterPicsUITests; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; B574F831B13D0D2E228DB04E74CA5E79 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 4E85A2F1733B0E0D31747F4281783C80 /* FBSDKLoginKit.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/FBSDKLoginKit/FBSDKLoginKit-prefix.pch"; INFOPLIST_FILE = "Target Support Files/FBSDKLoginKit/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/FBSDKLoginKit/FBSDKLoginKit.modulemap"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = FBSDKLoginKit; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; B65F72D79489A78C74E59B6A9748A30F /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 1D9675CE2687A056DD6C5B6D2FE1612F /* SwiftyJSON.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/SwiftyJSON/SwiftyJSON-prefix.pch"; INFOPLIST_FILE = "Target Support Files/SwiftyJSON/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/SwiftyJSON/SwiftyJSON.modulemap"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = SwiftyJSON; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; C19FEBBE4FE499F6FF03C6C69A4CDACA /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 30604910CF1BC094BCC4758C0D9FFAC1 /* AFNetworking.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/AFNetworking/AFNetworking-prefix.pch"; INFOPLIST_FILE = "Target Support Files/AFNetworking/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/AFNetworking/AFNetworking.modulemap"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = AFNetworking; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; C982F2E5923C436EA4AA179DDBDA6BD0 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7DB5DEB6C6536F5E4950DAFE15ADD32B /* Bolts.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/Bolts/Bolts-prefix.pch"; INFOPLIST_FILE = "Target Support Files/Bolts/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/Bolts/Bolts.modulemap"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = Bolts; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; CCB42F690FD383163AB8E7B4A48397C0 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = D6D5AD1E8060B45D6A24CF893CB9EDD2 /* Pods-PotterPicsUITests.release.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "Target Support Files/Pods-PotterPicsUITests/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 10; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-PotterPicsUITests/Pods-PotterPicsUITests.modulemap"; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = Pods_PotterPicsUITests; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; D00C670FE93493B4542B69A1575A2BD8 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 092A7AF28E09B340E2144F1A7C3DB11D /* FBSDKShareKit.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/FBSDKShareKit/FBSDKShareKit-prefix.pch"; INFOPLIST_FILE = "Target Support Files/FBSDKShareKit/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/FBSDKShareKit/FBSDKShareKit.modulemap"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = FBSDKShareKit; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; D235CE705FFFBE57228FAF18B4A11103 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 3FE115C8BE13A55F5DF0A63878484024 /* Pods-PotterPicsTests.debug.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "Target Support Files/Pods-PotterPicsTests/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 10; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-PotterPicsTests/Pods-PotterPicsTests.modulemap"; MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = Pods_PotterPicsTests; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; DEC65FD817AEA0050E555E93FCA745B3 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 83B9FE5A6E28DEC5A912C0035C98DEC1 /* MBProgressHUD.xcconfig */; buildSettings = { "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/MBProgressHUD/MBProgressHUD-prefix.pch"; INFOPLIST_FILE = "Target Support Files/MBProgressHUD/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/MBProgressHUD/MBProgressHUD.modulemap"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = MBProgressHUD; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 19E23EED00D7A70A3012305F0EAAC6F7 /* Build configuration list for PBXNativeTarget "Bolts" */ = { isa = XCConfigurationList; buildConfigurations = ( 32073F70E6AB7AE7033D0C706004125C /* Debug */, C982F2E5923C436EA4AA179DDBDA6BD0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 1B919EAB713C4FB469DCEAC27277542C /* Build configuration list for PBXNativeTarget "SwiftyJSON" */ = { isa = XCConfigurationList; buildConfigurations = ( 0D14FDAAB7CC2EA7CF49E8F9FED4F7C3 /* Debug */, B65F72D79489A78C74E59B6A9748A30F /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 1E2C012DEECFAAEF8B8A9CE1E8AAA03C /* Build configuration list for PBXNativeTarget "MBProgressHUD" */ = { isa = XCConfigurationList; buildConfigurations = ( 2460ACC06F532D3C8C5975B8A7386A25 /* Debug */, DEC65FD817AEA0050E555E93FCA745B3 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( 34C1D23DD2997E24C6462F7EE791E4EC /* Debug */, 2D66363A9A084D6562A99C4C9239400F /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 32ED130D3F319966AE7EECBEC8F1A552 /* Build configuration list for PBXNativeTarget "FBSDKLoginKit" */ = { isa = XCConfigurationList; buildConfigurations = ( B574F831B13D0D2E228DB04E74CA5E79 /* Debug */, 29FA920B37ACCB96F149EF2AEED7928B /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 3C71ACC1F6C9EEE584A9BCA75FAAA8F8 /* Build configuration list for PBXNativeTarget "Pods-PotterPicsTests" */ = { isa = XCConfigurationList; buildConfigurations = ( D235CE705FFFBE57228FAF18B4A11103 /* Debug */, 3586171477BF915F3F1C23C60D1A5276 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 57800A0D1724774333EF09E83030AA81 /* Build configuration list for PBXNativeTarget "AFNetworking" */ = { isa = XCConfigurationList; buildConfigurations = ( C19FEBBE4FE499F6FF03C6C69A4CDACA /* Debug */, 0E98EF9CD9FFD12A8C400554058C3DD2 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 61A0B904D3869084422346EF6B14CEF1 /* Build configuration list for PBXNativeTarget "Pods-PotterPicsUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( B3C681843D391FACCA50FF5A56949B5F /* Debug */, CCB42F690FD383163AB8E7B4A48397C0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 6C3DF0533D78EEF9D06FF5B09ACE469C /* Build configuration list for PBXNativeTarget "Pods-PotterPics" */ = { isa = XCConfigurationList; buildConfigurations = ( 6781882ADB9D32465BFFA168E40B47B0 /* Debug */, 09E46493E085E6E38E08137AA69E1BD9 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; BE44A0803B9534732B5A6586C44D793C /* Build configuration list for PBXNativeTarget "FBSDKCoreKit" */ = { isa = XCConfigurationList; buildConfigurations = ( 503F89E418DE170188142127F122E5CF /* Debug */, 7FE6EE0E1D9220C2C52FF8D9391F2DFB /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; C6E7F424D9A74E5A77B81FDB91D47E00 /* Build configuration list for PBXNativeTarget "FBSDKShareKit" */ = { isa = XCConfigurationList; buildConfigurations = ( 041BC100E31DF3ACE9767FAB788E8DD0 /* Debug */, D00C670FE93493B4542B69A1575A2BD8 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; } ================================================ FILE: Pods/SwiftyJSON/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2016 Ruoyu Fu 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. ================================================ FILE: Pods/SwiftyJSON/README.md ================================================ #SwiftyJSON [![Travis CI](https://travis-ci.org/SwiftyJSON/SwiftyJSON.svg?branch=master)](https://travis-ci.org/SwiftyJSON/SwiftyJSON) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) ![CocoaPods](https://img.shields.io/cocoapods/v/SwiftyJSON.svg) ![Platform](https://img.shields.io/badge/platforms-iOS%208.0+%20%7C%20macOS%2010.10+%20%7C%20tvOS%209.0+%20%7C%20watchOS%202.0+-333333.svg) SwiftyJSON makes it easy to deal with JSON data in Swift. 1. [Why is the typical JSON handling in Swift NOT good](#why-is-the-typical-json-handling-in-swift-not-good) 2. [Requirements](#requirements) 3. [Integration](#integration) 4. [Usage](#usage) - [Initialization](#initialization) - [Subscript](#subscript) - [Loop](#loop) - [Error](#error) - [Optional getter](#optional-getter) - [Non-optional getter](#non-optional-getter) - [Setter](#setter) - [Raw object](#raw-object) - [Literal convertibles](#literal-convertibles) 5. [Work with Alamofire](#work-with-alamofire) > For Legacy Swift support, take a look at the [swift2 branch](https://github.com/SwiftyJSON/SwiftyJSON/tree/swift2) > [中文介绍](http://tangplin.github.io/swiftyjson/) ##Why is the typical JSON handling in Swift NOT good? Swift is very strict about types. But although explicit typing is good for saving us from mistakes, it becomes painful when dealing with JSON and other areas that are, by nature, implicit about types. Take the Twitter API for example. Say we want to retrieve a user's "name" value of some tweet in Swift (according to Twitter's API https://dev.twitter.com/docs/api/1.1/get/statuses/home_timeline). The code would look like this: ```swift if let statusesArray = try? NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments) as? [[String: AnyObject]], let user = statusesArray[0]["user"] as? [String: AnyObject], let username = user["name"] as? String { // Finally we got the username } ``` It's not good. Even if we use optional chaining, it would be messy: ```swift if let JSONObject = try NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments) as? [[String: AnyObject]], let username = (JSONObject[0]["user"] as? [String: AnyObject])?["name"] as? String { // There's our username } ``` An unreadable mess--for something that should really be simple! With SwiftyJSON all you have to do is: ```swift let json = JSON(data: dataFromNetworking) if let userName = json[0]["user"]["name"].string { //Now you got your value } ``` And don't worry about the Optional Wrapping thing. It's done for you automatically. ```swift let json = JSON(data: dataFromNetworking) if let userName = json[999999]["wrong_key"]["wrong_name"].string { //Calm down, take it easy, the ".string" property still produces the correct Optional String type with safety } else { //Print the error print(json[999999]["wrong_key"]["wrong_name"]) } ``` ## Requirements - iOS 8.0+ | macOS 10.10+ | tvOS 9.0+ | watchOS 2.0+ - Xcode 8 ##Integration ####CocoaPods (iOS 8+, OS X 10.9+) You can use [CocoaPods](http://cocoapods.org/) to install `SwiftyJSON`by adding it to your `Podfile`: ```ruby platform :ios, '8.0' use_frameworks! target 'MyApp' do pod 'SwiftyJSON' end ``` Note that this requires CocoaPods version 36, and your iOS deployment target to be at least 8.0: ####Carthage (iOS 8+, OS X 10.9+) You can use [Carthage](https://github.com/Carthage/Carthage) to install `SwiftyJSON` by adding it to your `Cartfile`: ``` github "SwiftyJSON/SwiftyJSON" ``` ####Swift Package Manager You can use [The Swift Package Manager](https://swift.org/package-manager) to install `SwiftyJSON` by adding the proper description to your `Package.swift` file: ```swift import PackageDescription let package = Package( name: "YOUR_PROJECT_NAME", targets: [], dependencies: [ .Package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", versions: Version(1,0,0).. = json["list"].arrayValue ``` ```swift //If not a Dictionary or nil, return [:] let user: Dictionary = json["user"].dictionaryValue ``` ####Setter ```swift json["name"] = JSON("new-name") json[0] = JSON(1) ``` ```swift json["id"].int = 1234567890 json["coordinate"].double = 8766.766 json["name"].string = "Jack" json.arrayObject = [1,2,3,4] json.dictionaryObject = ["name":"Jack", "age":25] ``` ####Raw object ```swift let jsonObject: AnyObject = json.object ``` ```swift if let jsonObject: AnyObject = json.rawValue ``` ```swift //convert the JSON to raw NSData if let data = json.rawData() { //Do something you want } ``` ```swift //convert the JSON to a raw String if let string = json.rawString() { //Do something you want } ``` ####Existence ```swift //shows you whether value specified in JSON or not if json["name"].exists() ``` ####Literal convertibles For more info about literal convertibles: [Swift Literal Convertibles](http://nshipster.com/swift-literal-convertible/) ```swift //StringLiteralConvertible let json: JSON = "I'm a json" ``` ```swift //IntegerLiteralConvertible let json: JSON = 12345 ``` ```swift //BooleanLiteralConvertible let json: JSON = true ``` ```swift //FloatLiteralConvertible let json: JSON = 2.8765 ``` ```swift //DictionaryLiteralConvertible let json: JSON = ["I":"am", "a":"json"] ``` ```swift //ArrayLiteralConvertible let json: JSON = ["I", "am", "a", "json"] ``` ```swift //NilLiteralConvertible let json: JSON = nil ``` ```swift //With subscript in array var json: JSON = [1,2,3] json[0] = 100 json[1] = 200 json[2] = 300 json[999] = 300 //Don't worry, nothing will happen ``` ```swift //With subscript in dictionary var json: JSON = ["name": "Jack", "age": 25] json["name"] = "Mike" json["age"] = "25" //It's OK to set String json["address"] = "L.A." // Add the "address": "L.A." in json ``` ```swift //Array & Dictionary var json: JSON = ["name": "Jack", "age": 25, "list": ["a", "b", "c", ["what": "this"]]] json["list"][3]["what"] = "that" json["list",3,"what"] = "that" let path = ["list",3,"what"] json[path] = "that" ``` ```swift //With other JSON objects let user: JSON = ["username" : "Steve", "password": "supersecurepassword"] let auth: JSON = [ "user": user.object //use user.object instead of just user "apikey": "supersecretapitoken" ] ```` ##Work with Alamofire SwiftyJSON nicely wraps the result of the Alamofire JSON response handler: ```swift Alamofire.request(.GET, url).validate().responseJSON { response in switch response.result { case .success(let value): let json = JSON(value) print("JSON: \(json)") case .failure(let error): print(error) } } ``` ================================================ FILE: Pods/SwiftyJSON/Source/SwiftyJSON.swift ================================================ // SwiftyJSON.swift // // Copyright (c) 2014 - 2016 Ruoyu Fu, Pinglin Tang // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. import Foundation // MARK: - Error ///Error domain public let ErrorDomain: String = "SwiftyJSONErrorDomain" ///Error code public let ErrorUnsupportedType: Int = 999 public let ErrorIndexOutOfBounds: Int = 900 public let ErrorWrongType: Int = 901 public let ErrorNotExist: Int = 500 public let ErrorInvalidJSON: Int = 490 // MARK: - JSON Type /** JSON's type definitions. See http://www.json.org */ public enum Type :Int{ case number case string case bool case array case dictionary case null case unknown } // MARK: - JSON Base public struct JSON { /** Creates a JSON using the data. - parameter data: The NSData used to convert to json.Top level object in data is an NSArray or NSDictionary - parameter opt: The JSON serialization reading options. `.AllowFragments` by default. - parameter error: The NSErrorPointer used to return the error. `nil` by default. - returns: The created JSON */ public init(data:Data, options opt: JSONSerialization.ReadingOptions = .allowFragments, error: NSErrorPointer = nil) { do { let object: Any = try JSONSerialization.jsonObject(with: data, options: opt) self.init(object) } catch let aError as NSError { if error != nil { error?.pointee = aError } self.init(NSNull()) } } /** Creates a JSON from JSON string - parameter string: Normal json string like '{"a":"b"}' - returns: The created JSON */ public static func parse(_ string:String) -> JSON { return string.data(using: String.Encoding.utf8) .flatMap{ JSON(data: $0) } ?? JSON(NSNull()) } /** Creates a JSON using the object. - parameter object: The object must have the following properties: All objects are NSString/String, NSNumber/Int/Float/Double/Bool, NSArray/Array, NSDictionary/Dictionary, or NSNull; All dictionary keys are NSStrings/String; NSNumbers are not NaN or infinity. - returns: The created JSON */ public init(_ object: Any) { self.object = object } /** Creates a JSON from a [JSON] - parameter jsonArray: A Swift array of JSON objects - returns: The created JSON */ public init(_ jsonArray:[JSON]) { self.init(jsonArray.map { $0.object }) } /** Creates a JSON from a [String: JSON] - parameter jsonDictionary: A Swift dictionary of JSON objects - returns: The created JSON */ public init(_ jsonDictionary:[String: JSON]) { var dictionary = [String: Any](minimumCapacity: jsonDictionary.count) for (key, json) in jsonDictionary { dictionary[key] = json.object } self.init(dictionary) } /// Private object fileprivate var rawArray: [Any] = [] fileprivate var rawDictionary: [String : Any] = [:] fileprivate var rawString: String = "" fileprivate var rawNumber: NSNumber = 0 fileprivate var rawNull: NSNull = NSNull() fileprivate var rawBool: Bool = false /// Private type fileprivate var _type: Type = .null /// prviate error fileprivate var _error: NSError? = nil /// Object in JSON public var object: Any { get { switch self.type { case .array: return self.rawArray case .dictionary: return self.rawDictionary case .string: return self.rawString case .number: return self.rawNumber case .bool: return self.rawBool default: return self.rawNull } } set { _error = nil switch newValue { case let number as NSNumber: if number.isBool { _type = .bool self.rawBool = number.boolValue } else { _type = .number self.rawNumber = number } case let string as String: _type = .string self.rawString = string case _ as NSNull: _type = .null case let array as [JSON]: _type = .array self.rawArray = array.map { $0.object } case let array as [Any]: _type = .array self.rawArray = array case let dictionary as [String : Any]: _type = .dictionary self.rawDictionary = dictionary default: _type = .unknown _error = NSError(domain: ErrorDomain, code: ErrorUnsupportedType, userInfo: [NSLocalizedDescriptionKey: "It is a unsupported type"]) } } } /// JSON type public var type: Type { get { return _type } } /// Error in JSON public var error: NSError? { get { return self._error } } /// The static null JSON @available(*, unavailable, renamed:"null") public static var nullJSON: JSON { get { return null } } public static var null: JSON { get { return JSON(NSNull()) } } } public enum JSONIndex:Comparable { case array(Int) case dictionary(DictionaryIndex) case null } public func ==(lhs: JSONIndex, rhs: JSONIndex) -> Bool { switch (lhs, rhs) { case (.array(let left), .array(let right)): return left == right case (.dictionary(let left), .dictionary(let right)): return left == right case (.null, .null): return true default: return false } } public func <(lhs: JSONIndex, rhs: JSONIndex) -> Bool { switch (lhs, rhs) { case (.array(let left), .array(let right)): return left < right case (.dictionary(let left), .dictionary(let right)): return left < right default: return false } } extension JSON: Collection { public typealias Index = JSONIndex public var startIndex: Index { switch type { case .array: return .array(rawArray.startIndex) case .dictionary: return .dictionary(dictionaryValue.startIndex) default: return .null } } public var endIndex: Index { switch type { case .array: return .array(rawArray.endIndex) case .dictionary: return .dictionary(dictionaryValue.endIndex) default: return .null } } public func index(after i: Index) -> Index { switch i { case .array(let idx): return .array(rawArray.index(after: idx)) case .dictionary(let idx): return .dictionary(dictionaryValue.index(after: idx)) default: return .null } } public subscript (position: Index) -> (String, JSON) { switch position { case .array(let idx): return (String(idx), JSON(self.rawArray[idx])) case .dictionary(let idx): return dictionaryValue[idx] default: return ("", JSON.null) } } } // MARK: - Subscript /** * To mark both String and Int can be used in subscript. */ public enum JSONKey { case index(Int) case key(String) } public protocol JSONSubscriptType { var jsonKey:JSONKey { get } } extension Int: JSONSubscriptType { public var jsonKey:JSONKey { return JSONKey.index(self) } } extension String: JSONSubscriptType { public var jsonKey:JSONKey { return JSONKey.key(self) } } extension JSON { /// If `type` is `.Array`, return json whose object is `array[index]`, otherwise return null json with error. fileprivate subscript(index index: Int) -> JSON { get { if self.type != .array { var r = JSON.null r._error = self._error ?? NSError(domain: ErrorDomain, code: ErrorWrongType, userInfo: [NSLocalizedDescriptionKey: "Array[\(index)] failure, It is not an array"]) return r } else if index >= 0 && index < self.rawArray.count { return JSON(self.rawArray[index]) } else { var r = JSON.null r._error = NSError(domain: ErrorDomain, code:ErrorIndexOutOfBounds , userInfo: [NSLocalizedDescriptionKey: "Array[\(index)] is out of bounds"]) return r } } set { if self.type == .array { if self.rawArray.count > index && newValue.error == nil { self.rawArray[index] = newValue.object } } } } /// If `type` is `.Dictionary`, return json whose object is `dictionary[key]` , otherwise return null json with error. fileprivate subscript(key key: String) -> JSON { get { var r = JSON.null if self.type == .dictionary { if let o = self.rawDictionary[key] { r = JSON(o) } else { r._error = NSError(domain: ErrorDomain, code: ErrorNotExist, userInfo: [NSLocalizedDescriptionKey: "Dictionary[\"\(key)\"] does not exist"]) } } else { r._error = self._error ?? NSError(domain: ErrorDomain, code: ErrorWrongType, userInfo: [NSLocalizedDescriptionKey: "Dictionary[\"\(key)\"] failure, It is not an dictionary"]) } return r } set { if self.type == .dictionary && newValue.error == nil { self.rawDictionary[key] = newValue.object } } } /// If `sub` is `Int`, return `subscript(index:)`; If `sub` is `String`, return `subscript(key:)`. fileprivate subscript(sub sub: JSONSubscriptType) -> JSON { get { switch sub.jsonKey { case .index(let index): return self[index: index] case .key(let key): return self[key: key] } } set { switch sub.jsonKey { case .index(let index): self[index: index] = newValue case .key(let key): self[key: key] = newValue } } } /** Find a json in the complex data structures by using array of Int and/or String as path. - parameter path: The target json's path. Example: let json = JSON[data] let path = [9,"list","person","name"] let name = json[path] The same as: let name = json[9]["list"]["person"]["name"] - returns: Return a json found by the path or a null json with error */ public subscript(path: [JSONSubscriptType]) -> JSON { get { return path.reduce(self) { $0[sub: $1] } } set { switch path.count { case 0: return case 1: self[sub:path[0]].object = newValue.object default: var aPath = path; aPath.remove(at: 0) var nextJSON = self[sub: path[0]] nextJSON[aPath] = newValue self[sub: path[0]] = nextJSON } } } /** Find a json in the complex data structures by using array of Int and/or String as path. - parameter path: The target json's path. Example: let name = json[9,"list","person","name"] The same as: let name = json[9]["list"]["person"]["name"] - returns: Return a json found by the path or a null json with error */ public subscript(path: JSONSubscriptType...) -> JSON { get { return self[path] } set { self[path] = newValue } } } // MARK: - LiteralConvertible extension JSON: Swift.ExpressibleByStringLiteral { public init(stringLiteral value: StringLiteralType) { self.init(value as Any) } public init(extendedGraphemeClusterLiteral value: StringLiteralType) { self.init(value as Any) } public init(unicodeScalarLiteral value: StringLiteralType) { self.init(value as Any) } } extension JSON: Swift.ExpressibleByIntegerLiteral { public init(integerLiteral value: IntegerLiteralType) { self.init(value as Any) } } extension JSON: Swift.ExpressibleByBooleanLiteral { public init(booleanLiteral value: BooleanLiteralType) { self.init(value as Any) } } extension JSON: Swift.ExpressibleByFloatLiteral { public init(floatLiteral value: FloatLiteralType) { self.init(value as Any) } } extension JSON: Swift.ExpressibleByDictionaryLiteral { public init(dictionaryLiteral elements: (String, Any)...) { let array = elements self.init(dictionaryLiteral: array) } public init(dictionaryLiteral elements: [(String, Any)]) { let jsonFromDictionaryLiteral: ([String : Any]) -> JSON = { dictionary in let initializeElement = Array(dictionary.keys).flatMap { key -> (String, Any)? in if let value = dictionary[key] { return (key, value) } return nil } return JSON(dictionaryLiteral: initializeElement) } var dict = [String : Any](minimumCapacity: elements.count) for element in elements { let elementToSet: Any if let json = element.1 as? JSON { elementToSet = json.object } else if let jsonArray = element.1 as? [JSON] { elementToSet = JSON(jsonArray).object } else if let dictionary = element.1 as? [String : Any] { elementToSet = jsonFromDictionaryLiteral(dictionary).object } else if let dictArray = element.1 as? [[String : Any]] { let jsonArray = dictArray.map { jsonFromDictionaryLiteral($0) } elementToSet = JSON(jsonArray).object } else { elementToSet = element.1 } dict[element.0] = elementToSet } self.init(dict) } } extension JSON: Swift.ExpressibleByArrayLiteral { public init(arrayLiteral elements: Any...) { self.init(elements as Any) } } extension JSON: Swift.ExpressibleByNilLiteral { public init(nilLiteral: ()) { self.init(NSNull() as Any) } } // MARK: - Raw extension JSON: Swift.RawRepresentable { public init?(rawValue: Any) { if JSON(rawValue).type == .unknown { return nil } else { self.init(rawValue) } } public var rawValue: Any { return self.object } public func rawData(options opt: JSONSerialization.WritingOptions = JSONSerialization.WritingOptions(rawValue: 0)) throws -> Data { guard JSONSerialization.isValidJSONObject(self.object) else { throw NSError(domain: ErrorDomain, code: ErrorInvalidJSON, userInfo: [NSLocalizedDescriptionKey: "JSON is invalid"]) } return try JSONSerialization.data(withJSONObject: self.object, options: opt) } public func rawString(_ encoding: String.Encoding = String.Encoding.utf8, options opt: JSONSerialization.WritingOptions = .prettyPrinted) -> String? { switch self.type { case .array, .dictionary: do { let data = try self.rawData(options: opt) return String(data: data, encoding: encoding) } catch _ { return nil } case .string: return self.rawString case .number: return self.rawNumber.stringValue case .bool: return self.rawBool.description case .null: return "null" default: return nil } } } // MARK: - Printable, DebugPrintable extension JSON: Swift.CustomStringConvertible, Swift.CustomDebugStringConvertible { public var description: String { if let string = self.rawString(options:.prettyPrinted) { return string } else { return "unknown" } } public var debugDescription: String { return description } } // MARK: - Array extension JSON { //Optional [JSON] public var array: [JSON]? { get { if self.type == .array { return self.rawArray.map{ JSON($0) } } else { return nil } } } //Non-optional [JSON] public var arrayValue: [JSON] { get { return self.array ?? [] } } //Optional [AnyObject] public var arrayObject: [Any]? { get { switch self.type { case .array: return self.rawArray default: return nil } } set { if let array = newValue { self.object = array as Any } else { self.object = NSNull() } } } } // MARK: - Dictionary extension JSON { //Optional [String : JSON] public var dictionary: [String : JSON]? { if self.type == .dictionary { var d = [String : JSON](minimumCapacity: rawDictionary.count) for (key, value) in rawDictionary { d[key] = JSON(value) } return d } else { return nil } } //Non-optional [String : JSON] public var dictionaryValue: [String : JSON] { return self.dictionary ?? [:] } //Optional [String : AnyObject] public var dictionaryObject: [String : Any]? { get { switch self.type { case .dictionary: return self.rawDictionary default: return nil } } set { if let v = newValue { self.object = v as Any } else { self.object = NSNull() } } } } // MARK: - Bool extension JSON { // : Swift.Bool //Optional bool public var bool: Bool? { get { switch self.type { case .bool: return self.rawBool default: return nil } } set { if let newValue = newValue { self.object = newValue as Bool } else { self.object = NSNull() } } } //Non-optional bool public var boolValue: Bool { get { switch self.type { case .bool: return self.rawBool case .number: return self.rawNumber.boolValue case .string: return self.rawString.caseInsensitiveCompare("true") == .orderedSame default: return false } } set { self.object = newValue } } } // MARK: - String extension JSON { //Optional string public var string: String? { get { switch self.type { case .string: return self.object as? String default: return nil } } set { if let newValue = newValue { self.object = NSString(string:newValue) } else { self.object = NSNull() } } } //Non-optional string public var stringValue: String { get { switch self.type { case .string: return self.object as? String ?? "" case .number: return self.rawNumber.stringValue case .bool: return (self.object as? Bool).map { String($0) } ?? "" default: return "" } } set { self.object = NSString(string:newValue) } } } // MARK: - Number extension JSON { //Optional number public var number: NSNumber? { get { switch self.type { case .number: return self.rawNumber case .bool: return NSNumber(value: self.rawBool ? 1 : 0) default: return nil } } set { self.object = newValue ?? NSNull() } } //Non-optional number public var numberValue: NSNumber { get { switch self.type { case .string: let decimal = NSDecimalNumber(string: self.object as? String) if decimal == NSDecimalNumber.notANumber { // indicates parse error return NSDecimalNumber.zero } return decimal case .number: return self.object as? NSNumber ?? NSNumber(value: 0) case .bool: return NSNumber(value: self.rawBool ? 1 : 0) default: return NSNumber(value: 0.0) } } set { self.object = newValue } } } //MARK: - Null extension JSON { public var null: NSNull? { get { switch self.type { case .null: return self.rawNull default: return nil } } set { self.object = NSNull() } } public func exists() -> Bool{ if let errorValue = error, errorValue.code == ErrorNotExist || errorValue.code == ErrorIndexOutOfBounds || errorValue.code == ErrorWrongType { return false } return true } } //MARK: - URL extension JSON { //Optional URL public var URL: URL? { get { switch self.type { case .string: if let encodedString_ = self.rawString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) { // We have to use `Foundation.URL` otherwise it conflicts with the variable name. return Foundation.URL(string: encodedString_) } else { return nil } default: return nil } } set { self.object = newValue?.absoluteString } } } // MARK: - Int, Double, Float, Int8, Int16, Int32, Int64 extension JSON { public var double: Double? { get { return self.number?.doubleValue } set { if let newValue = newValue { self.object = NSNumber(value: newValue) } else { self.object = NSNull() } } } public var doubleValue: Double { get { return self.numberValue.doubleValue } set { self.object = NSNumber(value: newValue) } } public var float: Float? { get { return self.number?.floatValue } set { if let newValue = newValue { self.object = NSNumber(value: newValue) } else { self.object = NSNull() } } } public var floatValue: Float { get { return self.numberValue.floatValue } set { self.object = NSNumber(value: newValue) } } public var int: Int? { get { return self.number?.intValue } set { if let newValue = newValue { self.object = NSNumber(value: newValue) } else { self.object = NSNull() } } } public var intValue: Int { get { return self.numberValue.intValue } set { self.object = NSNumber(value: newValue) } } public var uInt: UInt? { get { return self.number?.uintValue } set { if let newValue = newValue { self.object = NSNumber(value: newValue) } else { self.object = NSNull() } } } public var uIntValue: UInt { get { return self.numberValue.uintValue } set { self.object = NSNumber(value: newValue) } } public var int8: Int8? { get { return self.number?.int8Value } set { if let newValue = newValue { self.object = NSNumber(value: newValue) } else { self.object = NSNull() } } } public var int8Value: Int8 { get { return self.numberValue.int8Value } set { self.object = NSNumber(value: newValue) } } public var uInt8: UInt8? { get { return self.number?.uint8Value } set { if let newValue = newValue { self.object = NSNumber(value: newValue) } else { self.object = NSNull() } } } public var uInt8Value: UInt8 { get { return self.numberValue.uint8Value } set { self.object = NSNumber(value: newValue) } } public var int16: Int16? { get { return self.number?.int16Value } set { if let newValue = newValue { self.object = NSNumber(value: newValue) } else { self.object = NSNull() } } } public var int16Value: Int16 { get { return self.numberValue.int16Value } set { self.object = NSNumber(value: newValue) } } public var uInt16: UInt16? { get { return self.number?.uint16Value } set { if let newValue = newValue { self.object = NSNumber(value: newValue) } else { self.object = NSNull() } } } public var uInt16Value: UInt16 { get { return self.numberValue.uint16Value } set { self.object = NSNumber(value: newValue) } } public var int32: Int32? { get { return self.number?.int32Value } set { if let newValue = newValue { self.object = NSNumber(value: newValue) } else { self.object = NSNull() } } } public var int32Value: Int32 { get { return self.numberValue.int32Value } set { self.object = NSNumber(value: newValue) } } public var uInt32: UInt32? { get { return self.number?.uint32Value } set { if let newValue = newValue { self.object = NSNumber(value: newValue) } else { self.object = NSNull() } } } public var uInt32Value: UInt32 { get { return self.numberValue.uint32Value } set { self.object = NSNumber(value: newValue) } } public var int64: Int64? { get { return self.number?.int64Value } set { if let newValue = newValue { self.object = NSNumber(value: newValue) } else { self.object = NSNull() } } } public var int64Value: Int64 { get { return self.numberValue.int64Value } set { self.object = NSNumber(value: newValue) } } public var uInt64: UInt64? { get { return self.number?.uint64Value } set { if let newValue = newValue { self.object = NSNumber(value: newValue) } else { self.object = NSNull() } } } public var uInt64Value: UInt64 { get { return self.numberValue.uint64Value } set { self.object = NSNumber(value: newValue) } } } //MARK: - Comparable extension JSON : Swift.Comparable {} public func ==(lhs: JSON, rhs: JSON) -> Bool { switch (lhs.type, rhs.type) { case (.number, .number): return lhs.rawNumber == rhs.rawNumber case (.string, .string): return lhs.rawString == rhs.rawString case (.bool, .bool): return lhs.rawBool == rhs.rawBool case (.array, .array): return lhs.rawArray as NSArray == rhs.rawArray as NSArray case (.dictionary, .dictionary): return lhs.rawDictionary as NSDictionary == rhs.rawDictionary as NSDictionary case (.null, .null): return true default: return false } } public func <=(lhs: JSON, rhs: JSON) -> Bool { switch (lhs.type, rhs.type) { case (.number, .number): return lhs.rawNumber <= rhs.rawNumber case (.string, .string): return lhs.rawString <= rhs.rawString case (.bool, .bool): return lhs.rawBool == rhs.rawBool case (.array, .array): return lhs.rawArray as NSArray == rhs.rawArray as NSArray case (.dictionary, .dictionary): return lhs.rawDictionary as NSDictionary == rhs.rawDictionary as NSDictionary case (.null, .null): return true default: return false } } public func >=(lhs: JSON, rhs: JSON) -> Bool { switch (lhs.type, rhs.type) { case (.number, .number): return lhs.rawNumber >= rhs.rawNumber case (.string, .string): return lhs.rawString >= rhs.rawString case (.bool, .bool): return lhs.rawBool == rhs.rawBool case (.array, .array): return lhs.rawArray as NSArray == rhs.rawArray as NSArray case (.dictionary, .dictionary): return lhs.rawDictionary as NSDictionary == rhs.rawDictionary as NSDictionary case (.null, .null): return true default: return false } } public func >(lhs: JSON, rhs: JSON) -> Bool { switch (lhs.type, rhs.type) { case (.number, .number): return lhs.rawNumber > rhs.rawNumber case (.string, .string): return lhs.rawString > rhs.rawString default: return false } } public func <(lhs: JSON, rhs: JSON) -> Bool { switch (lhs.type, rhs.type) { case (.number, .number): return lhs.rawNumber < rhs.rawNumber case (.string, .string): return lhs.rawString < rhs.rawString default: return false } } private let trueNumber = NSNumber(value: true) private let falseNumber = NSNumber(value: false) private let trueObjCType = String(cString: trueNumber.objCType) private let falseObjCType = String(cString: falseNumber.objCType) // MARK: - NSNumber: Comparable extension NSNumber { var isBool:Bool { get { let objCType = String(cString: self.objCType) if (self.compare(trueNumber) == .orderedSame && objCType == trueObjCType) || (self.compare(falseNumber) == .orderedSame && objCType == falseObjCType){ return true } else { return false } } } } func ==(lhs: NSNumber, rhs: NSNumber) -> Bool { switch (lhs.isBool, rhs.isBool) { case (false, true): return false case (true, false): return false default: return lhs.compare(rhs) == .orderedSame } } func !=(lhs: NSNumber, rhs: NSNumber) -> Bool { return !(lhs == rhs) } func <(lhs: NSNumber, rhs: NSNumber) -> Bool { switch (lhs.isBool, rhs.isBool) { case (false, true): return false case (true, false): return false default: return lhs.compare(rhs) == .orderedAscending } } func >(lhs: NSNumber, rhs: NSNumber) -> Bool { switch (lhs.isBool, rhs.isBool) { case (false, true): return false case (true, false): return false default: return lhs.compare(rhs) == ComparisonResult.orderedDescending } } func <=(lhs: NSNumber, rhs: NSNumber) -> Bool { switch (lhs.isBool, rhs.isBool) { case (false, true): return false case (true, false): return false default: return lhs.compare(rhs) != .orderedDescending } } func >=(lhs: NSNumber, rhs: NSNumber) -> Bool { switch (lhs.isBool, rhs.isBool) { case (false, true): return false case (true, false): return false default: return lhs.compare(rhs) != .orderedAscending } } ================================================ FILE: Pods/Target Support Files/AFNetworking/AFNetworking-dummy.m ================================================ #import @interface PodsDummy_AFNetworking : NSObject @end @implementation PodsDummy_AFNetworking @end ================================================ FILE: Pods/Target Support Files/AFNetworking/AFNetworking-prefix.pch ================================================ #ifdef __OBJC__ #import #endif #ifndef TARGET_OS_IOS #define TARGET_OS_IOS TARGET_OS_IPHONE #endif #ifndef TARGET_OS_WATCH #define TARGET_OS_WATCH 0 #endif #ifndef TARGET_OS_TV #define TARGET_OS_TV 0 #endif ================================================ FILE: Pods/Target Support Files/AFNetworking/AFNetworking-umbrella.h ================================================ #import #import "AFNetworking.h" #import "AFHTTPSessionManager.h" #import "AFURLSessionManager.h" #import "AFNetworkReachabilityManager.h" #import "AFSecurityPolicy.h" #import "AFURLRequestSerialization.h" #import "AFURLResponseSerialization.h" #import "AFAutoPurgingImageCache.h" #import "AFImageDownloader.h" #import "AFNetworkActivityIndicatorManager.h" #import "UIActivityIndicatorView+AFNetworking.h" #import "UIButton+AFNetworking.h" #import "UIImage+AFNetworking.h" #import "UIImageView+AFNetworking.h" #import "UIKit+AFNetworking.h" #import "UIProgressView+AFNetworking.h" #import "UIRefreshControl+AFNetworking.h" #import "UIWebView+AFNetworking.h" FOUNDATION_EXPORT double AFNetworkingVersionNumber; FOUNDATION_EXPORT const unsigned char AFNetworkingVersionString[]; ================================================ FILE: Pods/Target Support Files/AFNetworking/AFNetworking.modulemap ================================================ framework module AFNetworking { umbrella header "AFNetworking-umbrella.h" export * module * { export * } } ================================================ FILE: Pods/Target Support Files/AFNetworking/AFNetworking.xcconfig ================================================ CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/AFNetworking GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" "${PODS_ROOT}/Headers/Public/FirebaseAuth" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/FirebaseStorage" "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" "${PODS_ROOT}/Headers/Public/GoogleUtilities" OTHER_LDFLAGS = -framework "CoreGraphics" -framework "MobileCoreServices" -framework "Security" -framework "SystemConfiguration" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES ================================================ FILE: Pods/Target Support Files/AFNetworking/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 3.1.0 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: Pods/Target Support Files/Bolts/Bolts-dummy.m ================================================ #import @interface PodsDummy_Bolts : NSObject @end @implementation PodsDummy_Bolts @end ================================================ FILE: Pods/Target Support Files/Bolts/Bolts-prefix.pch ================================================ #ifdef __OBJC__ #import #endif ================================================ FILE: Pods/Target Support Files/Bolts/Bolts-umbrella.h ================================================ #import #import "BFAppLink.h" #import "BFAppLinkNavigation.h" #import "BFAppLinkResolving.h" #import "BFAppLinkReturnToRefererController.h" #import "BFAppLinkReturnToRefererView.h" #import "BFAppLinkTarget.h" #import "BFMeasurementEvent.h" #import "BFURL.h" #import "BFWebViewAppLinkResolver.h" #import "BFCancellationToken.h" #import "BFCancellationTokenRegistration.h" #import "BFCancellationTokenSource.h" #import "BFExecutor.h" #import "BFTask+Exceptions.h" #import "BFTask.h" #import "BFTaskCompletionSource.h" #import "Bolts.h" FOUNDATION_EXPORT double BoltsVersionNumber; FOUNDATION_EXPORT const unsigned char BoltsVersionString[]; ================================================ FILE: Pods/Target Support Files/Bolts/Bolts.modulemap ================================================ framework module Bolts { umbrella header "Bolts-umbrella.h" export * module * { export * } } ================================================ FILE: Pods/Target Support Files/Bolts/Bolts.xcconfig ================================================ CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Bolts GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" "${PODS_ROOT}/Headers/Public/FirebaseAuth" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/FirebaseStorage" "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" "${PODS_ROOT}/Headers/Public/GoogleUtilities" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES ================================================ FILE: Pods/Target Support Files/Bolts/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 1.8.4 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: Pods/Target Support Files/FBSDKCoreKit/FBSDKCoreKit-dummy.m ================================================ #import @interface PodsDummy_FBSDKCoreKit : NSObject @end @implementation PodsDummy_FBSDKCoreKit @end ================================================ FILE: Pods/Target Support Files/FBSDKCoreKit/FBSDKCoreKit-prefix.pch ================================================ #ifdef __OBJC__ #import #endif ================================================ FILE: Pods/Target Support Files/FBSDKCoreKit/FBSDKCoreKit-umbrella.h ================================================ #import #import "FBSDKAccessToken.h" #import "FBSDKAppEvents.h" #import "FBSDKApplicationDelegate.h" #import "FBSDKAppLinkResolver.h" #import "FBSDKAppLinkUtility.h" #import "FBSDKButton.h" #import "FBSDKConstants.h" #import "FBSDKCopying.h" #import "FBSDKCoreKit.h" #import "FBSDKGraphErrorRecoveryProcessor.h" #import "FBSDKGraphRequest.h" #import "FBSDKGraphRequestConnection.h" #import "FBSDKGraphRequestDataAttachment.h" #import "FBSDKMacros.h" #import "FBSDKMutableCopying.h" #import "FBSDKProfile.h" #import "FBSDKProfilePictureView.h" #import "FBSDKSettings.h" #import "FBSDKTestUsersManager.h" #import "FBSDKUtility.h" FOUNDATION_EXPORT double FBSDKCoreKitVersionNumber; FOUNDATION_EXPORT const unsigned char FBSDKCoreKitVersionString[]; ================================================ FILE: Pods/Target Support Files/FBSDKCoreKit/FBSDKCoreKit.modulemap ================================================ framework module FBSDKCoreKit { umbrella header "FBSDKCoreKit-umbrella.h" export * module * { export * } } ================================================ FILE: Pods/Target Support Files/FBSDKCoreKit/FBSDKCoreKit.xcconfig ================================================ CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/FBSDKCoreKit FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Bolts" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" "${PODS_ROOT}/Headers/Public/FirebaseAuth" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/FirebaseStorage" "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" "${PODS_ROOT}/Headers/Public/GoogleUtilities" OTHER_LDFLAGS = -weak_framework "Accounts" -weak_framework "AudioToolbox" -weak_framework "CoreGraphics" -weak_framework "CoreLocation" -weak_framework "Foundation" -weak_framework "QuartzCore" -weak_framework "Security" -weak_framework "Social" -weak_framework "UIKit" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES ================================================ FILE: Pods/Target Support Files/FBSDKCoreKit/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 4.16.0 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: Pods/Target Support Files/FBSDKLoginKit/FBSDKLoginKit-dummy.m ================================================ #import @interface PodsDummy_FBSDKLoginKit : NSObject @end @implementation PodsDummy_FBSDKLoginKit @end ================================================ FILE: Pods/Target Support Files/FBSDKLoginKit/FBSDKLoginKit-prefix.pch ================================================ #ifdef __OBJC__ #import #endif ================================================ FILE: Pods/Target Support Files/FBSDKLoginKit/FBSDKLoginKit-umbrella.h ================================================ #import #import "FBSDKLoginButton.h" #import "FBSDKLoginConstants.h" #import "FBSDKLoginKit.h" #import "FBSDKLoginManager.h" #import "FBSDKLoginManagerLoginResult.h" #import "FBSDKLoginTooltipView.h" #import "FBSDKTooltipView.h" FOUNDATION_EXPORT double FBSDKLoginKitVersionNumber; FOUNDATION_EXPORT const unsigned char FBSDKLoginKitVersionString[]; ================================================ FILE: Pods/Target Support Files/FBSDKLoginKit/FBSDKLoginKit.modulemap ================================================ framework module FBSDKLoginKit { umbrella header "FBSDKLoginKit-umbrella.h" export * module * { export * } } ================================================ FILE: Pods/Target Support Files/FBSDKLoginKit/FBSDKLoginKit.xcconfig ================================================ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/FBSDKLoginKit FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Bolts" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKCoreKit" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" "${PODS_ROOT}/Headers/Public/FirebaseAuth" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/FirebaseStorage" "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" "${PODS_ROOT}/Headers/Public/GoogleUtilities" OTHER_LDFLAGS = -weak_framework "Accounts" -weak_framework "AudioToolbox" -weak_framework "CoreGraphics" -weak_framework "CoreLocation" -weak_framework "Foundation" -weak_framework "QuartzCore" -weak_framework "Security" -weak_framework "Social" -weak_framework "UIKit" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES ================================================ FILE: Pods/Target Support Files/FBSDKLoginKit/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 4.16.1 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: Pods/Target Support Files/FBSDKShareKit/FBSDKShareKit-dummy.m ================================================ #import @interface PodsDummy_FBSDKShareKit : NSObject @end @implementation PodsDummy_FBSDKShareKit @end ================================================ FILE: Pods/Target Support Files/FBSDKShareKit/FBSDKShareKit-prefix.pch ================================================ #ifdef __OBJC__ #import #endif ================================================ FILE: Pods/Target Support Files/FBSDKShareKit/FBSDKShareKit-umbrella.h ================================================ #import #import "FBSDKAppGroupAddDialog.h" #import "FBSDKAppGroupContent.h" #import "FBSDKAppGroupJoinDialog.h" #import "FBSDKAppInviteContent.h" #import "FBSDKAppInviteDialog.h" #import "FBSDKGameRequestContent.h" #import "FBSDKGameRequestDialog.h" #import "FBSDKHashtag.h" #import "FBSDKLikeButton.h" #import "FBSDKLikeControl.h" #import "FBSDKLikeObjectType.h" #import "FBSDKLiking.h" #import "FBSDKMessageDialog.h" #import "FBSDKSendButton.h" #import "FBSDKShareAPI.h" #import "FBSDKShareButton.h" #import "FBSDKShareConstants.h" #import "FBSDKShareDialog.h" #import "FBSDKShareDialogMode.h" #import "FBSDKShareKit.h" #import "FBSDKShareLinkContent.h" #import "FBSDKShareMediaContent.h" #import "FBSDKShareOpenGraphAction.h" #import "FBSDKShareOpenGraphContent.h" #import "FBSDKShareOpenGraphObject.h" #import "FBSDKShareOpenGraphValueContainer.h" #import "FBSDKSharePhoto.h" #import "FBSDKSharePhotoContent.h" #import "FBSDKShareVideo.h" #import "FBSDKShareVideoContent.h" #import "FBSDKSharing.h" #import "FBSDKSharingButton.h" #import "FBSDKSharingContent.h" FOUNDATION_EXPORT double FBSDKShareKitVersionNumber; FOUNDATION_EXPORT const unsigned char FBSDKShareKitVersionString[]; ================================================ FILE: Pods/Target Support Files/FBSDKShareKit/FBSDKShareKit.modulemap ================================================ framework module FBSDKShareKit { umbrella header "FBSDKShareKit-umbrella.h" export * module * { export * } } ================================================ FILE: Pods/Target Support Files/FBSDKShareKit/FBSDKShareKit.xcconfig ================================================ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/FBSDKShareKit FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Bolts" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKCoreKit" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" "${PODS_ROOT}/Headers/Public/FirebaseAuth" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/FirebaseStorage" "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" "${PODS_ROOT}/Headers/Public/GoogleUtilities" OTHER_LDFLAGS = -weak_framework "Accounts" -weak_framework "AudioToolbox" -weak_framework "CoreGraphics" -weak_framework "CoreLocation" -weak_framework "Foundation" -weak_framework "QuartzCore" -weak_framework "Security" -weak_framework "Social" -weak_framework "UIKit" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES ================================================ FILE: Pods/Target Support Files/FBSDKShareKit/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 4.16.1 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: Pods/Target Support Files/MBProgressHUD/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 1.0.0 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: Pods/Target Support Files/MBProgressHUD/MBProgressHUD-dummy.m ================================================ #import @interface PodsDummy_MBProgressHUD : NSObject @end @implementation PodsDummy_MBProgressHUD @end ================================================ FILE: Pods/Target Support Files/MBProgressHUD/MBProgressHUD-prefix.pch ================================================ #ifdef __OBJC__ #import #endif ================================================ FILE: Pods/Target Support Files/MBProgressHUD/MBProgressHUD-umbrella.h ================================================ #import #import "MBProgressHUD.h" FOUNDATION_EXPORT double MBProgressHUDVersionNumber; FOUNDATION_EXPORT const unsigned char MBProgressHUDVersionString[]; ================================================ FILE: Pods/Target Support Files/MBProgressHUD/MBProgressHUD.modulemap ================================================ framework module MBProgressHUD { umbrella header "MBProgressHUD-umbrella.h" export * module * { export * } } ================================================ FILE: Pods/Target Support Files/MBProgressHUD/MBProgressHUD.xcconfig ================================================ CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/MBProgressHUD GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" "${PODS_ROOT}/Headers/Public/FirebaseAuth" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/FirebaseStorage" "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" "${PODS_ROOT}/Headers/Public/GoogleUtilities" OTHER_LDFLAGS = -framework "CoreGraphics" -framework "QuartzCore" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES ================================================ FILE: Pods/Target Support Files/Pods-PotterPics/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 1.0.0 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: Pods/Target Support Files/Pods-PotterPics/Pods-PotterPics-acknowledgements.markdown ================================================ # Acknowledgements This application makes use of the following third party libraries: ## AFNetworking Copyright (c) 2011–2016 Alamofire Software Foundation (http://alamofire.org/) 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. ## Bolts BSD License For Bolts software Copyright (c) 2013-present, Facebook, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name Facebook nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ## FBSDKCoreKit Copyright (c) 2014-present, Facebook, Inc. All rights reserved. You are hereby granted a non-exclusive, worldwide, royalty-free license to use, copy, modify, and distribute this software in source code or binary form for use in connection with the web services and APIs provided by Facebook. As with any software that integrates with the Facebook platform, your use of this software is subject to the Facebook Developer Principles and Policies [http://developers.facebook.com/policy/]. This copyright 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. ## FBSDKLoginKit Copyright (c) 2014-present, Facebook, Inc. All rights reserved. You are hereby granted a non-exclusive, worldwide, royalty-free license to use, copy, modify, and distribute this software in source code or binary form for use in connection with the web services and APIs provided by Facebook. As with any software that integrates with the Facebook platform, your use of this software is subject to the Facebook Developer Principles and Policies [http://developers.facebook.com/policy/]. This copyright 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. ## FBSDKShareKit Copyright (c) 2014-present, Facebook, Inc. All rights reserved. You are hereby granted a non-exclusive, worldwide, royalty-free license to use, copy, modify, and distribute this software in source code or binary form for use in connection with the web services and APIs provided by Facebook. As with any software that integrates with the Facebook platform, your use of this software is subject to the Facebook Developer Principles and Policies [http://developers.facebook.com/policy/]. This copyright 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. ## Firebase Copyright 2016 Google ## FirebaseAnalytics Copyright 2016 Google ## FirebaseAuth Copyright 2016 Google ## FirebaseCore Copyright 2016 Google ## FirebaseDatabase Copyright 2016 Google ## FirebaseInstanceID Copyright 2016 Google ## FirebaseStorage Copyright 2016 Google ## GoogleInterchangeUtilities Copyright 2016 Google ## GoogleNetworkingUtilities Copyright 2016 Google ## GoogleSymbolUtilities Copyright 2016 Google ## GoogleUtilities Copyright 2016 Google ## MBProgressHUD Copyright © 2009-2016 Matej Bukovinski 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. ## SwiftyJSON The MIT License (MIT) Copyright (c) 2016 Ruoyu Fu 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. Generated by CocoaPods - https://cocoapods.org ================================================ FILE: Pods/Target Support Files/Pods-PotterPics/Pods-PotterPics-acknowledgements.plist ================================================ PreferenceSpecifiers FooterText This application makes use of the following third party libraries: Title Acknowledgements Type PSGroupSpecifier FooterText Copyright (c) 2011–2016 Alamofire Software Foundation (http://alamofire.org/) 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. License MIT Title AFNetworking Type PSGroupSpecifier FooterText BSD License For Bolts software Copyright (c) 2013-present, Facebook, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name Facebook nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. License BSD Title Bolts Type PSGroupSpecifier FooterText Copyright (c) 2014-present, Facebook, Inc. All rights reserved. You are hereby granted a non-exclusive, worldwide, royalty-free license to use, copy, modify, and distribute this software in source code or binary form for use in connection with the web services and APIs provided by Facebook. As with any software that integrates with the Facebook platform, your use of this software is subject to the Facebook Developer Principles and Policies [http://developers.facebook.com/policy/]. This copyright 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. License Facebook Platform License Title FBSDKCoreKit Type PSGroupSpecifier FooterText Copyright (c) 2014-present, Facebook, Inc. All rights reserved. You are hereby granted a non-exclusive, worldwide, royalty-free license to use, copy, modify, and distribute this software in source code or binary form for use in connection with the web services and APIs provided by Facebook. As with any software that integrates with the Facebook platform, your use of this software is subject to the Facebook Developer Principles and Policies [http://developers.facebook.com/policy/]. This copyright 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. License Facebook Platform License Title FBSDKLoginKit Type PSGroupSpecifier FooterText Copyright (c) 2014-present, Facebook, Inc. All rights reserved. You are hereby granted a non-exclusive, worldwide, royalty-free license to use, copy, modify, and distribute this software in source code or binary form for use in connection with the web services and APIs provided by Facebook. As with any software that integrates with the Facebook platform, your use of this software is subject to the Facebook Developer Principles and Policies [http://developers.facebook.com/policy/]. This copyright 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. License Facebook Platform License Title FBSDKShareKit Type PSGroupSpecifier FooterText Copyright 2016 Google License Copyright Title Firebase Type PSGroupSpecifier FooterText Copyright 2016 Google License Copyright Title FirebaseAnalytics Type PSGroupSpecifier FooterText Copyright 2016 Google License Copyright Title FirebaseAuth Type PSGroupSpecifier FooterText Copyright 2016 Google License Copyright Title FirebaseCore Type PSGroupSpecifier FooterText Copyright 2016 Google License Copyright Title FirebaseDatabase Type PSGroupSpecifier FooterText Copyright 2016 Google License Copyright Title FirebaseInstanceID Type PSGroupSpecifier FooterText Copyright 2016 Google License Copyright Title FirebaseStorage Type PSGroupSpecifier FooterText Copyright 2016 Google License Copyright Title GoogleInterchangeUtilities Type PSGroupSpecifier FooterText Copyright 2016 Google License Copyright Title GoogleNetworkingUtilities Type PSGroupSpecifier FooterText Copyright 2016 Google License Copyright Title GoogleSymbolUtilities Type PSGroupSpecifier FooterText Copyright 2016 Google License Copyright Title GoogleUtilities Type PSGroupSpecifier FooterText Copyright © 2009-2016 Matej Bukovinski 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. License MIT Title MBProgressHUD Type PSGroupSpecifier FooterText The MIT License (MIT) Copyright (c) 2016 Ruoyu Fu 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. License MIT Title SwiftyJSON Type PSGroupSpecifier FooterText Generated by CocoaPods - https://cocoapods.org Title Type PSGroupSpecifier StringsTable Acknowledgements Title Acknowledgements ================================================ FILE: Pods/Target Support Files/Pods-PotterPics/Pods-PotterPics-dummy.m ================================================ #import @interface PodsDummy_Pods_PotterPics : NSObject @end @implementation PodsDummy_Pods_PotterPics @end ================================================ FILE: Pods/Target Support Files/Pods-PotterPics/Pods-PotterPics-frameworks.sh ================================================ #!/bin/sh set -e echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" install_framework() { if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then local source="${BUILT_PRODUCTS_DIR}/$1" elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" elif [ -r "$1" ]; then local source="$1" fi local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" if [ -L "${source}" ]; then echo "Symlinked..." source="$(readlink "${source}")" fi # use filter instead of exclude so missing patterns dont' throw errors echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" local basename basename="$(basename -s .framework "$1")" binary="${destination}/${basename}.framework/${basename}" if ! [ -r "$binary" ]; then binary="${destination}/${basename}" fi # Strip invalid architectures so "fat" simulator / device frameworks work on device if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then strip_invalid_archs "$binary" fi # Resign the code if required by the build settings to avoid unstable apps code_sign_if_enabled "${destination}/$(basename "$1")" # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then local swift_runtime_libs swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) for lib in $swift_runtime_libs; do echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" code_sign_if_enabled "${destination}/${lib}" done fi } # Signs a framework with the provided identity code_sign_if_enabled() { if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then # Use the current code_sign_identitiy echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" fi } # Strip invalid architectures strip_invalid_archs() { binary="$1" # Get architectures for current file archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" stripped="" for arch in $archs; do if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then # Strip non-valid architectures in-place lipo -remove "$arch" -output "$binary" "$binary" || exit 1 stripped="$stripped $arch" fi done if [[ "$stripped" ]]; then echo "Stripped $binary of architectures:$stripped" fi } if [[ "$CONFIGURATION" == "Debug" ]]; then install_framework "$BUILT_PRODUCTS_DIR/AFNetworking/AFNetworking.framework" install_framework "$BUILT_PRODUCTS_DIR/Bolts/Bolts.framework" install_framework "$BUILT_PRODUCTS_DIR/FBSDKCoreKit/FBSDKCoreKit.framework" install_framework "$BUILT_PRODUCTS_DIR/FBSDKLoginKit/FBSDKLoginKit.framework" install_framework "$BUILT_PRODUCTS_DIR/FBSDKShareKit/FBSDKShareKit.framework" install_framework "$BUILT_PRODUCTS_DIR/MBProgressHUD/MBProgressHUD.framework" install_framework "$BUILT_PRODUCTS_DIR/SwiftyJSON/SwiftyJSON.framework" fi if [[ "$CONFIGURATION" == "Release" ]]; then install_framework "$BUILT_PRODUCTS_DIR/AFNetworking/AFNetworking.framework" install_framework "$BUILT_PRODUCTS_DIR/Bolts/Bolts.framework" install_framework "$BUILT_PRODUCTS_DIR/FBSDKCoreKit/FBSDKCoreKit.framework" install_framework "$BUILT_PRODUCTS_DIR/FBSDKLoginKit/FBSDKLoginKit.framework" install_framework "$BUILT_PRODUCTS_DIR/FBSDKShareKit/FBSDKShareKit.framework" install_framework "$BUILT_PRODUCTS_DIR/MBProgressHUD/MBProgressHUD.framework" install_framework "$BUILT_PRODUCTS_DIR/SwiftyJSON/SwiftyJSON.framework" fi ================================================ FILE: Pods/Target Support Files/Pods-PotterPics/Pods-PotterPics-resources.sh ================================================ #!/bin/sh set -e mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt > "$RESOURCES_TO_COPY" XCASSET_FILES=() case "${TARGETED_DEVICE_FAMILY}" in 1,2) TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" ;; 1) TARGET_DEVICE_ARGS="--target-device iphone" ;; 2) TARGET_DEVICE_ARGS="--target-device ipad" ;; *) TARGET_DEVICE_ARGS="--target-device mac" ;; esac realpath() { DIRECTORY="$(cd "${1%/*}" && pwd)" FILENAME="${1##*/}" echo "$DIRECTORY/$FILENAME" } install_resource() { if [[ "$1" = /* ]] ; then RESOURCE_PATH="$1" else RESOURCE_PATH="${PODS_ROOT}/$1" fi if [[ ! -e "$RESOURCE_PATH" ]] ; then cat << EOM error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. EOM exit 1 fi case $RESOURCE_PATH in *.storyboard) echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} ;; *.xib) echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} ;; *.framework) echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" ;; *.xcdatamodel) echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" ;; *.xcdatamodeld) echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" ;; *.xcmappingmodel) echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" ;; *.xcassets) ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") ;; *) echo "$RESOURCE_PATH" echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" ;; esac } mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" fi rm -f "$RESOURCES_TO_COPY" if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] then # Find all other xcassets (this unfortunately includes those of path pods and other targets). OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) while read line; do if [[ $line != "`realpath $PODS_ROOT`*" ]]; then XCASSET_FILES+=("$line") fi done <<<"$OTHER_XCASSETS" printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" fi ================================================ FILE: Pods/Target Support Files/Pods-PotterPics/Pods-PotterPics-umbrella.h ================================================ #import FOUNDATION_EXPORT double Pods_PotterPicsVersionNumber; FOUNDATION_EXPORT const unsigned char Pods_PotterPicsVersionString[]; ================================================ FILE: Pods/Target Support Files/Pods-PotterPics/Pods-PotterPics.debug.xcconfig ================================================ EMBEDDED_CONTENT_CONTAINS_SWIFT = YES FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/AFNetworking" "$PODS_CONFIGURATION_BUILD_DIR/Bolts" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKCoreKit" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKLoginKit" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKShareKit" "$PODS_CONFIGURATION_BUILD_DIR/MBProgressHUD" "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON" "${PODS_ROOT}/FirebaseAnalytics/Frameworks/frameworks" "${PODS_ROOT}/FirebaseAuth/Frameworks/frameworks" "${PODS_ROOT}/FirebaseCore/Frameworks/frameworks" "${PODS_ROOT}/FirebaseDatabase/Frameworks" "${PODS_ROOT}/FirebaseInstanceID/Frameworks/frameworks" "${PODS_ROOT}/FirebaseStorage/Frameworks/frameworks" "${PODS_ROOT}/GoogleInterchangeUtilities/Frameworks/frameworks" "${PODS_ROOT}/GoogleNetworkingUtilities/Frameworks/frameworks" "${PODS_ROOT}/GoogleSymbolUtilities/Frameworks/frameworks" "${PODS_ROOT}/GoogleUtilities/Frameworks/frameworks" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) ${PODS_ROOT}/Firebase/Core/Sources $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" "${PODS_ROOT}/Headers/Public/FirebaseAuth" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/FirebaseStorage" "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" "${PODS_ROOT}/Headers/Public/GoogleUtilities" LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/AFNetworking/AFNetworking.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Bolts/Bolts.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKCoreKit/FBSDKCoreKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKLoginKit/FBSDKLoginKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKShareKit/FBSDKShareKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/MBProgressHUD/MBProgressHUD.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON/SwiftyJSON.framework/Headers" -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/Firebase" -isystem "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" -isystem "${PODS_ROOT}/Headers/Public/FirebaseAuth" -isystem "${PODS_ROOT}/Headers/Public/FirebaseCore" -isystem "${PODS_ROOT}/Headers/Public/FirebaseDatabase" -isystem "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" -isystem "${PODS_ROOT}/Headers/Public/FirebaseStorage" -isystem "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleUtilities" OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"icucore" -l"sqlite3" -l"z" -framework "AFNetworking" -framework "AddressBook" -framework "Bolts" -framework "CFNetwork" -framework "CoreGraphics" -framework "FBSDKCoreKit" -framework "FBSDKLoginKit" -framework "FBSDKShareKit" -framework "FirebaseAnalytics" -framework "FirebaseAuth" -framework "FirebaseCore" -framework "FirebaseDatabase" -framework "FirebaseInstanceID" -framework "FirebaseStorage" -framework "GoogleInterchangeUtilities" -framework "GoogleNetworkingUtilities" -framework "GoogleSymbolUtilities" -framework "GoogleUtilities" -framework "MBProgressHUD" -framework "MobileCoreServices" -framework "Security" -framework "StoreKit" -framework "SwiftyJSON" -framework "SystemConfiguration" OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT}/Pods ================================================ FILE: Pods/Target Support Files/Pods-PotterPics/Pods-PotterPics.modulemap ================================================ framework module Pods_PotterPics { umbrella header "Pods-PotterPics-umbrella.h" export * module * { export * } } ================================================ FILE: Pods/Target Support Files/Pods-PotterPics/Pods-PotterPics.release.xcconfig ================================================ EMBEDDED_CONTENT_CONTAINS_SWIFT = YES FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/AFNetworking" "$PODS_CONFIGURATION_BUILD_DIR/Bolts" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKCoreKit" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKLoginKit" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKShareKit" "$PODS_CONFIGURATION_BUILD_DIR/MBProgressHUD" "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON" "${PODS_ROOT}/FirebaseAnalytics/Frameworks/frameworks" "${PODS_ROOT}/FirebaseAuth/Frameworks/frameworks" "${PODS_ROOT}/FirebaseCore/Frameworks/frameworks" "${PODS_ROOT}/FirebaseDatabase/Frameworks" "${PODS_ROOT}/FirebaseInstanceID/Frameworks/frameworks" "${PODS_ROOT}/FirebaseStorage/Frameworks/frameworks" "${PODS_ROOT}/GoogleInterchangeUtilities/Frameworks/frameworks" "${PODS_ROOT}/GoogleNetworkingUtilities/Frameworks/frameworks" "${PODS_ROOT}/GoogleSymbolUtilities/Frameworks/frameworks" "${PODS_ROOT}/GoogleUtilities/Frameworks/frameworks" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) ${PODS_ROOT}/Firebase/Core/Sources $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" "${PODS_ROOT}/Headers/Public/FirebaseAuth" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/FirebaseStorage" "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" "${PODS_ROOT}/Headers/Public/GoogleUtilities" LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/AFNetworking/AFNetworking.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Bolts/Bolts.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKCoreKit/FBSDKCoreKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKLoginKit/FBSDKLoginKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKShareKit/FBSDKShareKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/MBProgressHUD/MBProgressHUD.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON/SwiftyJSON.framework/Headers" -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/Firebase" -isystem "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" -isystem "${PODS_ROOT}/Headers/Public/FirebaseAuth" -isystem "${PODS_ROOT}/Headers/Public/FirebaseCore" -isystem "${PODS_ROOT}/Headers/Public/FirebaseDatabase" -isystem "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" -isystem "${PODS_ROOT}/Headers/Public/FirebaseStorage" -isystem "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleUtilities" OTHER_LDFLAGS = $(inherited) -ObjC -l"c++" -l"icucore" -l"sqlite3" -l"z" -framework "AFNetworking" -framework "AddressBook" -framework "Bolts" -framework "CFNetwork" -framework "CoreGraphics" -framework "FBSDKCoreKit" -framework "FBSDKLoginKit" -framework "FBSDKShareKit" -framework "FirebaseAnalytics" -framework "FirebaseAuth" -framework "FirebaseCore" -framework "FirebaseDatabase" -framework "FirebaseInstanceID" -framework "FirebaseStorage" -framework "GoogleInterchangeUtilities" -framework "GoogleNetworkingUtilities" -framework "GoogleSymbolUtilities" -framework "GoogleUtilities" -framework "MBProgressHUD" -framework "MobileCoreServices" -framework "Security" -framework "StoreKit" -framework "SwiftyJSON" -framework "SystemConfiguration" OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT}/Pods ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsTests/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 1.0.0 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsTests/Pods-PotterPicsTests-acknowledgements.markdown ================================================ # Acknowledgements This application makes use of the following third party libraries: Generated by CocoaPods - https://cocoapods.org ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsTests/Pods-PotterPicsTests-acknowledgements.plist ================================================ PreferenceSpecifiers FooterText This application makes use of the following third party libraries: Title Acknowledgements Type PSGroupSpecifier FooterText Generated by CocoaPods - https://cocoapods.org Title Type PSGroupSpecifier StringsTable Acknowledgements Title Acknowledgements ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsTests/Pods-PotterPicsTests-dummy.m ================================================ #import @interface PodsDummy_Pods_PotterPicsTests : NSObject @end @implementation PodsDummy_Pods_PotterPicsTests @end ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsTests/Pods-PotterPicsTests-frameworks.sh ================================================ #!/bin/sh set -e echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" install_framework() { if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then local source="${BUILT_PRODUCTS_DIR}/$1" elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" elif [ -r "$1" ]; then local source="$1" fi local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" if [ -L "${source}" ]; then echo "Symlinked..." source="$(readlink "${source}")" fi # use filter instead of exclude so missing patterns dont' throw errors echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" local basename basename="$(basename -s .framework "$1")" binary="${destination}/${basename}.framework/${basename}" if ! [ -r "$binary" ]; then binary="${destination}/${basename}" fi # Strip invalid architectures so "fat" simulator / device frameworks work on device if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then strip_invalid_archs "$binary" fi # Resign the code if required by the build settings to avoid unstable apps code_sign_if_enabled "${destination}/$(basename "$1")" # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then local swift_runtime_libs swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) for lib in $swift_runtime_libs; do echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" code_sign_if_enabled "${destination}/${lib}" done fi } # Signs a framework with the provided identity code_sign_if_enabled() { if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then # Use the current code_sign_identitiy echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" fi } # Strip invalid architectures strip_invalid_archs() { binary="$1" # Get architectures for current file archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" stripped="" for arch in $archs; do if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then # Strip non-valid architectures in-place lipo -remove "$arch" -output "$binary" "$binary" || exit 1 stripped="$stripped $arch" fi done if [[ "$stripped" ]]; then echo "Stripped $binary of architectures:$stripped" fi } ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsTests/Pods-PotterPicsTests-resources.sh ================================================ #!/bin/sh set -e mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt > "$RESOURCES_TO_COPY" XCASSET_FILES=() case "${TARGETED_DEVICE_FAMILY}" in 1,2) TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" ;; 1) TARGET_DEVICE_ARGS="--target-device iphone" ;; 2) TARGET_DEVICE_ARGS="--target-device ipad" ;; *) TARGET_DEVICE_ARGS="--target-device mac" ;; esac realpath() { DIRECTORY="$(cd "${1%/*}" && pwd)" FILENAME="${1##*/}" echo "$DIRECTORY/$FILENAME" } install_resource() { if [[ "$1" = /* ]] ; then RESOURCE_PATH="$1" else RESOURCE_PATH="${PODS_ROOT}/$1" fi if [[ ! -e "$RESOURCE_PATH" ]] ; then cat << EOM error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. EOM exit 1 fi case $RESOURCE_PATH in *.storyboard) echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} ;; *.xib) echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} ;; *.framework) echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" ;; *.xcdatamodel) echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" ;; *.xcdatamodeld) echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" ;; *.xcmappingmodel) echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" ;; *.xcassets) ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") ;; *) echo "$RESOURCE_PATH" echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" ;; esac } mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" fi rm -f "$RESOURCES_TO_COPY" if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] then # Find all other xcassets (this unfortunately includes those of path pods and other targets). OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) while read line; do if [[ $line != "`realpath $PODS_ROOT`*" ]]; then XCASSET_FILES+=("$line") fi done <<<"$OTHER_XCASSETS" printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" fi ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsTests/Pods-PotterPicsTests-umbrella.h ================================================ #import FOUNDATION_EXPORT double Pods_PotterPicsTestsVersionNumber; FOUNDATION_EXPORT const unsigned char Pods_PotterPicsTestsVersionString[]; ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsTests/Pods-PotterPicsTests.debug.xcconfig ================================================ FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/AFNetworking" "$PODS_CONFIGURATION_BUILD_DIR/Bolts" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKCoreKit" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKLoginKit" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKShareKit" "$PODS_CONFIGURATION_BUILD_DIR/MBProgressHUD" "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" "${PODS_ROOT}/Headers/Public/FirebaseAuth" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/FirebaseStorage" "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" "${PODS_ROOT}/Headers/Public/GoogleUtilities" LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/AFNetworking/AFNetworking.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Bolts/Bolts.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKCoreKit/FBSDKCoreKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKLoginKit/FBSDKLoginKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKShareKit/FBSDKShareKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/MBProgressHUD/MBProgressHUD.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON/SwiftyJSON.framework/Headers" -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/Firebase" -isystem "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" -isystem "${PODS_ROOT}/Headers/Public/FirebaseAuth" -isystem "${PODS_ROOT}/Headers/Public/FirebaseCore" -isystem "${PODS_ROOT}/Headers/Public/FirebaseDatabase" -isystem "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" -isystem "${PODS_ROOT}/Headers/Public/FirebaseStorage" -isystem "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleUtilities" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT}/Pods ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsTests/Pods-PotterPicsTests.modulemap ================================================ framework module Pods_PotterPicsTests { umbrella header "Pods-PotterPicsTests-umbrella.h" export * module * { export * } } ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsTests/Pods-PotterPicsTests.release.xcconfig ================================================ FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/AFNetworking" "$PODS_CONFIGURATION_BUILD_DIR/Bolts" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKCoreKit" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKLoginKit" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKShareKit" "$PODS_CONFIGURATION_BUILD_DIR/MBProgressHUD" "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" "${PODS_ROOT}/Headers/Public/FirebaseAuth" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/FirebaseStorage" "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" "${PODS_ROOT}/Headers/Public/GoogleUtilities" LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/AFNetworking/AFNetworking.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Bolts/Bolts.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKCoreKit/FBSDKCoreKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKLoginKit/FBSDKLoginKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKShareKit/FBSDKShareKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/MBProgressHUD/MBProgressHUD.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON/SwiftyJSON.framework/Headers" -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/Firebase" -isystem "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" -isystem "${PODS_ROOT}/Headers/Public/FirebaseAuth" -isystem "${PODS_ROOT}/Headers/Public/FirebaseCore" -isystem "${PODS_ROOT}/Headers/Public/FirebaseDatabase" -isystem "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" -isystem "${PODS_ROOT}/Headers/Public/FirebaseStorage" -isystem "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleUtilities" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT}/Pods ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsUITests/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 1.0.0 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsUITests/Pods-PotterPicsUITests-acknowledgements.markdown ================================================ # Acknowledgements This application makes use of the following third party libraries: Generated by CocoaPods - https://cocoapods.org ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsUITests/Pods-PotterPicsUITests-acknowledgements.plist ================================================ PreferenceSpecifiers FooterText This application makes use of the following third party libraries: Title Acknowledgements Type PSGroupSpecifier FooterText Generated by CocoaPods - https://cocoapods.org Title Type PSGroupSpecifier StringsTable Acknowledgements Title Acknowledgements ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsUITests/Pods-PotterPicsUITests-dummy.m ================================================ #import @interface PodsDummy_Pods_PotterPicsUITests : NSObject @end @implementation PodsDummy_Pods_PotterPicsUITests @end ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsUITests/Pods-PotterPicsUITests-frameworks.sh ================================================ #!/bin/sh set -e echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" install_framework() { if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then local source="${BUILT_PRODUCTS_DIR}/$1" elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" elif [ -r "$1" ]; then local source="$1" fi local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" if [ -L "${source}" ]; then echo "Symlinked..." source="$(readlink "${source}")" fi # use filter instead of exclude so missing patterns dont' throw errors echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" local basename basename="$(basename -s .framework "$1")" binary="${destination}/${basename}.framework/${basename}" if ! [ -r "$binary" ]; then binary="${destination}/${basename}" fi # Strip invalid architectures so "fat" simulator / device frameworks work on device if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then strip_invalid_archs "$binary" fi # Resign the code if required by the build settings to avoid unstable apps code_sign_if_enabled "${destination}/$(basename "$1")" # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then local swift_runtime_libs swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) for lib in $swift_runtime_libs; do echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" code_sign_if_enabled "${destination}/${lib}" done fi } # Signs a framework with the provided identity code_sign_if_enabled() { if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then # Use the current code_sign_identitiy echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" fi } # Strip invalid architectures strip_invalid_archs() { binary="$1" # Get architectures for current file archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" stripped="" for arch in $archs; do if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then # Strip non-valid architectures in-place lipo -remove "$arch" -output "$binary" "$binary" || exit 1 stripped="$stripped $arch" fi done if [[ "$stripped" ]]; then echo "Stripped $binary of architectures:$stripped" fi } ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsUITests/Pods-PotterPicsUITests-resources.sh ================================================ #!/bin/sh set -e mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt > "$RESOURCES_TO_COPY" XCASSET_FILES=() case "${TARGETED_DEVICE_FAMILY}" in 1,2) TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" ;; 1) TARGET_DEVICE_ARGS="--target-device iphone" ;; 2) TARGET_DEVICE_ARGS="--target-device ipad" ;; *) TARGET_DEVICE_ARGS="--target-device mac" ;; esac realpath() { DIRECTORY="$(cd "${1%/*}" && pwd)" FILENAME="${1##*/}" echo "$DIRECTORY/$FILENAME" } install_resource() { if [[ "$1" = /* ]] ; then RESOURCE_PATH="$1" else RESOURCE_PATH="${PODS_ROOT}/$1" fi if [[ ! -e "$RESOURCE_PATH" ]] ; then cat << EOM error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. EOM exit 1 fi case $RESOURCE_PATH in *.storyboard) echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} ;; *.xib) echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} ;; *.framework) echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" ;; *.xcdatamodel) echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" ;; *.xcdatamodeld) echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" ;; *.xcmappingmodel) echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" ;; *.xcassets) ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") ;; *) echo "$RESOURCE_PATH" echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" ;; esac } mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" fi rm -f "$RESOURCES_TO_COPY" if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] then # Find all other xcassets (this unfortunately includes those of path pods and other targets). OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) while read line; do if [[ $line != "`realpath $PODS_ROOT`*" ]]; then XCASSET_FILES+=("$line") fi done <<<"$OTHER_XCASSETS" printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" fi ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsUITests/Pods-PotterPicsUITests-umbrella.h ================================================ #import FOUNDATION_EXPORT double Pods_PotterPicsUITestsVersionNumber; FOUNDATION_EXPORT const unsigned char Pods_PotterPicsUITestsVersionString[]; ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsUITests/Pods-PotterPicsUITests.debug.xcconfig ================================================ FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/AFNetworking" "$PODS_CONFIGURATION_BUILD_DIR/Bolts" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKCoreKit" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKLoginKit" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKShareKit" "$PODS_CONFIGURATION_BUILD_DIR/MBProgressHUD" "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" "${PODS_ROOT}/Headers/Public/FirebaseAuth" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/FirebaseStorage" "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" "${PODS_ROOT}/Headers/Public/GoogleUtilities" LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/AFNetworking/AFNetworking.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Bolts/Bolts.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKCoreKit/FBSDKCoreKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKLoginKit/FBSDKLoginKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKShareKit/FBSDKShareKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/MBProgressHUD/MBProgressHUD.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON/SwiftyJSON.framework/Headers" -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/Firebase" -isystem "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" -isystem "${PODS_ROOT}/Headers/Public/FirebaseAuth" -isystem "${PODS_ROOT}/Headers/Public/FirebaseCore" -isystem "${PODS_ROOT}/Headers/Public/FirebaseDatabase" -isystem "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" -isystem "${PODS_ROOT}/Headers/Public/FirebaseStorage" -isystem "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleUtilities" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT}/Pods ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsUITests/Pods-PotterPicsUITests.modulemap ================================================ framework module Pods_PotterPicsUITests { umbrella header "Pods-PotterPicsUITests-umbrella.h" export * module * { export * } } ================================================ FILE: Pods/Target Support Files/Pods-PotterPicsUITests/Pods-PotterPicsUITests.release.xcconfig ================================================ FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/AFNetworking" "$PODS_CONFIGURATION_BUILD_DIR/Bolts" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKCoreKit" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKLoginKit" "$PODS_CONFIGURATION_BUILD_DIR/FBSDKShareKit" "$PODS_CONFIGURATION_BUILD_DIR/MBProgressHUD" "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" "${PODS_ROOT}/Headers/Public/FirebaseAuth" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/FirebaseStorage" "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" "${PODS_ROOT}/Headers/Public/GoogleUtilities" LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/AFNetworking/AFNetworking.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/Bolts/Bolts.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKCoreKit/FBSDKCoreKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKLoginKit/FBSDKLoginKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/FBSDKShareKit/FBSDKShareKit.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/MBProgressHUD/MBProgressHUD.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON/SwiftyJSON.framework/Headers" -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/Firebase" -isystem "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" -isystem "${PODS_ROOT}/Headers/Public/FirebaseAuth" -isystem "${PODS_ROOT}/Headers/Public/FirebaseCore" -isystem "${PODS_ROOT}/Headers/Public/FirebaseDatabase" -isystem "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" -isystem "${PODS_ROOT}/Headers/Public/FirebaseStorage" -isystem "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" -isystem "${PODS_ROOT}/Headers/Public/GoogleUtilities" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT}/Pods ================================================ FILE: Pods/Target Support Files/SwiftyJSON/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier ${PRODUCT_BUNDLE_IDENTIFIER} CFBundleInfoDictionaryVersion 6.0 CFBundleName ${PRODUCT_NAME} CFBundlePackageType FMWK CFBundleShortVersionString 3.1.1 CFBundleSignature ???? CFBundleVersion ${CURRENT_PROJECT_VERSION} NSPrincipalClass ================================================ FILE: Pods/Target Support Files/SwiftyJSON/SwiftyJSON-dummy.m ================================================ #import @interface PodsDummy_SwiftyJSON : NSObject @end @implementation PodsDummy_SwiftyJSON @end ================================================ FILE: Pods/Target Support Files/SwiftyJSON/SwiftyJSON-prefix.pch ================================================ #ifdef __OBJC__ #import #endif ================================================ FILE: Pods/Target Support Files/SwiftyJSON/SwiftyJSON-umbrella.h ================================================ #import FOUNDATION_EXPORT double SwiftyJSONVersionNumber; FOUNDATION_EXPORT const unsigned char SwiftyJSONVersionString[]; ================================================ FILE: Pods/Target Support Files/SwiftyJSON/SwiftyJSON.modulemap ================================================ framework module SwiftyJSON { umbrella header "SwiftyJSON-umbrella.h" export * module * { export * } } ================================================ FILE: Pods/Target Support Files/SwiftyJSON/SwiftyJSON.xcconfig ================================================ CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/SwiftyJSON GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Firebase" "${PODS_ROOT}/Headers/Public/FirebaseAnalytics" "${PODS_ROOT}/Headers/Public/FirebaseAuth" "${PODS_ROOT}/Headers/Public/FirebaseCore" "${PODS_ROOT}/Headers/Public/FirebaseDatabase" "${PODS_ROOT}/Headers/Public/FirebaseInstanceID" "${PODS_ROOT}/Headers/Public/FirebaseStorage" "${PODS_ROOT}/Headers/Public/GoogleInterchangeUtilities" "${PODS_ROOT}/Headers/Public/GoogleNetworkingUtilities" "${PODS_ROOT}/Headers/Public/GoogleSymbolUtilities" "${PODS_ROOT}/Headers/Public/GoogleUtilities" OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES SWIFT_VERSION = 3.0 ================================================ FILE: PotterPics/AppDelegate.swift ================================================ // // AppDelegate.swift // PotterPics // // Created by Suraya Shivji on 11/16/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit import Firebase import FBSDKCoreKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { FIRApp.configure() FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions) let launchedBefore = UserDefaults.standard.bool(forKey: "launchedBefore") self.window = UIWindow(frame: UIScreen.main.bounds) let storyboard = UIStoryboard(name: "Main", bundle: nil) var initialViewController = UIViewController() let defaults = UserDefaults.standard if launchedBefore { // app has been launched before, segue to login let houseValue = defaults.string(forKey: "userHouse") var navCol = UIColor() switch houseValue! { case "Gryffindor": navCol = Gryffindor.navigation break case "Slytherin": navCol = Slytherin.navigation break case "Hufflepuff": navCol = Hufflepuff.navigation break case "Ravenclaw": navCol = Ravenclaw.navigation break default: break } defaults.potter_setColor(color: navCol, forKey: "navCol") guard let initialViewController = storyboard.instantiateViewController(withIdentifier: "homeView") as? HomeViewController else { print("Could not cast VC to HomeViewController") return false } } else { // app has not been launched before, segue to house quiz to set defaults UserDefaults.standard.set(true, forKey: "launchedBefore") UserDefaults.standard.set(true, forKey: "pickHouse") let randomNum:UInt32 = arc4random_uniform(4) let houses = ["Slytherin", "Gryffindor", "Hufflepuff", "Ravenclaw"] let defaults = UserDefaults.standard let randomHouse = houses[Int(randomNum)] defaults.set(randomHouse, forKey: "userHouse") defaults.synchronize() var navCol = UIColor() switch randomHouse { case "Gryffindor": navCol = Gryffindor.navigation break case "Slytherin": navCol = Slytherin.navigation break case "Hufflepuff": navCol = Hufflepuff.navigation break case "Ravenclaw": navCol = Ravenclaw.navigation break default: break } defaults.potter_setColor(color: navCol, forKey: "navCol") initialViewController = storyboard.instantiateViewController(withIdentifier: "homeView") as! HomeViewController } self.window?.rootViewController = initialViewController self.window?.makeKeyAndVisible() return true } func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { let handled = FBSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String!, annotation: options[UIApplicationOpenURLOptionsKey.annotation]) return handled } } ================================================ FILE: PotterPics/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "iphone", "size" : "20x20", "scale" : "2x" }, { "idiom" : "iphone", "size" : "20x20", "scale" : "3x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "3x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "3x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "120.png", "scale" : "2x" }, { "size" : "60x60", "idiom" : "iphone", "filename" : "180.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/Contents.json ================================================ { "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/GfeedDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "GfeedDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/GpostDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "GpostDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/GprofileDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "GprofileDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/GsearchDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "GsearchDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/HfeedDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "HfeedDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/HpostDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "HpostDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/HprofileDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "HprofileDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/HsearchDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "HsearchDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/RfeedDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "RfeedDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/RpostDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "RpostDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/RprofileDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "RprofileDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/RsearchDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "RsearchDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/SfeedDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "SfeedDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/SpostDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "SpostDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/SprofileDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "SprofileDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/SsearchDark.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "SsearchDark@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/cancel.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "cancel.jpg", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/facebook.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "facebook.jpg", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/feed.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "feed@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/logout.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "logout.jpg", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/nav_more_icon.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "nav_more_icon@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/post.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "camera@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/profile.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "profile@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/Assets.xcassets/search.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "scale" : "1x" }, { "idiom" : "universal", "filename" : "search@2x.png", "scale" : "2x" }, { "idiom" : "universal", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: PotterPics/BackgroundVideo.swift ================================================ // // BackgroundVideo.swift // // Adapted From https://github.com/Guzlan/BackgroundVideoiOS import Foundation import AVKit import AVFoundation enum BackgroundVideoErrors: Error { case invalidVideo } class BackgroundVideo { // creating an instance of an AVPlayer for background video var backGroundPlayer : AVPlayer? var videoURL: URL? var viewController: UIViewController? var hasBeenUsed: Bool = false init (on viewController: UIViewController, withVideoURL URL: String) { self.viewController = viewController // parse the video string to split it into name and extension let videoNameAndExtension:[String]? = URL.characters.split{$0 == "."}.map(String.init) if videoNameAndExtension!.count == 2 { if let videoName = videoNameAndExtension?[0] , let videoExtension = videoNameAndExtension?[1] { if let url = Bundle.main.url(forResource: videoName, withExtension: videoExtension) { self.videoURL = url // initialize our player with our fetched video url self.backGroundPlayer = AVPlayer(url: self.videoURL!) } else { print(BackgroundVideoErrors.invalidVideo) } } } else { print("Wrong video name format") } } deinit{ if self.hasBeenUsed { NotificationCenter.default.removeObserver(self, name: .AVPlayerItemDidPlayToEndTime, object: nil) NotificationCenter.default.removeObserver(self, name: .UIApplicationWillEnterForeground, object: nil) } } /* setUpBackground called in viewDidLoad to load a local video to play as the background */ func setUpBackground() { self.backGroundPlayer?.actionAtItemEnd = .none // add the video to your view let loginView: UIView = self.viewController!.view // get our view controllers view let playerLayer = AVPlayerLayer(player: self.backGroundPlayer) playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill // preserve aspect ratio and resize to fill screen playerLayer.zPosition = -1 // set it's position behined anything in our view playerLayer.frame = loginView.frame // set our player frame to our view's frame loginView.layer.addSublayer(playerLayer) self.backGroundPlayer?.play() // start the video self.hasBeenUsed = true } // A function that will restarts the video for the purpose of looping @objc private func loopVideo() { self.backGroundPlayer?.seek(to: kCMTimeZero) self.backGroundPlayer?.play() } // play/pause video func pause() { self.backGroundPlayer?.pause() } func play() { self.backGroundPlayer?.play() } } ================================================ FILE: PotterPics/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: PotterPics/Base.lproj/Main.storyboard ================================================ Title Title ================================================ FILE: PotterPics/CameraViewController.swift ================================================ // // CameraViewController.swift // PotterPics // // Created by Suraya Shivji on 12/6/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit import AVFoundation protocol ModalViewControllerDelegate { func sendValue(value : UIImage) } class CameraViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource { var delegate: ModalViewControllerDelegate! @IBOutlet weak var collecFlow: UICollectionViewFlowLayout! @IBOutlet weak var filterCollectionView: UICollectionView! @IBOutlet weak var captureImageView: UIImageView! @IBOutlet weak var previewImgView: UIView! var photoTaken: Bool = false var imagePicker: UIImagePickerController! var session: AVCaptureSession? var unfilteredImage: UIImage? var stillImageOutput: AVCaptureStillImageOutput? var videoPreviewLayer: AVCaptureVideoPreviewLayer? var filters = ["Original", "CISepiaTone", "CIDotScreen", "CIGaussianBlur", "CIColorInvert", "CIPhotoEffectNoir"] override func viewDidLoad() { super.viewDidLoad() self.filterCollectionView.delegate = self self.filterCollectionView.dataSource = self self.filterCollectionView.showsHorizontalScrollIndicator = false self.filterCollectionView.backgroundColor = UIColor.black setupFlow() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.unfilteredImage = self.captureImageView.image // setup camera session = AVCaptureSession() session!.sessionPreset = AVCaptureSession.Preset.medium // select rear camera for input if let backCamera = AVCaptureDevice.default(for: AVMediaType.video) { var error: NSError? var input: AVCaptureDeviceInput! do { input = try AVCaptureDeviceInput(device: backCamera) } catch let error1 as NSError { error = error1 input = nil print(error!.localizedDescription) } if error == nil && session!.canAddInput(input) { session!.addInput(input) stillImageOutput = AVCaptureStillImageOutput() stillImageOutput?.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG] } if session!.canAddOutput(stillImageOutput!) { session!.addOutput(stillImageOutput!) videoPreviewLayer = AVCaptureVideoPreviewLayer(session: session!) videoPreviewLayer!.videoGravity = AVLayerVideoGravity.resizeAspectFill videoPreviewLayer!.connection?.videoOrientation = AVCaptureVideoOrientation.portrait previewImgView.layer.addSublayer(videoPreviewLayer!) session!.startRunning() } } } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) videoPreviewLayer!.frame = previewImgView.bounds } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func takePicture(_ sender: UIButton) { photoTaken = true if let videoConnection = stillImageOutput!.connection(with: AVMediaType.video) { stillImageOutput?.captureStillImageAsynchronously(from: videoConnection, completionHandler: { (sampleBuffer, error) in // process image data (sampleBuffer) to get the file for the image view if sampleBuffer != nil { let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer!) let dataProvider = CGDataProvider(data: imageData as! CFData) let cgImageRef = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent) let image = UIImage(cgImage: cgImageRef!, scale: 1.0, orientation: UIImageOrientation.right) // let image = UIImage(cgImage: cgImageRef!) self.unfilteredImage = image self.captureImageView.image = image } }) } } // MARK: Collection View Methods func setupFlow() { self.collecFlow.sectionInset = UIEdgeInsets.init(top: 0 , left: 0, bottom: 0, right: 0) self.collecFlow.itemSize = CGSize(width: 120, height: 120) self.collecFlow.minimumLineSpacing = 0 } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return filters.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "filtersCell", for: indexPath as IndexPath) as! FilterCollectionViewCell cell.backgroundColor = UIColor.black cell.filteredLbl.text = "" let placeholderImage = UIImage(named: "filterPlaceholder") let inputImage = CIImage(image: placeholderImage!); let filterName = filters[indexPath.row] cell.filteredImg.image = generateFilteredImage(name: filterName, image: inputImage!, placeholder: true) cell.filteredLbl.text = filterName return cell } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let cell = collectionView.cellForItem(at: indexPath as IndexPath) as! FilterCollectionViewCell if cell.filteredImg.image != nil { if let ciVersion = CIImage(image: unfilteredImage!) { let filteredImage = generateFilteredImage(name: filters[indexPath.row], image: ciVersion, placeholder: !photoTaken) self.captureImageView.image = filteredImage } } } func generateFilteredImage(name: String!, image: CIImage, placeholder: Bool) -> UIImage { if name == "Original" { return UIImage(ciImage: image) } var filteredImage = UIImage() let context:CIContext = CIContext(options:nil); let filter = CIFilter(name: name)! filter.setValue(image, forKey: "inputImage") let inputKeys = filter.inputKeys if inputKeys.contains(kCIInputIntensityKey) { filter.setValue(1.7, forKey: kCIInputIntensityKey) } if inputKeys.contains(kCIInputRadiusKey) { filter.setValue(10, forKey: kCIInputRadiusKey) } if inputKeys.contains(kCIInputScaleKey) { filter.setValue(0.9 * 10, forKey: kCIInputScaleKey) } if let cgimg = context.createCGImage(filter.outputImage!, from: filter.outputImage!.extent) { let processedImage = placeholder ? UIImage(cgImage: cgimg) : UIImage(cgImage: cgimg, scale: 1.0, orientation: UIImageOrientation.right) filteredImage = processedImage } return filteredImage } @IBAction func uploadPicture(_ sender: AnyObject) { delegate?.sendValue(value: self.captureImageView.image!) self.dismiss(animated: true, completion: nil) } } ================================================ FILE: PotterPics/ColorPalette.swift ================================================ // // ColorPalette.swift // UpsAndDowns // // Created by Suraya Shivji on 11/24/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit struct ColorPalette { static let white = UIColor.potter_rbg(r: 255, g: 255, b: 255) static let black = UIColor.potter_rbg(r: 0, g: 0, b: 0) } struct Gryffindor { static let red = UIColor.potter_rbg(r: 174, g: 0, b: 1) static let darkRed = UIColor.potter_rbg(r: 116, g: 0, b: 1) static let brightYellow = UIColor.potter_rbg(r: 238, g: 186, b: 48) static let darkYellow = UIColor.potter_rbg(r: 211, g: 166, b: 37) static let navigation = UIColor.potter_rbg(r: 116, g: 0, b: 1) } struct Hufflepuff { static let solidYellow = UIColor.potter_rbg(r: 236, g: 185, b: 57) static let lightYellow = UIColor.potter_rbg(r: 240, g: 199, b: 94) static let muskyBrown = UIColor.potter_rbg(r: 114, g: 98, b: 85) static let darkBrown = UIColor.potter_rbg(r: 55, g: 46, b: 41) static let navigation = UIColor.potter_rbg(r: 236, g: 185, b: 57) } struct Slytherin { static let darkGreen = UIColor.potter_rbg(r: 26, g: 71, b: 42) static let green = UIColor.potter_rbg(r: 42, g: 98, b: 61) static let darkGray = UIColor.potter_rbg(r: 93, g: 93, b: 93) static let lightGray = UIColor.potter_rbg(r: 170, g: 170, b: 170) static let navigation = UIColor.potter_rbg(r: 42, g: 98, b: 61) } struct Ravenclaw { static let darkBlue = UIColor.potter_rbg(r: 14, g: 26, b: 64) static let blue = UIColor.potter_rbg(r: 34, g: 47, b: 91) static let brown = UIColor.potter_rbg(r: 148, g: 107, b: 45) static let gray = UIColor.potter_rbg(r: 93, g: 93, b: 93) static let navigation = UIColor.potter_rbg(r: 14, g: 26, b: 64) } ================================================ FILE: PotterPics/Extensions.swift ================================================ // // Extensions.swift // PotterPics // // Created by Suraya Shivji on 11/24/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit // rgb to uicolor extension UIColor { class func potter_rbg(r: CGFloat, g: CGFloat, b: CGFloat) -> UIColor { let color = UIColor.init(red: r/255, green: g/255, blue: b/255, alpha: 1) return color } } // crop uiimage into a circle extension UIImage { var potter_circle: UIImage? { let square = CGSize(width: min(size.width, size.height), height: min(size.width, size.height)) let imageView = UIImageView(frame: CGRect(origin: .zero, size: square)) imageView.contentMode = .scaleAspectFill imageView.image = self imageView.layer.cornerRadius = square.width/2 imageView.layer.masksToBounds = true UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, false, scale) guard let context = UIGraphicsGetCurrentContext() else { return nil } imageView.layer.render(in: context) let result = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return result } } // hide keyboards in view controllers extension UIViewController { func hideKeyboardWhenTappedAround() { let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard)) view.addGestureRecognizer(tap) } @objc func dismissKeyboard() { view.endEditing(true) } } // store colors on user defaults extension UserDefaults { func potter_colorForKey(key: String) -> UIColor? { var color: UIColor? if let colorData = data(forKey: key) { color = NSKeyedUnarchiver.unarchiveObject(with: colorData) as? UIColor } return color } func potter_setColor(color: UIColor?, forKey key: String) { var colorData: NSData? if let color = color { colorData = NSKeyedArchiver.archivedData(withRootObject: color) as NSData? } set(colorData, forKey: key) } } ================================================ FILE: PotterPics/FilterCollectionViewCell.swift ================================================ // // FilterCollectionViewCell.swift // PotterPicsSwift // // Created by Suraya Shivji on 10/28/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit class FilterCollectionViewCell: UICollectionViewCell { @IBOutlet weak var filteredImg: UIImageView! { didSet { filteredImg.contentMode = UIViewContentMode.scaleAspectFit filteredImg.image = UIImage(named: "filterPlaceholder") } } @IBOutlet weak var filteredLbl: UILabel! } ================================================ FILE: PotterPics/GlobalVariables.swift ================================================ // // GlobalVariables.swift // PotterPics // // Created by Suraya Shivji on 11/27/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import Foundation import UIKit struct globalVariables { static let rect = CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 44) static let width = UIScreen.main.bounds.width static let height: CGFloat = 64 } ================================================ FILE: PotterPics/GoogleService-Info.plist ================================================ AD_UNIT_ID_FOR_BANNER_TEST ca-app-pub-3940256099942544/2934735716 AD_UNIT_ID_FOR_INTERSTITIAL_TEST ca-app-pub-3940256099942544/4411468910 CLIENT_ID 782492568888-eg9bccm257r168l857a445n7jd3shtvl.apps.googleusercontent.com REVERSED_CLIENT_ID com.googleusercontent.apps.782492568888-eg9bccm257r168l857a445n7jd3shtvl API_KEY AIzaSyBNZ2O7ox8a7TTmz6Svh6V4XoZejAq2js4 GCM_SENDER_ID 782492568888 PLIST_VERSION 1 BUNDLE_ID com.surayashivji.PotterPics PROJECT_ID potterpics-2bcbc STORAGE_BUCKET potterpics-2bcbc.appspot.com IS_ADS_ENABLED IS_ANALYTICS_ENABLED IS_APPINVITE_ENABLED IS_GCM_ENABLED IS_SIGNIN_ENABLED GOOGLE_APP_ID 1:782492568888:ios:e8372e1215f6f60b DATABASE_URL https://potterpics-2bcbc.firebaseio.com ================================================ FILE: PotterPics/HomeButton.swift ================================================ // // HomeButton.swift // PotterPicsSwift // // Created by Suraya Shivji on 10/24/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit class HomeButton: UIButton { override func awakeFromNib() { layer.borderColor = UIColor.white.cgColor layer.borderWidth = 1.0 layer.backgroundColor = UIColor.black.withAlphaComponent(0.55).cgColor } } ================================================ FILE: PotterPics/HomeViewController.swift ================================================ // // HomeViewController.swift // PotterPics // // Created by Suraya Shivji on 11/16/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit import Firebase import FBSDKLoginKit import FBSDKCoreKit class HomeViewController: UIViewController { var cloudsVideo: BackgroundVideo? let facebookPermissions = ["public_profile", "email", "user_friends"] override func viewDidLoad() { super.viewDidLoad() // set up background video self.cloudsVideo = BackgroundVideo(on: self, withVideoURL: "IntroMusic.mp4") self.cloudsVideo?.setUpBackground() } // login user via Facebook @IBAction func loginTapped(_ sender: HomeButton) { let loginManager: FBSDKLoginManager = FBSDKLoginManager() // check that the user isn't already logged in if FBSDKAccessToken.current() != nil { // user logged in, segue to navigation controller self.cloudsVideo?.pause() self.performSegue(withIdentifier: "mainNavSegue", sender: nil) } else { loginManager.logIn(withReadPermissions: self.facebookPermissions, from: self, handler: { (result, error) in if error != nil { loginManager.logOut() let message: String = "An error has occured. \(String(describing: error))" let alertView = UIAlertController(title: "Alert", message: message, preferredStyle: UIAlertControllerStyle.alert) alertView.addAction(UIAlertAction(title: "Ok ", style: UIAlertActionStyle.default, handler: nil)) self.present(alertView, animated: true, completion: nil) } else if (result?.isCancelled)! { // user cancelled login loginManager.logOut() } else { let accessToken = FBSDKAccessToken.current() guard let accessTokenString = accessToken?.tokenString else { return } let credential = FIRFacebookAuthProvider.credential(withAccessToken: accessTokenString) FIRAuth.auth()?.signIn(with: credential) { (user, error) in if (error != nil) { // handle error print(error ?? "Error") } else { let ref = FIRDatabase.database().reference(fromURL: "https://potterpics-2bcbc.firebaseio.com") // guard for user id guard let uid = user?.uid else { return } let usersReference = ref.child("users").child(uid) let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, email"]) graphRequest.start(completionHandler: { (connection, result, error) -> Void in if error != nil { // Process error print("Error: \(String(describing: error))") } else { guard let data: [String:AnyObject] = result as? [String:AnyObject] else { print("Can't pull data from JSON") return } guard let userName: String = data["name"] as? String else { print("Can't pull username from JSON") return } guard let userEmail: String = data["email"] as? String else { print("Can't pull email from JSON") return } guard let userID: String = data["id"] as? String else { print("Can't pull ID from JSON") return } let imgURLString = "http://graph.facebook.com/\(userID)/picture?type=large" as String let defaults = UserDefaults.standard let houseValue = defaults.string(forKey: "userHouse")! as String // initial # posts = 0 let values = ["name": userName, "email": userEmail, "facebookID": userID, "profPicString": imgURLString, "house": houseValue, "postCount": 4] as [String : Any] // update database with new user usersReference.updateChildValues(values, withCompletionBlock: { (err, ref) in // error in database save if err != nil { print(err ?? "Error saving user to database") return } }) } }) self.dismiss(animated: false, completion: nil) self.performSegue(withIdentifier: "mainNavSegue", sender: nil) } } } }) } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } } ================================================ FILE: PotterPics/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleURLTypes CFBundleURLSchemes fb1148095658614618 CFBundleVersion 1 FacebookAppID 1148095658614618 FacebookDisplayName PotterPics LSApplicationQueriesSchemes fbapi fb-messenger-api fbauth2 fbshareextension LSRequiresIPhoneOS NSAppTransportSecurity NSAllowsArbitraryLoads NSCameraUsageDescription Required to take a picture and post to PotterPics. NSPhotoLibraryUsageDescription Upload pictures to PotterPics UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities armv7 UISupportedInterfaceOrientations UIInterfaceOrientationPortrait ================================================ FILE: PotterPics/MainViewController.swift ================================================ // // MainViewcontroller.swift // PotterPics // // Created by Suraya Shivji on 11/27/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit class MainViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, TabBarDelegate { // MARK: Properties var navColor: UIColor! var views = [UIView]() let items = ["Feed", "Search", "Post", "Profile"] var viewsAreInitialized = false lazy var collectionView: UICollectionView = { let layout = UICollectionViewFlowLayout() layout.scrollDirection = .horizontal layout.minimumInteritemSpacing = 0 layout.minimumLineSpacing = 0 let cv: UICollectionView = UICollectionView.init(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: (self.view.bounds.height)), collectionViewLayout: layout) cv.delegate = self cv.dataSource = self cv.showsHorizontalScrollIndicator = false cv.backgroundColor = UIColor.blue cv.bounces = false cv.isPagingEnabled = true cv.isDirectionalLockEnabled = true return cv }() lazy var tabBar: TabBar = { let tab = TabBar.init(frame: CGRect.init(x: 0, y: 0, width: globalVariables.width, height: 64)) tab.delegate = self return tab }() let titleLabel: UILabel = { let title = UILabel.init(frame: CGRect.init(x: 30, y: 17, width: 200, height: 30)) title.font = UIFont(name: "Avenir-Medium", size: 25)! title.textColor = UIColor.white title.text = "" return title }() class func updateNav() { } // MARK: Methods func customization() { // Collection View Customization self.collectionView.contentInset = UIEdgeInsetsMake(44, 0, 0, 0) self.view.addSubview(self.collectionView) // Navigation Controller Customization // house background color let defaults = UserDefaults.standard let navigationColor = defaults.potter_colorForKey(key: "navCol") self.navigationController?.view.backgroundColor = navigationColor self.navigationController?.navigationItem.hidesBackButton = true self.navigationItem.hidesBackButton = true // Navigation Bar color and shadow self.navigationController?.navigationBar.barTintColor = navigationColor self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default) self.navigationController?.navigationBar.shadowImage = UIImage() // Title Label self.navigationController?.navigationBar.addSubview(self.titleLabel) // Tab Bar self.view.addSubview(self.tabBar) // View Controllers init for title in self.items { let storyBoard = self.storyboard! let vc = storyBoard.instantiateViewController(withIdentifier: title) self.addChildViewController(vc) vc.view.frame = CGRect.init(x: 0, y: 0, width: self.view.bounds.width, height: (self.view.bounds.height - 44)) vc.didMove(toParentViewController: self) self.views.append(vc.view) } self.viewsAreInitialized = true } // MARK: Delegates implementation func didSelectItem(atIndex: Int) { self.collectionView.scrollRectToVisible(CGRect.init(origin: CGPoint.init(x: (self.view.bounds.width * CGFloat(atIndex)), y: 0), size: self.view.bounds.size), animated: true) } override func viewDidLoad() { self.collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell") super.viewDidLoad() customization() // add notification center to switch tab let notificationName = Notification.Name("switchTab") NotificationCenter.default.addObserver(self, selector: #selector(MainViewController.switchTab(notification:)), name: notificationName, object: nil) } @objc func switchTab(notification: Notification) { // extract index from notification info guard let userInfo = notification.userInfo else { return } if let index = userInfo["index"] as? Int { // move to selected index didSelectItem(atIndex: index) } } // MARK: CollectionView DataSources func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return self.views.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) cell.contentView.addSubview(self.views[indexPath.row]) return cell } // MARK: Collection View Delegates func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize.init(width: self.view.bounds.width, height: (self.view.bounds.height + 22)) } func scrollViewDidScroll(_ scrollView: UIScrollView) { let scrollIndex = Int(round(scrollView.contentOffset.x / self.view.bounds.width)) self.titleLabel.text = self.items[scrollIndex] if self.viewsAreInitialized { self.tabBar.whiteView.frame.origin.x = (scrollView.contentOffset.x / 4) self.tabBar.highlightItem(atIndex: scrollIndex) } } } ================================================ FILE: PotterPics/NavVC.swift ================================================ // // NavVC.swift // PotterPics // // Created by Suraya Shivji on 11/27/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit class NavVC: UINavigationController { // MARK: Properties let statusView: UIView = { let st = UIView.init(frame: UIApplication.shared.statusBarFrame) st.backgroundColor = UIColor.black st.alpha = 0.15 return st }() // MARK: ViewController lifecycle override func viewDidLoad() { super.viewDidLoad() } override func viewDidAppear(_ animated: Bool) { super.viewWillAppear(true) if let window = UIApplication.shared.keyWindow { window.addSubview(self.statusView) } } } ================================================ FILE: PotterPics/Post.swift ================================================ // // Post.swift // PotterPics // // Created by Suraya Shivji on 12/7/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit class Post { var uid: String // firebase ID var caption: String var downloadURL: String var name: String var profPic: String // facebook profile picture var date: Date init(uid: String, caption: String, downloadURL: String, name: String, profPic: String, date: Date){ self.uid = uid self.caption = caption self.downloadURL = downloadURL self.name = name self.profPic = profPic self.date = date } } ================================================ FILE: PotterPics/PostFeedTableViewCell.swift ================================================ // // PostFeedTableViewCell.swift // PotterPics // // Created by Suraya Shivji on 12/7/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit class PostFeedTableViewCell: UITableViewCell { @IBOutlet weak var captionIcon: UIImageView! @IBOutlet weak var captionLabel: UILabel! @IBOutlet weak var postImage: UIImageView! @IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var smallProfileImg: UIImageView! @IBOutlet weak var dateLabel: UILabel! override func awakeFromNib() { super.awakeFromNib() // Initialization code } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } } ================================================ FILE: PotterPics/PostFeedViewController.swift ================================================ // // PostFeedViewController.swift // PotterPics // // Created by Suraya Shivji on 12/7/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit import Firebase import SwiftyJSON import FBSDKLoginKit import FBSDKCoreKit import MBProgressHUD import AFNetworking class PostFeedViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { @IBOutlet weak var feedTableView: UITableView! var feeds = [Post]() override func viewDidLoad() { super.viewDidLoad() // get posts for all users getAllPosts(refreshing: false, refreshControl: nil) // refresh control let refreshControl = UIRefreshControl() refreshControl.addTarget(self, action: #selector(refreshControlAction(refreshControl:)), for: UIControlEvents.valueChanged) self.feedTableView.insertSubview(refreshControl, at: 0) } @objc func refreshControlAction(refreshControl: UIRefreshControl) { getAllPosts(refreshing: true, refreshControl: refreshControl) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // MARK: Table View Methods func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.feeds.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if let cell = tableView.dequeueReusableCell(withIdentifier: "feedCell", for: indexPath) as? PostFeedTableViewCell { let post = self.feeds[indexPath.row] let caption = post.caption let downloadURL = post.downloadURL let profPic = post.profPic let name = post.name let date = post.date let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd" let dateString = dateFormatter.string(from: date) // user's name cell.nameLabel.text = name // caption cell.captionLabel.text = caption // post image cell.postImage.image = nil if let postURL = URL(string: downloadURL) { let postRequest = URLRequest(url: postURL) cell.postImage.setImageWith(postRequest, placeholderImage: nil, success: { (imageRequest, imageResponse, image) in cell.postImage.contentMode = UIViewContentMode.scaleToFill cell.postImage.image = image }, failure: { (imageRequest, imageResponse, error) -> Void in // failure downloading image print("Error downloading Firebase post image") print(error) }) } // profile image cell.smallProfileImg.image = nil if let url = URL(string: profPic) { let profileRequest = URLRequest(url: url) cell.smallProfileImg.setImageWith(profileRequest, placeholderImage: nil, success: { (imageRequest, imageResponse, image) in cell.smallProfileImg.image = image.potter_circle }, failure: { (imageRequest, imageResponse, error) -> Void in // failure downloading image print("Error downloading Firebase profile image for feed/") print(error) }) } // set date of post cell.dateLabel.text = dateString return cell } return UITableViewCell() } // MARK: Queries func getAllPosts(refreshing: Bool, refreshControl: UIRefreshControl?) { let ref = FIRDatabase.database().reference(withPath: "posts") MBProgressHUD.showAdded(to: self.view, animated: true) ref.observeSingleEvent(of: .value, with: { snapshot in if let dict = snapshot.value as? NSDictionary { if self.feeds.count == Int(snapshot.childrenCount) { if refreshing { refreshControl?.endRefreshing() } MBProgressHUD.hide(for: self.view, animated: true) return } self.feeds = [] for item in dict { let json = JSON(item.value) let uid = json["uid"].stringValue var name: String = "" var pic: String = "" let caption: String = json["caption"].stringValue let downloadURL: String = json["download_url"].stringValue let timestamp = json["timestamp"].doubleValue let date = Date(timeIntervalSince1970: timestamp/1000) let usersReference = FIRDatabase.database().reference(withPath: "users").queryOrderedByKey().queryEqual(toValue: uid) usersReference.observeSingleEvent(of: .value, with: { snapshot in if let dict = snapshot.value as? NSDictionary { let userInfo = dict.allValues[0] let userJSON = JSON(userInfo) name = userJSON["name"].stringValue pic = userJSON["profPicString"].stringValue } let post = Post(uid: uid, caption: caption, downloadURL: downloadURL, name: name, profPic: pic, date: date) self.feeds.append(post) // sort posts by date self.feeds.sort {$0.date.compare($1.date) == .orderedDescending} self.feedTableView.reloadData() }) } } if refreshing { refreshControl?.endRefreshing() } MBProgressHUD.hide(for: self.view, animated: true) }) } } ================================================ FILE: PotterPics/PostViewController.swift ================================================ // // PostViewController.swift // PotterPics // // Created by Suraya Shivji on 12/6/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit import Firebase import MBProgressHUD class PostViewController: UIViewController, ModalViewControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate { let imagePicker = UIImagePickerController() @IBOutlet weak var imagetoUpload: UIImageView! @IBOutlet weak var captionTextField: UITextField! @IBOutlet weak var takePhotoButton: HomeButton! override func viewDidLoad() { super.viewDidLoad() imagePicker.delegate = self self.hideKeyboardWhenTappedAround() self.captionTextField.attributedPlaceholder = NSAttributedString(string: "Enter Caption", attributes:[NSAttributedStringKey.foregroundColor: UIColor.white]) } func sendValue(value: UIImage) { self.imagetoUpload.image = value } @IBAction func dismissKeyboard(_ sender: AnyObject) { sender.resignFirstResponder() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func postToFeed(_ sender: UIButton) { MBProgressHUD.showAdded(to: self.view, animated: true) // post image to firebase storage let postImage = self.imagetoUpload.image let caption = self.captionTextField.text let storage = FIRStorage.storage() let data = UIImagePNGRepresentation(postImage!) // guard for user id guard let uid = FIRAuth.auth()?.currentUser?.uid else { return } let photosRef = storage.reference().child("posts") let usersRef = FIRDatabase.database().reference().child("users") var currentNumPosts: Int? // increase post count usersRef.child(uid).observeSingleEvent(of: .value, with: { (snapshot) in // get user value let value = snapshot.value as? NSDictionary currentNumPosts = value?["postCount"] as? Int self.updateNumPosts(currentNumPosts: currentNumPosts!, uid: uid) }) { (error) in print(error.localizedDescription) } let imageName = NSUUID().uuidString let photoRef = photosRef.child("\(uid)") photoRef.child("\(imageName)").put(data!, metadata: nil) { (metaData,error) in if let error = error { print("there was an error") print(error.localizedDescription) return } else { // store downloadURL let downloadURL = metaData!.downloadURL()!.absoluteString let values: Dictionary = ["uid": uid, "caption": caption ?? "", "download_url": downloadURL, "timestamp": FIRServerValue.timestamp()] // store downloadURL at database let databaseRef = FIRDatabase.database().reference() let path = databaseRef.child("posts").childByAutoId() path.setValue(values) { (error, ref) -> Void in if error != nil { print("error saving post in db") } else { // reset caption field self.captionTextField.text = "" // reset placeholder image self.imagetoUpload.image = UIImage(named: "filterPlaceholder") MBProgressHUD.hide(for: self.view, animated: true) } } } } } func updateNumPosts(currentNumPosts: Int, uid: String) { let usersRef = FIRDatabase.database().reference().child("users") let newCount = currentNumPosts + 1 let values = ["postCount": newCount] usersRef.child(uid).updateChildValues(values) } @IBAction func chooseFromRoll(_ sender: AnyObject) { imagePicker.allowsEditing = false imagePicker.sourceType = .photoLibrary present(imagePicker, animated: true, completion: nil) } @IBAction func takePhoto(_ sender: AnyObject) { // check for simulator #if (arch(i386) || arch(x86_64)) && os(iOS) // alert let message: String = "Please run on a device to use the camera!" let alertView = UIAlertController(title: "Alert", message: message, preferredStyle: UIAlertControllerStyle.alert) alertView.addAction(UIAlertAction(title: "Ok ", style: UIAlertActionStyle.default, handler: nil)) self.present(alertView, animated: true, completion: nil) #else if let modalVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ModalViewController") as? CameraViewController { modalVC.delegate = self present(modalVC, animated: true, completion: nil) } #endif } @objc // MARK: - UIImagePickerControllerDelegate Methods func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) { if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage { self.imagetoUpload.contentMode = .scaleAspectFit self.imagetoUpload.image = pickedImage } dismiss(animated: true, completion: nil) } } ================================================ FILE: PotterPics/PotterPics.entitlements ================================================ keychain-access-groups $(AppIdentifierPrefix)com.surayashivji.PotterPics ================================================ FILE: PotterPics/ProfileTableViewCell.swift ================================================ // // ProfileTableViewCell.swift // PotterPics // // Created by Suraya Shivji on 12/7/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit class ProfileTableViewCell: UITableViewCell { @IBOutlet weak var captionIcon: UIImageView! @IBOutlet weak var captionLabel: UILabel! @IBOutlet weak var postImage: UIImageView! @IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var smallProfileImg: UIImageView! @IBOutlet weak var dateLabel: UILabel! override func awakeFromNib() { super.awakeFromNib() // Initialization code } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } } ================================================ FILE: PotterPics/ProfileViewController.swift ================================================ // // ProfileViewController.swift // PotterPics // // Created by Suraya Shivji on 12/6/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit import Firebase import SwiftyJSON import FBSDKLoginKit import FBSDKCoreKit import AFNetworking import MBProgressHUD class ProfileViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { var user: User? var ref: FIRDatabaseReference! = FIRDatabase.database().reference() var posts = [Post]() typealias CompletionHandler = (_ success:Bool) -> Void @IBOutlet weak var mainView: UIView! @IBOutlet weak var returnButton: UIButton! @IBOutlet weak var houseCrest: UIImageView! @IBOutlet weak var numPostsLabel: UILabel! @IBOutlet weak var returnView: UIView! @IBOutlet weak var tableView: UITableView! @IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var proileImageView: UIImageView! @IBOutlet weak var logoutButton: UIButton! override func viewDidLoad() { super.viewDidLoad() let defaults = UserDefaults.standard let stripCol = defaults.potter_colorForKey(key: "navCol") self.view.backgroundColor = stripCol // set the UID so that we know if it's the current user if let currentUser = FIRAuth.auth()?.currentUser?.uid { configureHeader(currentID: currentUser, completionHandler: { (success) -> Void in if success { // header success self.getUserPosts(currentID: currentUser, refreshing: false, refreshControl: nil) } else { // header fail print("Failure downloading header!") } }) } let profileName = Notification.Name("loadProfileData") NotificationCenter.default.addObserver(self, selector: #selector(ProfileViewController.loadData(notification:)), name: profileName, object: nil) // refresh control let refreshControl = UIRefreshControl() refreshControl.addTarget(self, action: #selector(refreshControlAction(refreshControl:)), for: UIControlEvents.valueChanged) self.tableView.insertSubview(refreshControl, at: 0) } @objc func refreshControlAction(refreshControl: UIRefreshControl) { getUserPosts(currentID: self.user?.userID, refreshing: true, refreshControl: refreshControl) } @objc func loadData(notification: Notification) { // extract user id from notification info self.posts.removeAll() self.tableView.reloadData() guard let userID = notification.userInfo else { return } if let id = userID["id"] as? String { // reload profile with user's info let defaults = UserDefaults.standard let navigationColor = defaults.potter_colorForKey(key: "navCol") self.returnView.backgroundColor = navigationColor self.returnView.isHidden = false // hide logout button self.logoutButton.isHidden = true configureHeader(currentID: id, completionHandler: { (success) -> Void in if success { // header success self.getUserPosts(currentID: id, refreshing: false, refreshControl: nil) } else { // download fail print("Failure setting up header") } }) } } @IBAction func returnToProfile(_ sender: Any) { self.logoutButton.isHidden = false if let currentUser = FIRAuth.auth()?.currentUser?.uid { configureHeader(currentID: currentUser, completionHandler: { (success) -> Void in if success { // header success self.posts.removeAll() self.tableView.reloadData() self.getUserPosts(currentID: currentUser, refreshing: false, refreshControl: nil) } else { // download fail print("Failure to load header info") } }) self.returnView.isHidden = true } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } @IBAction func logoutUser(_ sender: UIButton) { let firebaseAuth = FIRAuth.auth() do { try firebaseAuth?.signOut() FBSDKLoginManager().logOut() self.dismiss(animated: true, completion: nil) } catch let signOutError as NSError { print("Error signing out: %@", signOutError) } } func configureHeader(currentID: String, completionHandler: @escaping CompletionHandler) { let uid = currentID var profPicURL: String = "" var name: String = "Name" var email: String = "Email" var fbID: String = "" var flag: Bool = false var postCount: Int = 0 ref.child("users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in let value = snapshot.value as? NSDictionary // extract values name = value?["name"] as! String profPicURL = value?["profPicString"] as! String email = value?["email"] as! String fbID = value?["facebookID"] as! String postCount = value?["postCount"] as! Int // user: name, email, facebookID, userID, profPic, postCount self.user = User(name: name, email: email, facebookID: fbID, userID: currentID, profPic: profPicURL, postCount: postCount) // set name label self.nameLabel.text = name // set image if profPicURL.characters.count > 0 { let url = URL(string: profPicURL) DispatchQueue.global().async { let data = try? Data(contentsOf: url!) DispatchQueue.main.async { let image = UIImage(data: data!)?.potter_circle self.proileImageView.contentMode = UIViewContentMode.scaleAspectFill self.proileImageView.image = image } } } else { let image = UIImage(named: "default")?.potter_circle self.proileImageView.contentMode = UIViewContentMode.scaleAspectFill self.proileImageView.image = image } // set house crest let house = value?["house"] as! String let image = "\(house).png" self.houseCrest.image = UIImage(named: image) // set num posts if postCount == 1 { self.numPostsLabel.text = "\(postCount) Post" } else { self.numPostsLabel.text = "\(postCount) Posts" } flag = true completionHandler(flag) }) { (error) in flag = false completionHandler(flag) print(error.localizedDescription) } } // MARK: Table View Methods func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.posts.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "profileCell", for: indexPath) as! ProfileTableViewCell let post = self.posts[indexPath.row] let caption = post.caption let downloadURL = post.downloadURL let profPic = self.user?.profPic let name = self.user?.name let date = post.date let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd" let dateString = dateFormatter.string(from: date) // user's post image cell.postImage.image = nil if let postURL = URL(string: downloadURL) { let postRequest = URLRequest(url: postURL) cell.postImage.setImageWith(postRequest, placeholderImage: nil, success: { (imageRequest, imageResponse, image) in cell.postImage.contentMode = UIViewContentMode.scaleToFill cell.postImage.image = image }, failure: { (imageRequest, imageResponse, error) -> Void in // failure downloading image print("Error downloading Firebase post image") print(error) }) } // user's name cell.nameLabel.text = name // user's post caption cell.captionLabel.text = caption // profile image if let urlString = profPic { if let picUrl = URL(string: urlString) { let placeholder = UIImage(named: "default") let profileRequest = URLRequest(url: picUrl) cell.smallProfileImg.setImageWith(profileRequest, placeholderImage: placeholder, success: { (imageRequest, imageResponse, image) in cell.smallProfileImg.image = image.potter_circle }, failure: { (imageRequest, imageResponse, error) -> Void in // failure downloading image print("Error downloading Firebase profile image") print(error) }) } } // date cell.dateLabel.text = dateString return cell } // MARK: Firebase Query Methods // get current user's posts func getUserPosts(currentID: String?, refreshing: Bool, refreshControl: UIRefreshControl?) { if let uid = currentID { let ref = FIRDatabase.database().reference(withPath: "posts").queryOrdered(byChild: "uid").queryEqual(toValue: uid) MBProgressHUD.showAdded(to: self.view, animated: true) var postsCount = self.posts.count ref.observeSingleEvent(of: .value, with: { snapshot in if let dict = snapshot.value as? NSDictionary { if self.posts.count == Int(snapshot.childrenCount) { if refreshing { refreshControl?.endRefreshing() } MBProgressHUD.hide(for: self.view, animated: true) return } postsCount = Int(snapshot.childrenCount) self.posts = [] for item in dict { let json = JSON(item.value) let caption: String = json["caption"].stringValue let downloadURL: String = json["download_url"].stringValue let name: String = json["name"].stringValue let profPic: String = json["profPicString"].stringValue let timestamp = json["timestamp"].doubleValue let date = Date(timeIntervalSince1970: timestamp/1000) // create post from firebase data let post = Post(uid: uid, caption: caption, downloadURL: downloadURL, name: name, profPic: profPic, date: date) self.posts.append(post) } // sort posts by timestamp self.posts.sort{$0.date.compare($1.date) == .orderedDescending} self.tableView.reloadData() } if refreshing { // update post count if postsCount == 1 { self.numPostsLabel.text = "\(postsCount) Post" } else { self.numPostsLabel.text = "\(postsCount) Posts" } refreshControl?.endRefreshing() } MBProgressHUD.hide(for: self.view, animated: true) }) } } } ================================================ FILE: PotterPics/SearchTableViewCell.swift ================================================ // // SearchTableViewCell.swift // PotterPics // // Created by Suraya Shivji on 12/5/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit class SearchTableViewCell: UITableViewCell { @IBOutlet weak var searchImageView: UIImageView! @IBOutlet weak var searchName: UILabel! @IBOutlet weak var numPostsLabel: UILabel! override func awakeFromNib() { super.awakeFromNib() } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } } ================================================ FILE: PotterPics/SearchViewController.swift ================================================ // // SearchViewController.swift // PotterPics // // Created by Suraya Shivji on 12/5/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit import Firebase import SwiftyJSON class SearchViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate { @IBOutlet weak var searchBar: UISearchBar! @IBOutlet weak var tableView: UITableView! var filteredUsers: [User]! var users : [User] = [] override func viewDidLoad() { super.viewDidLoad() self.searchBar.delegate = self getUsers() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func getUsers() { let DB = FIRDatabase.database().reference() let usersRef : FIRDatabaseReference = DB.child("users") usersRef.observe(.value, with: { (snapshot) in if let dict = snapshot.value as? NSDictionary { for item in dict { let json = JSON(item.value) let name: String = json["name"].stringValue let email: String = json["email"].stringValue let fbID: String = json["facebookID"].stringValue let firebaseID: String = item.key as! String let profPicURL: String = json["profPicString"].stringValue let numPosts: Int = json["postCount"].intValue // create User, add to users array let user = User(name: name, email: email, facebookID: fbID, userID: firebaseID, profPic: profPicURL, postCount: numPosts) if let currentID = FIRAuth.auth()?.currentUser?.uid { if(firebaseID != currentID) { self.users.append(user) self.filteredUsers = self.users self.tableView.reloadData() } } } } }) } // MARK: - Table View Methods func numberOfSections(in tableView: UITableView) -> Int { return 1 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // check for nil if self.filteredUsers != nil { return self.filteredUsers!.count } else { return 0 } } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "searchCell") as! SearchTableViewCell cell.searchImageView.image = UIImage() let user = filteredUsers[indexPath.row] let name = user.name let profPicURL = user.profPic let url = URL(string: profPicURL) DispatchQueue.global().async { let data = try? Data(contentsOf: url!) DispatchQueue.main.async { var image = UIImage(data: data!) image = image?.potter_circle cell.searchImageView.contentMode = UIViewContentMode.scaleAspectFill cell.searchImageView.image = image } } // set # of posts cell.numPostsLabel.text = user.postCount == 1 ? "\(user.postCount) Post" : "\(user.postCount) Posts" cell.searchName.text = name return cell } func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { cell.selectionStyle = UITableViewCellSelectionStyle.none } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // resign keyboard self.searchBar.resignFirstResponder() let indexPath = self.tableView.indexPathForSelectedRow let user = filteredUsers[(indexPath?.row)!] // go to profile tab let data: [String: Int] = ["index": 3] let notificationName = Notification.Name("switchTab") NotificationCenter.default.post(name: notificationName, object: nil, userInfo: data) let userID: [String: String] = ["id": user.userID] let profileName = Notification.Name("loadProfileData") NotificationCenter.default.post(name: profileName, object: nil, userInfo: userID) } // MARK: - Search Bar Methods func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { // search bar text changed if(searchText.isEmpty) { filteredUsers = users } else { // user typed in search box // return true in filter if item should be included filteredUsers = users.filter({ (user: User) -> Bool in let name = user.name if name.range(of: searchText, options: .caseInsensitive ) != nil { return true } else { return false } }) } self.tableView.reloadData() } func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) { self.searchBar.showsCancelButton = true } func searchBarCancelButtonClicked(_ searchBar: UISearchBar) { searchBar.text = "" searchBar.showsCancelButton = false searchBar.resignFirstResponder() } } ================================================ FILE: PotterPics/TabBar.swift ================================================ // // TabBar.swift // PotterPics // // Created by Suraya Shivji on 11/27/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // protocol TabBarDelegate { func didSelectItem(atIndex: Int) } import UIKit class TabBar: UIView, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { // MARK: Properties let identifier = "cell" var darkItems = ["feedDark", "searchDark", "postDark", "profileDark"] let items = ["feed", "search", "post", "profile"] lazy var whiteView: UIView = { let wv = UIView.init(frame: CGRect.init(x: 0, y: self.frame.height - 5, width: self.frame.width / 4, height: 5)) wv.backgroundColor = UIColor.potter_rbg(r: 245, g: 245, b: 245) return wv }() lazy var collectionView: UICollectionView = { let layout = UICollectionViewFlowLayout() let cv = UICollectionView.init(frame: CGRect.init(x: 0, y: 20, width: self.frame.width, height: (self.frame.height - 20)), collectionViewLayout: layout) cv.delegate = self cv.dataSource = self cv.backgroundColor = UIColor.clear cv.isScrollEnabled = false return cv }() var delegate: TabBarDelegate? //MARK: CollectionView DataSources func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return self.items.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath) as? TabBarCellCollectionViewCell { cell.icon.image = UIImage.init(named: darkItems[indexPath.row]) if indexPath.row == 0 { cell.icon.image = UIImage.init(named: items[0]) } return cell } return UICollectionViewCell() } // MARK: CollectionView Delegates func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize.init(width: self.frame.width / 4, height: (self.frame.height - 20)) } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { return 0 } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { delegate?.didSelectItem(atIndex: indexPath.row) } // MARK: Methods func highlightItem(atIndex: Int) { for index in 0...3 { if let cell = collectionView.cellForItem(at: IndexPath.init(row: index, section: 0)) as? TabBarCellCollectionViewCell { cell.icon.contentMode = UIViewContentMode.scaleAspectFit cell.icon.image = UIImage.init(named: darkItems[index]) } } if let cell = collectionView.cellForItem(at: IndexPath.init(row: atIndex, section: 0)) as? TabBarCellCollectionViewCell { cell.icon.contentMode = UIViewContentMode.scaleAspectFit cell.icon.image = UIImage.init(named: items[atIndex]) } } // MARK: - Inits override init(frame: CGRect) { super.init(frame: frame) collectionView.register(TabBarCellCollectionViewCell.self, forCellWithReuseIdentifier: identifier) let defaults = UserDefaults.standard let houseValue = defaults.string(forKey: "userHouse") // figure out items and dark items based on house switch houseValue! { case "Gryffindor": darkItems = ["GfeedDark", "GsearchDark", "GpostDark", "GprofileDark"] break case "Slytherin": darkItems = ["SfeedDark", "SsearchDark", "SpostDark", "SprofileDark"] break case "Hufflepuff": darkItems = ["HfeedDark", "HsearchDark", "HpostDark", "HprofileDark"] break case "Ravenclaw": darkItems = ["RfeedDark", "RsearchDark", "RpostDark", "RprofileDark"] break default: break } // house background color let navigationColor = defaults.potter_colorForKey(key: "navCol") self.backgroundColor = navigationColor addSubview(self.collectionView) addSubview(self.whiteView) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } // TabBarCell Class class TabBarCellCollectionViewCell: UICollectionViewCell { let icon = UIImageView() override init(frame: CGRect) { super.init(frame: frame) self.backgroundColor = UIColor.clear let width = (self.contentView.bounds.width - 30) / 2 icon.contentMode = UIViewContentMode.scaleAspectFit icon.frame = CGRect.init(x: width, y: 2, width: 30, height: 30) let image = UIImage.init(named: "home") icon.image = image?.withRenderingMode(.alwaysTemplate) self.contentView.addSubview(icon) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } ================================================ FILE: PotterPics/User.swift ================================================ // // User.swift // PotterPics // // Created by Suraya Shivji on 12/5/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import UIKit class User { var name: String var email: String var facebookID: String var userID: String // firebase ID var profPic: String // fb profile picture var postCount: Int init(name: String, email: String, facebookID: String, userID: String, profPic: String, postCount: Int){ self.name = name self.email = email self.facebookID = facebookID self.userID = userID self.profPic = profPic self.postCount = postCount } } ================================================ FILE: PotterPics.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 2BED6F7C77178D8FFF4A1B0B /* Pods_PotterPicsUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C4BB91CB294702887173BD6 /* Pods_PotterPicsUITests.framework */; }; 633919A21DDD2B5400ABFF34 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 633919A11DDD2B5400ABFF34 /* AppDelegate.swift */; }; 633919A71DDD2B5400ABFF34 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 633919A51DDD2B5400ABFF34 /* Main.storyboard */; }; 633919A91DDD2B5400ABFF34 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 633919A81DDD2B5400ABFF34 /* Assets.xcassets */; }; 633919AC1DDD2B5400ABFF34 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 633919AA1DDD2B5400ABFF34 /* LaunchScreen.storyboard */; }; 633919B71DDD2B5400ABFF34 /* PotterPicsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 633919B61DDD2B5400ABFF34 /* PotterPicsTests.swift */; }; 633919C21DDD2B5400ABFF34 /* PotterPicsUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 633919C11DDD2B5400ABFF34 /* PotterPicsUITests.swift */; }; 633919D11DDD2F1000ABFF34 /* IntroMusic.mp4 in Resources */ = {isa = PBXBuildFile; fileRef = 633919D01DDD2F1000ABFF34 /* IntroMusic.mp4 */; }; 633919D31DDD32F200ABFF34 /* HomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 633919D21DDD32F200ABFF34 /* HomeViewController.swift */; }; 633919D81DDD352C00ABFF34 /* BackgroundVideo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 633919D71DDD352C00ABFF34 /* BackgroundVideo.swift */; }; 633919DB1DDD578800ABFF34 /* HomeButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 633919DA1DDD578800ABFF34 /* HomeButton.swift */; }; 6358ADF21DF8C1C7007C7A25 /* PostFeedTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6358ADF11DF8C1C7007C7A25 /* PostFeedTableViewCell.swift */; }; 6390A94D1DF8C0E60050E75C /* PostFeedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6390A94C1DF8C0E60050E75C /* PostFeedViewController.swift */; }; 6394B8931DF8526E00666811 /* ProfileTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6394B8921DF8526E00666811 /* ProfileTableViewCell.swift */; }; 639AB92D1DED1B4C003BEB0E /* NavVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AB92C1DED1B4C003BEB0E /* NavVC.swift */; }; 639AB92F1DED1B7F003BEB0E /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AB92E1DED1B7F003BEB0E /* MainViewController.swift */; }; 639AB9311DED1BCC003BEB0E /* TabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AB9301DED1BCC003BEB0E /* TabBar.swift */; }; 639AB9331DED1BDA003BEB0E /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AB9321DED1BDA003BEB0E /* Extensions.swift */; }; 639AB9371DED1C1E003BEB0E /* GlobalVariables.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AB9361DED1C1E003BEB0E /* GlobalVariables.swift */; }; 639AB9391DED2007003BEB0E /* ColorPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = 639AB9381DED2007003BEB0E /* ColorPalette.swift */; }; 63EF63751DF85C1F00727FAD /* Post.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63EF63741DF85C1F00727FAD /* Post.swift */; }; 63F4EB3C1DE689E5001832F4 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 63F4EB3B1DE689E5001832F4 /* GoogleService-Info.plist */; }; 63FE0A661DF55F2C00BF7113 /* SearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63FE0A651DF55F2C00BF7113 /* SearchViewController.swift */; }; 63FE0A681DF55F4C00BF7113 /* SearchTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63FE0A671DF55F4C00BF7113 /* SearchTableViewCell.swift */; }; 63FE0A6A1DF5F08A00BF7113 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63FE0A691DF5F08A00BF7113 /* User.swift */; }; 63FE0AB01DF6D03800BF7113 /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63FE0AAF1DF6D03800BF7113 /* ProfileViewController.swift */; }; 63FE0AB21DF6D93E00BF7113 /* default.png in Resources */ = {isa = PBXBuildFile; fileRef = 63FE0AB11DF6D93E00BF7113 /* default.png */; }; 63FE0ABA1DF6F0F000BF7113 /* Gryffindor.png in Resources */ = {isa = PBXBuildFile; fileRef = 63FE0AB61DF6F0F000BF7113 /* Gryffindor.png */; }; 63FE0ABB1DF6F0F000BF7113 /* Slytherin.png in Resources */ = {isa = PBXBuildFile; fileRef = 63FE0AB71DF6F0F000BF7113 /* Slytherin.png */; }; 63FE0ABC1DF6F0F000BF7113 /* Ravenclaw.png in Resources */ = {isa = PBXBuildFile; fileRef = 63FE0AB81DF6F0F000BF7113 /* Ravenclaw.png */; }; 63FE0ABD1DF6F0F000BF7113 /* Hufflepuff.png in Resources */ = {isa = PBXBuildFile; fileRef = 63FE0AB91DF6F0F000BF7113 /* Hufflepuff.png */; }; 63FE0ABF1DF6F37200BF7113 /* background.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 63FE0ABE1DF6F37200BF7113 /* background.jpg */; }; 63FE0AC11DF6FF9A00BF7113 /* PostViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63FE0AC01DF6FF9A00BF7113 /* PostViewController.swift */; }; 63FE0AC31DF78E5B00BF7113 /* filterPlaceholder.png in Resources */ = {isa = PBXBuildFile; fileRef = 63FE0AC21DF78E5B00BF7113 /* filterPlaceholder.png */; }; 63FE0AC51DF78E9900BF7113 /* CameraViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63FE0AC41DF78E9900BF7113 /* CameraViewController.swift */; }; 63FE0AC71DF79A7800BF7113 /* FilterCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63FE0AC61DF79A7800BF7113 /* FilterCollectionViewCell.swift */; }; 8CBAEACF864FDB6D0D036B54 /* Pods_PotterPics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC66CBEF6CAADAECA954EFA3 /* Pods_PotterPics.framework */; }; B4A68C6759D618394E395D2D /* Pods_PotterPicsTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4017A70A8CAF4A8155644A8B /* Pods_PotterPicsTests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ 633919B31DDD2B5400ABFF34 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 633919961DDD2B5400ABFF34 /* Project object */; proxyType = 1; remoteGlobalIDString = 6339199D1DDD2B5400ABFF34; remoteInfo = PotterPics; }; 633919BE1DDD2B5400ABFF34 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 633919961DDD2B5400ABFF34 /* Project object */; proxyType = 1; remoteGlobalIDString = 6339199D1DDD2B5400ABFF34; remoteInfo = PotterPics; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 1C4BB91CB294702887173BD6 /* Pods_PotterPicsUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PotterPicsUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 4017A70A8CAF4A8155644A8B /* Pods_PotterPicsTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PotterPicsTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 6339199E1DDD2B5400ABFF34 /* PotterPics.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PotterPics.app; sourceTree = BUILT_PRODUCTS_DIR; }; 633919A11DDD2B5400ABFF34 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 633919A61DDD2B5400ABFF34 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 633919A81DDD2B5400ABFF34 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 633919AB1DDD2B5400ABFF34 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 633919AD1DDD2B5400ABFF34 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 633919B21DDD2B5400ABFF34 /* PotterPicsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PotterPicsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 633919B61DDD2B5400ABFF34 /* PotterPicsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PotterPicsTests.swift; sourceTree = ""; }; 633919B81DDD2B5400ABFF34 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 633919BD1DDD2B5400ABFF34 /* PotterPicsUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PotterPicsUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 633919C11DDD2B5400ABFF34 /* PotterPicsUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PotterPicsUITests.swift; sourceTree = ""; }; 633919C31DDD2B5400ABFF34 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 633919D01DDD2F1000ABFF34 /* IntroMusic.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = IntroMusic.mp4; sourceTree = ""; }; 633919D21DDD32F200ABFF34 /* HomeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = ""; }; 633919D71DDD352C00ABFF34 /* BackgroundVideo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundVideo.swift; sourceTree = ""; }; 633919DA1DDD578800ABFF34 /* HomeButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeButton.swift; sourceTree = ""; }; 633919E41DDF9AF600ABFF34 /* PotterPics.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PotterPics.entitlements; sourceTree = ""; }; 6358ADF11DF8C1C7007C7A25 /* PostFeedTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostFeedTableViewCell.swift; sourceTree = ""; }; 6390A94C1DF8C0E60050E75C /* PostFeedViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostFeedViewController.swift; sourceTree = ""; }; 6394B8921DF8526E00666811 /* ProfileTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProfileTableViewCell.swift; sourceTree = ""; }; 639AB92C1DED1B4C003BEB0E /* NavVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavVC.swift; sourceTree = ""; }; 639AB92E1DED1B7F003BEB0E /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = ""; }; 639AB9301DED1BCC003BEB0E /* TabBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabBar.swift; sourceTree = ""; }; 639AB9321DED1BDA003BEB0E /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 639AB9361DED1C1E003BEB0E /* GlobalVariables.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalVariables.swift; sourceTree = ""; }; 639AB9381DED2007003BEB0E /* ColorPalette.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorPalette.swift; sourceTree = ""; }; 63EF63741DF85C1F00727FAD /* Post.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Post.swift; sourceTree = ""; }; 63F4EB3B1DE689E5001832F4 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 63FE0A651DF55F2C00BF7113 /* SearchViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchViewController.swift; sourceTree = ""; }; 63FE0A671DF55F4C00BF7113 /* SearchTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SearchTableViewCell.swift; sourceTree = ""; }; 63FE0A691DF5F08A00BF7113 /* User.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = ""; }; 63FE0AAF1DF6D03800BF7113 /* ProfileViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = ""; }; 63FE0AB11DF6D93E00BF7113 /* default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = default.png; sourceTree = ""; }; 63FE0AB61DF6F0F000BF7113 /* Gryffindor.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Gryffindor.png; sourceTree = ""; }; 63FE0AB71DF6F0F000BF7113 /* Slytherin.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Slytherin.png; sourceTree = ""; }; 63FE0AB81DF6F0F000BF7113 /* Ravenclaw.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Ravenclaw.png; sourceTree = ""; }; 63FE0AB91DF6F0F000BF7113 /* Hufflepuff.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Hufflepuff.png; sourceTree = ""; }; 63FE0ABE1DF6F37200BF7113 /* background.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = background.jpg; sourceTree = ""; }; 63FE0AC01DF6FF9A00BF7113 /* PostViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostViewController.swift; sourceTree = ""; }; 63FE0AC21DF78E5B00BF7113 /* filterPlaceholder.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = filterPlaceholder.png; sourceTree = ""; }; 63FE0AC41DF78E9900BF7113 /* CameraViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraViewController.swift; sourceTree = ""; }; 63FE0AC61DF79A7800BF7113 /* FilterCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FilterCollectionViewCell.swift; sourceTree = ""; }; 6FD8AD91C27B308A584ACEAA /* Pods-PotterPicsUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PotterPicsUITests.release.xcconfig"; path = "Pods/Target Support Files/Pods-PotterPicsUITests/Pods-PotterPicsUITests.release.xcconfig"; sourceTree = ""; }; 77F924F2B63D37AFD4B263B5 /* Pods-PotterPicsTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PotterPicsTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-PotterPicsTests/Pods-PotterPicsTests.release.xcconfig"; sourceTree = ""; }; 841C1D4EB105680E38118A37 /* Pods-PotterPicsTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PotterPicsTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PotterPicsTests/Pods-PotterPicsTests.debug.xcconfig"; sourceTree = ""; }; B5C6FF5FAFCD28EBA922BBC3 /* Pods-PotterPics.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PotterPics.release.xcconfig"; path = "Pods/Target Support Files/Pods-PotterPics/Pods-PotterPics.release.xcconfig"; sourceTree = ""; }; CC66CBEF6CAADAECA954EFA3 /* Pods_PotterPics.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PotterPics.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E3C916B7A307A51188192735 /* Pods-PotterPicsUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PotterPicsUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PotterPicsUITests/Pods-PotterPicsUITests.debug.xcconfig"; sourceTree = ""; }; F547D28AB9D74E94184E48A3 /* Pods-PotterPics.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PotterPics.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PotterPics/Pods-PotterPics.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 6339199B1DDD2B5400ABFF34 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 8CBAEACF864FDB6D0D036B54 /* Pods_PotterPics.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 633919AF1DDD2B5400ABFF34 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( B4A68C6759D618394E395D2D /* Pods_PotterPicsTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; 633919BA1DDD2B5400ABFF34 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 2BED6F7C77178D8FFF4A1B0B /* Pods_PotterPicsUITests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 5DBB93647EFFF284B99333FF /* Frameworks */ = { isa = PBXGroup; children = ( CC66CBEF6CAADAECA954EFA3 /* Pods_PotterPics.framework */, 4017A70A8CAF4A8155644A8B /* Pods_PotterPicsTests.framework */, 1C4BB91CB294702887173BD6 /* Pods_PotterPicsUITests.framework */, ); name = Frameworks; sourceTree = ""; }; 633919951DDD2B5400ABFF34 = { isa = PBXGroup; children = ( 633919A01DDD2B5400ABFF34 /* PotterPics */, 633919B51DDD2B5400ABFF34 /* PotterPicsTests */, 633919C01DDD2B5400ABFF34 /* PotterPicsUITests */, 6339199F1DDD2B5400ABFF34 /* Products */, 78C1FB455017BD611DBA4DD4 /* Pods */, 5DBB93647EFFF284B99333FF /* Frameworks */, ); sourceTree = ""; }; 6339199F1DDD2B5400ABFF34 /* Products */ = { isa = PBXGroup; children = ( 6339199E1DDD2B5400ABFF34 /* PotterPics.app */, 633919B21DDD2B5400ABFF34 /* PotterPicsTests.xctest */, 633919BD1DDD2B5400ABFF34 /* PotterPicsUITests.xctest */, ); name = Products; sourceTree = ""; }; 633919A01DDD2B5400ABFF34 /* PotterPics */ = { isa = PBXGroup; children = ( 633919E41DDF9AF600ABFF34 /* PotterPics.entitlements */, 63F4EB3B1DE689E5001832F4 /* GoogleService-Info.plist */, 633919A11DDD2B5400ABFF34 /* AppDelegate.swift */, 639AB93C1DED35AD003BEB0E /* Helpers */, 633919D61DDD330500ABFF34 /* Models */, 633919D51DDD330000ABFF34 /* Views */, 633919D41DDD32FB00ABFF34 /* ViewControllers */, 633919CF1DDD2F0200ABFF34 /* Assets */, 633919A51DDD2B5400ABFF34 /* Main.storyboard */, 633919A81DDD2B5400ABFF34 /* Assets.xcassets */, 633919AA1DDD2B5400ABFF34 /* LaunchScreen.storyboard */, 633919AD1DDD2B5400ABFF34 /* Info.plist */, ); path = PotterPics; sourceTree = ""; }; 633919B51DDD2B5400ABFF34 /* PotterPicsTests */ = { isa = PBXGroup; children = ( 633919B61DDD2B5400ABFF34 /* PotterPicsTests.swift */, 633919B81DDD2B5400ABFF34 /* Info.plist */, ); path = PotterPicsTests; sourceTree = ""; }; 633919C01DDD2B5400ABFF34 /* PotterPicsUITests */ = { isa = PBXGroup; children = ( 633919C11DDD2B5400ABFF34 /* PotterPicsUITests.swift */, 633919C31DDD2B5400ABFF34 /* Info.plist */, ); path = PotterPicsUITests; sourceTree = ""; }; 633919CF1DDD2F0200ABFF34 /* Assets */ = { isa = PBXGroup; children = ( 63FE0AB11DF6D93E00BF7113 /* default.png */, 633919D01DDD2F1000ABFF34 /* IntroMusic.mp4 */, 63FE0AC21DF78E5B00BF7113 /* filterPlaceholder.png */, 63FE0AB61DF6F0F000BF7113 /* Gryffindor.png */, 63FE0AB71DF6F0F000BF7113 /* Slytherin.png */, 63FE0AB81DF6F0F000BF7113 /* Ravenclaw.png */, 63FE0ABE1DF6F37200BF7113 /* background.jpg */, 63FE0AB91DF6F0F000BF7113 /* Hufflepuff.png */, ); name = Assets; sourceTree = ""; }; 633919D41DDD32FB00ABFF34 /* ViewControllers */ = { isa = PBXGroup; children = ( 639AB92C1DED1B4C003BEB0E /* NavVC.swift */, 63FE0AC41DF78E9900BF7113 /* CameraViewController.swift */, 633919D21DDD32F200ABFF34 /* HomeViewController.swift */, 639AB92E1DED1B7F003BEB0E /* MainViewController.swift */, 63FE0A651DF55F2C00BF7113 /* SearchViewController.swift */, 63FE0AAF1DF6D03800BF7113 /* ProfileViewController.swift */, 6390A94C1DF8C0E60050E75C /* PostFeedViewController.swift */, 63FE0AC01DF6FF9A00BF7113 /* PostViewController.swift */, ); name = ViewControllers; sourceTree = ""; }; 633919D51DDD330000ABFF34 /* Views */ = { isa = PBXGroup; children = ( 63FE0AC61DF79A7800BF7113 /* FilterCollectionViewCell.swift */, 639AB9301DED1BCC003BEB0E /* TabBar.swift */, 633919DA1DDD578800ABFF34 /* HomeButton.swift */, 63FE0A671DF55F4C00BF7113 /* SearchTableViewCell.swift */, 6358ADF11DF8C1C7007C7A25 /* PostFeedTableViewCell.swift */, 6394B8921DF8526E00666811 /* ProfileTableViewCell.swift */, ); name = Views; sourceTree = ""; }; 633919D61DDD330500ABFF34 /* Models */ = { isa = PBXGroup; children = ( 63EF63741DF85C1F00727FAD /* Post.swift */, 63FE0A691DF5F08A00BF7113 /* User.swift */, ); name = Models; sourceTree = ""; }; 639AB93C1DED35AD003BEB0E /* Helpers */ = { isa = PBXGroup; children = ( 639AB9381DED2007003BEB0E /* ColorPalette.swift */, 639AB9321DED1BDA003BEB0E /* Extensions.swift */, 639AB9361DED1C1E003BEB0E /* GlobalVariables.swift */, 633919D71DDD352C00ABFF34 /* BackgroundVideo.swift */, ); name = Helpers; sourceTree = ""; }; 78C1FB455017BD611DBA4DD4 /* Pods */ = { isa = PBXGroup; children = ( F547D28AB9D74E94184E48A3 /* Pods-PotterPics.debug.xcconfig */, B5C6FF5FAFCD28EBA922BBC3 /* Pods-PotterPics.release.xcconfig */, 841C1D4EB105680E38118A37 /* Pods-PotterPicsTests.debug.xcconfig */, 77F924F2B63D37AFD4B263B5 /* Pods-PotterPicsTests.release.xcconfig */, E3C916B7A307A51188192735 /* Pods-PotterPicsUITests.debug.xcconfig */, 6FD8AD91C27B308A584ACEAA /* Pods-PotterPicsUITests.release.xcconfig */, ); name = Pods; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 6339199D1DDD2B5400ABFF34 /* PotterPics */ = { isa = PBXNativeTarget; buildConfigurationList = 633919C61DDD2B5400ABFF34 /* Build configuration list for PBXNativeTarget "PotterPics" */; buildPhases = ( B7846CC88D3048B2642C59D8 /* [CP] Check Pods Manifest.lock */, 6339199A1DDD2B5400ABFF34 /* Sources */, 6339199B1DDD2B5400ABFF34 /* Frameworks */, 6339199C1DDD2B5400ABFF34 /* Resources */, 3B05B9399D5E0AC33E264366 /* [CP] Embed Pods Frameworks */, A4680ADD17B06347890F800B /* [CP] Copy Pods Resources */, ); buildRules = ( ); dependencies = ( ); name = PotterPics; productName = PotterPics; productReference = 6339199E1DDD2B5400ABFF34 /* PotterPics.app */; productType = "com.apple.product-type.application"; }; 633919B11DDD2B5400ABFF34 /* PotterPicsTests */ = { isa = PBXNativeTarget; buildConfigurationList = 633919C91DDD2B5400ABFF34 /* Build configuration list for PBXNativeTarget "PotterPicsTests" */; buildPhases = ( 6F39E5BD0AB1992C7DFD6D66 /* [CP] Check Pods Manifest.lock */, 633919AE1DDD2B5400ABFF34 /* Sources */, 633919AF1DDD2B5400ABFF34 /* Frameworks */, 633919B01DDD2B5400ABFF34 /* Resources */, EE4A4055366AEA4BBE9AF956 /* [CP] Embed Pods Frameworks */, AFA1FBE6B9DB6E6CA68F2029 /* [CP] Copy Pods Resources */, ); buildRules = ( ); dependencies = ( 633919B41DDD2B5400ABFF34 /* PBXTargetDependency */, ); name = PotterPicsTests; productName = PotterPicsTests; productReference = 633919B21DDD2B5400ABFF34 /* PotterPicsTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; 633919BC1DDD2B5400ABFF34 /* PotterPicsUITests */ = { isa = PBXNativeTarget; buildConfigurationList = 633919CC1DDD2B5400ABFF34 /* Build configuration list for PBXNativeTarget "PotterPicsUITests" */; buildPhases = ( 06625B5A1F45865349162505 /* [CP] Check Pods Manifest.lock */, 633919B91DDD2B5400ABFF34 /* Sources */, 633919BA1DDD2B5400ABFF34 /* Frameworks */, 633919BB1DDD2B5400ABFF34 /* Resources */, EBA8B0E9D067AA46D409A86E /* [CP] Embed Pods Frameworks */, FD564F2D9ED2925E21600C2B /* [CP] Copy Pods Resources */, ); buildRules = ( ); dependencies = ( 633919BF1DDD2B5400ABFF34 /* PBXTargetDependency */, ); name = PotterPicsUITests; productName = PotterPicsUITests; productReference = 633919BD1DDD2B5400ABFF34 /* PotterPicsUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 633919961DDD2B5400ABFF34 /* Project object */ = { isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0810; LastUpgradeCheck = 0810; ORGANIZATIONNAME = "Suraya Shivji"; TargetAttributes = { 6339199D1DDD2B5400ABFF34 = { CreatedOnToolsVersion = 8.1; DevelopmentTeam = 97Q63CPWP2; LastSwiftMigration = 0900; ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.Keychain = { enabled = 1; }; }; }; 633919B11DDD2B5400ABFF34 = { CreatedOnToolsVersion = 8.1; DevelopmentTeam = 97Q63CPWP2; LastSwiftMigration = 0900; ProvisioningStyle = Automatic; TestTargetID = 6339199D1DDD2B5400ABFF34; }; 633919BC1DDD2B5400ABFF34 = { CreatedOnToolsVersion = 8.1; DevelopmentTeam = 97Q63CPWP2; LastSwiftMigration = 0900; ProvisioningStyle = Automatic; TestTargetID = 6339199D1DDD2B5400ABFF34; }; }; }; buildConfigurationList = 633919991DDD2B5400ABFF34 /* Build configuration list for PBXProject "PotterPics" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = 633919951DDD2B5400ABFF34; productRefGroup = 6339199F1DDD2B5400ABFF34 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 6339199D1DDD2B5400ABFF34 /* PotterPics */, 633919B11DDD2B5400ABFF34 /* PotterPicsTests */, 633919BC1DDD2B5400ABFF34 /* PotterPicsUITests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 6339199C1DDD2B5400ABFF34 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 63FE0ABB1DF6F0F000BF7113 /* Slytherin.png in Resources */, 63FE0ABF1DF6F37200BF7113 /* background.jpg in Resources */, 633919AC1DDD2B5400ABFF34 /* LaunchScreen.storyboard in Resources */, 63FE0AC31DF78E5B00BF7113 /* filterPlaceholder.png in Resources */, 633919A91DDD2B5400ABFF34 /* Assets.xcassets in Resources */, 63FE0AB21DF6D93E00BF7113 /* default.png in Resources */, 63FE0ABA1DF6F0F000BF7113 /* Gryffindor.png in Resources */, 63F4EB3C1DE689E5001832F4 /* GoogleService-Info.plist in Resources */, 63FE0ABD1DF6F0F000BF7113 /* Hufflepuff.png in Resources */, 63FE0ABC1DF6F0F000BF7113 /* Ravenclaw.png in Resources */, 633919D11DDD2F1000ABFF34 /* IntroMusic.mp4 in Resources */, 633919A71DDD2B5400ABFF34 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; 633919B01DDD2B5400ABFF34 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; 633919BB1DDD2B5400ABFF34 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 06625B5A1F45865349162505 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; showEnvVarsInLog = 0; }; 3B05B9399D5E0AC33E264366 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PotterPics/Pods-PotterPics-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; 6F39E5BD0AB1992C7DFD6D66 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; showEnvVarsInLog = 0; }; A4680ADD17B06347890F800B /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "[CP] Copy Pods Resources"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PotterPics/Pods-PotterPics-resources.sh\"\n"; showEnvVarsInLog = 0; }; AFA1FBE6B9DB6E6CA68F2029 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "[CP] Copy Pods Resources"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PotterPicsTests/Pods-PotterPicsTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; B7846CC88D3048B2642C59D8 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; showEnvVarsInLog = 0; }; EBA8B0E9D067AA46D409A86E /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PotterPicsUITests/Pods-PotterPicsUITests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; EE4A4055366AEA4BBE9AF956 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PotterPicsTests/Pods-PotterPicsTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; FD564F2D9ED2925E21600C2B /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "[CP] Copy Pods Resources"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PotterPicsUITests/Pods-PotterPicsUITests-resources.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 6339199A1DDD2B5400ABFF34 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 63FE0A661DF55F2C00BF7113 /* SearchViewController.swift in Sources */, 63FE0AC51DF78E9900BF7113 /* CameraViewController.swift in Sources */, 633919DB1DDD578800ABFF34 /* HomeButton.swift in Sources */, 6394B8931DF8526E00666811 /* ProfileTableViewCell.swift in Sources */, 639AB92D1DED1B4C003BEB0E /* NavVC.swift in Sources */, 6358ADF21DF8C1C7007C7A25 /* PostFeedTableViewCell.swift in Sources */, 633919A21DDD2B5400ABFF34 /* AppDelegate.swift in Sources */, 6390A94D1DF8C0E60050E75C /* PostFeedViewController.swift in Sources */, 63FE0AB01DF6D03800BF7113 /* ProfileViewController.swift in Sources */, 639AB9331DED1BDA003BEB0E /* Extensions.swift in Sources */, 63FE0A6A1DF5F08A00BF7113 /* User.swift in Sources */, 639AB9371DED1C1E003BEB0E /* GlobalVariables.swift in Sources */, 63EF63751DF85C1F00727FAD /* Post.swift in Sources */, 639AB92F1DED1B7F003BEB0E /* MainViewController.swift in Sources */, 633919D81DDD352C00ABFF34 /* BackgroundVideo.swift in Sources */, 63FE0AC71DF79A7800BF7113 /* FilterCollectionViewCell.swift in Sources */, 63FE0AC11DF6FF9A00BF7113 /* PostViewController.swift in Sources */, 633919D31DDD32F200ABFF34 /* HomeViewController.swift in Sources */, 63FE0A681DF55F4C00BF7113 /* SearchTableViewCell.swift in Sources */, 639AB9311DED1BCC003BEB0E /* TabBar.swift in Sources */, 639AB9391DED2007003BEB0E /* ColorPalette.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 633919AE1DDD2B5400ABFF34 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 633919B71DDD2B5400ABFF34 /* PotterPicsTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; 633919B91DDD2B5400ABFF34 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 633919C21DDD2B5400ABFF34 /* PotterPicsUITests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 633919B41DDD2B5400ABFF34 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 6339199D1DDD2B5400ABFF34 /* PotterPics */; targetProxy = 633919B31DDD2B5400ABFF34 /* PBXContainerItemProxy */; }; 633919BF1DDD2B5400ABFF34 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 6339199D1DDD2B5400ABFF34 /* PotterPics */; targetProxy = 633919BE1DDD2B5400ABFF34 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ 633919A51DDD2B5400ABFF34 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 633919A61DDD2B5400ABFF34 /* Base */, ); name = Main.storyboard; sourceTree = ""; }; 633919AA1DDD2B5400ABFF34 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( 633919AB1DDD2B5400ABFF34 /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 633919C41DDD2B5400ABFF34 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 10.1; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; 633919C51DDD2B5400ABFF34 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 10.1; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; VALIDATE_PRODUCT = YES; }; name = Release; }; 633919C71DDD2B5400ABFF34 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = F547D28AB9D74E94184E48A3 /* Pods-PotterPics.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = PotterPics/PotterPics.entitlements; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = 97Q63CPWP2; INFOPLIST_FILE = PotterPics/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.surayashivji.PotterPicsApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_SWIFT3_OBJC_INFERENCE = On; SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = 1; }; name = Debug; }; 633919C81DDD2B5400ABFF34 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = B5C6FF5FAFCD28EBA922BBC3 /* Pods-PotterPics.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = PotterPics/PotterPics.entitlements; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = 97Q63CPWP2; INFOPLIST_FILE = PotterPics/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 10.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.surayashivji.PotterPicsApp; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_SWIFT3_OBJC_INFERENCE = On; SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = 1; }; name = Release; }; 633919CA1DDD2B5400ABFF34 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 841C1D4EB105680E38118A37 /* Pods-PotterPicsTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; DEVELOPMENT_TEAM = 97Q63CPWP2; INFOPLIST_FILE = PotterPicsTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.surayashivji.PotterPicsTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = On; SWIFT_VERSION = 4.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PotterPics.app/PotterPics"; }; name = Debug; }; 633919CB1DDD2B5400ABFF34 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 77F924F2B63D37AFD4B263B5 /* Pods-PotterPicsTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; DEVELOPMENT_TEAM = 97Q63CPWP2; INFOPLIST_FILE = PotterPicsTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.surayashivji.PotterPicsTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = On; SWIFT_VERSION = 4.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/PotterPics.app/PotterPics"; }; name = Release; }; 633919CD1DDD2B5400ABFF34 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = E3C916B7A307A51188192735 /* Pods-PotterPicsUITests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; DEVELOPMENT_TEAM = 97Q63CPWP2; INFOPLIST_FILE = PotterPicsUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.surayashivji.PotterPicsUITests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = On; SWIFT_VERSION = 4.0; TEST_TARGET_NAME = PotterPics; }; name = Debug; }; 633919CE1DDD2B5400ABFF34 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 6FD8AD91C27B308A584ACEAA /* Pods-PotterPicsUITests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; DEVELOPMENT_TEAM = 97Q63CPWP2; INFOPLIST_FILE = PotterPicsUITests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.surayashivji.PotterPicsUITests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_SWIFT3_OBJC_INFERENCE = On; SWIFT_VERSION = 4.0; TEST_TARGET_NAME = PotterPics; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 633919991DDD2B5400ABFF34 /* Build configuration list for PBXProject "PotterPics" */ = { isa = XCConfigurationList; buildConfigurations = ( 633919C41DDD2B5400ABFF34 /* Debug */, 633919C51DDD2B5400ABFF34 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 633919C61DDD2B5400ABFF34 /* Build configuration list for PBXNativeTarget "PotterPics" */ = { isa = XCConfigurationList; buildConfigurations = ( 633919C71DDD2B5400ABFF34 /* Debug */, 633919C81DDD2B5400ABFF34 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 633919C91DDD2B5400ABFF34 /* Build configuration list for PBXNativeTarget "PotterPicsTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 633919CA1DDD2B5400ABFF34 /* Debug */, 633919CB1DDD2B5400ABFF34 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 633919CC1DDD2B5400ABFF34 /* Build configuration list for PBXNativeTarget "PotterPicsUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( 633919CD1DDD2B5400ABFF34 /* Debug */, 633919CE1DDD2B5400ABFF34 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 633919961DDD2B5400ABFF34 /* Project object */; } ================================================ FILE: PotterPics.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: PotterPics.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: PotterPicsTests/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleVersion 1 ================================================ FILE: PotterPicsTests/PotterPicsTests.swift ================================================ // // PotterPicsTests.swift // PotterPicsTests // // Created by Suraya Shivji on 11/16/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import XCTest @testable import PotterPics class PotterPicsTests: XCTestCase { override func setUp() { super.setUp() // Put setup code here. This method is called before the invocation of each test method in the class. } override func tearDown() { // Put teardown code here. This method is called after the invocation of each test method in the class. super.tearDown() } func testExample() { // This is an example of a functional test case. // Use XCTAssert and related functions to verify your tests produce the correct results. } func testPerformanceExample() { // This is an example of a performance test case. self.measure { // Put the code you want to measure the time of here. } } } ================================================ FILE: PotterPicsUITests/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleVersion 1 ================================================ FILE: PotterPicsUITests/PotterPicsUITests.swift ================================================ // // PotterPicsUITests.swift // PotterPicsUITests // // Created by Suraya Shivji on 11/16/16. // Copyright © 2016 Suraya Shivji. All rights reserved. // import XCTest class PotterPicsUITests: XCTestCase { override func setUp() { super.setUp() // Put setup code here. This method is called before the invocation of each test method in the class. // In UI tests it is usually best to stop immediately when a failure occurs. continueAfterFailure = false // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. XCUIApplication().launch() // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. } override func tearDown() { // Put teardown code here. This method is called after the invocation of each test method in the class. super.tearDown() } func testExample() { // Use recording to get started writing UI tests. // Use XCTAssert and related functions to verify your tests produce the correct results. } } ================================================ FILE: README.md ================================================ # Potter Pics [![Language: Swift 4.0](https://img.shields.io/badge/swift-4.0-orange.svg?style=flat)](https://developer.apple.com/swift) [![License: MIT License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://opensource.org/licenses/MIT) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/59242a4e7d224e178caf013098ffe5ce)](https://www.codacy.com) **PotterPics** is a Harry Potter themed social network similar to Instagram. ## Walkthrough #### Home, Main Feed, Profile
Home Main Feed Profile
#### Library Post, Search, Camera Post
Post Search Camera
## Installation #### Test Facebook Account: Email: **harry_cpmpqmi_potter@tfbnw.net**
Password: voldemort123

## Design Assets - [After Effects Cloud Animation](https://drive.google.com/open?id=0B6aOEAXdWnEGanFLS3JORmNDWDA) - [Photoshop Title Text](https://drive.google.com/open?id=0B6aOEAXdWnEGUnI3N1FQZ0JDOFk) ## Credits - [Facebook SDK](https://developers.facebook.com/docs/ios/) - [Firebase](https://firebase.google.com/) - [SwiftyJSON](https://github.com/SwiftyJSON/SwiftyJSON) - [MBProgressHUD](https://github.com/jdg/MBProgressHUD) - [AFNetworking](https://github.com/AFNetworking/AFNetworking)