diff --git a/Pods/Braintree/BraintreeApplePay/BTApplePayCardNonce.m b/Pods/Braintree/BraintreeApplePay/BTApplePayCardNonce.m new file mode 100644 index 0000000..517e27d --- /dev/null +++ b/Pods/Braintree/BraintreeApplePay/BTApplePayCardNonce.m @@ -0,0 +1,13 @@ +#import "BTApplePayCardNonce.h" + +@implementation BTApplePayCardNonce + +- (instancetype)initWithNonce:(NSString *)nonce localizedDescription:(NSString *)description type:(NSString *)type json:(BTJSON *)json { + self = [super initWithNonce:nonce localizedDescription:description type:type]; + if (self) { + _binData = [[BTBinData alloc] initWithJSON:json[@"binData"]]; + } + return self; +} + +@end diff --git a/Pods/Braintree/BraintreeApplePay/BTApplePayClient.m b/Pods/Braintree/BraintreeApplePay/BTApplePayClient.m new file mode 100644 index 0000000..d6d0270 --- /dev/null +++ b/Pods/Braintree/BraintreeApplePay/BTApplePayClient.m @@ -0,0 +1,179 @@ +#if __has_include("BraintreeCore.h") +#import "BTAPIClient_Internal.h" +#import "BTPaymentMethodNonce.h" +#else +#import +#import +#endif +#import "BTApplePayClient_Internal.h" +#import "BTConfiguration+ApplePay.h" + +NSString *const BTApplePayErrorDomain = @"com.braintreepayments.BTApplePayErrorDomain"; + +@interface BTApplePayClient () +@end + +@implementation BTApplePayClient + +#pragma mark - Initialization + ++ (void)load { + if (self == [BTApplePayClient class]) { + [[BTPaymentMethodNonceParser sharedParser] registerType:@"ApplePayCard" withParsingBlock:^BTPaymentMethodNonce * _Nullable(BTJSON * _Nonnull applePayCard) { + NSString *cardType = applePayCard[@"details"][@"cardType"] ? [applePayCard[@"details"][@"cardType"] asString] : @"ApplePayCard"; + return [[BTApplePayCardNonce alloc] initWithNonce:[applePayCard[@"nonce"] asString] localizedDescription:[applePayCard[@"description"] asString] type:cardType json:applePayCard]; + }]; + } +} + +- (instancetype)initWithAPIClient:(BTAPIClient *)apiClient { + if (self = [super init]) { + _apiClient = apiClient; + } + return self; +} + +- (instancetype)init { + return nil; +} + +#pragma mark - Public methods + +- (void)paymentRequest:(void (^)(PKPaymentRequest * _Nullable, NSError * _Nullable))completion { + if (!self.apiClient) { + NSError *error = [NSError errorWithDomain:BTApplePayErrorDomain + code:BTApplePayErrorTypeIntegration + userInfo:@{NSLocalizedDescriptionKey: @"BTAPIClient is nil."}]; + [self invokeBlock:completion onMainThreadWithPaymentRequest:nil error:error]; + return; + } + + [self.apiClient fetchOrReturnRemoteConfiguration:^(BTConfiguration * _Nullable configuration, NSError * _Nullable error) { + if (error) { + [self.apiClient sendAnalyticsEvent:@"ios.apple-pay.error.configuration"]; + [self invokeBlock:completion onMainThreadWithPaymentRequest:nil error:error]; + return; + } + + if (!configuration.isApplePayEnabled) { + NSError *error = [NSError errorWithDomain:BTApplePayErrorDomain + code:BTApplePayErrorTypeUnsupported + userInfo:@{ NSLocalizedDescriptionKey: @"Apple Pay is not enabled for this merchant. Please ensure that Apple Pay is enabled in the control panel and then try saving an Apple Pay payment method again." }]; + [self invokeBlock:completion onMainThreadWithPaymentRequest:nil error:error]; + [self.apiClient sendAnalyticsEvent:@"ios.apple-pay.error.disabled"]; + return; + } + + PKPaymentRequest *paymentRequest = [[PKPaymentRequest alloc] init]; + paymentRequest.countryCode = configuration.applePayCountryCode; + paymentRequest.currencyCode = configuration.applePayCurrencyCode; + paymentRequest.merchantIdentifier = configuration.applePayMerchantIdentifier; + paymentRequest.supportedNetworks = configuration.applePaySupportedNetworks; + + [self invokeBlock:completion onMainThreadWithPaymentRequest:paymentRequest error:nil]; + }]; +} + +- (void)tokenizeApplePayPayment:(PKPayment *)payment completion:(void (^)(BTApplePayCardNonce *, NSError *))completionBlock { + if (!self.apiClient) { + NSError *error = [NSError errorWithDomain:BTApplePayErrorDomain + code:BTApplePayErrorTypeIntegration + userInfo:@{NSLocalizedDescriptionKey: @"BTApplePayClient tokenization failed because BTAPIClient is nil."}]; + completionBlock(nil, error); + return; + } + + [self.apiClient sendAnalyticsEvent:@"ios.apple-pay.start"]; + + if (!payment) { + NSError *error = [NSError errorWithDomain:BTApplePayErrorDomain + code:BTApplePayErrorTypeUnsupported + userInfo:@{NSLocalizedDescriptionKey: @"A valid PKPayment is required."}]; + completionBlock(nil, error); + [self.apiClient sendAnalyticsEvent:@"ios.apple-pay.error.invalid-payment"]; + return; + } + + [self.apiClient fetchOrReturnRemoteConfiguration:^(BTConfiguration *configuration, NSError *error) { + if (error) { + [self.apiClient sendAnalyticsEvent:@"ios.apple-pay.error.configuration"]; + completionBlock(nil, error); + return; + } + + if (![configuration.json[@"applePay"][@"status"] isString] || + [[configuration.json[@"applePay"][@"status"] asString] isEqualToString:@"off"]) { + NSError *error = [NSError errorWithDomain:BTApplePayErrorDomain + code:BTApplePayErrorTypeUnsupported + userInfo:@{ NSLocalizedDescriptionKey: @"Apple Pay is not enabled for this merchant. Please ensure that Apple Pay is enabled in the control panel and then try saving an Apple Pay payment method again." }]; + completionBlock(nil, error); + [self.apiClient sendAnalyticsEvent:@"ios.apple-pay.error.disabled"]; + return; + } + + NSMutableDictionary *parameters = [NSMutableDictionary new]; + parameters[@"applePaymentToken"] = [self parametersForPaymentToken:payment.token]; + parameters[@"_meta"] = @{ + @"source" : self.apiClient.metadata.sourceString, + @"integration" : self.apiClient.metadata.integrationString, + @"sessionId" : self.apiClient.metadata.sessionId, + }; + + [self.apiClient POST:@"v1/payment_methods/apple_payment_tokens" + parameters:parameters + completion:^(BTJSON *body, __unused NSHTTPURLResponse *response, NSError *error) { + if (error) { + completionBlock(nil, error); + [self.apiClient sendAnalyticsEvent:@"ios.apple-pay.error.tokenization"]; + return; + } + + BTJSON *applePayCard = body[@"applePayCards"][0]; + NSString *cardType = applePayCard[@"details"][@"cardType"] ? [applePayCard[@"details"][@"cardType"] asString] : @"ApplePayCard"; + BTApplePayCardNonce *tokenized = [[BTApplePayCardNonce alloc] initWithNonce:[applePayCard[@"nonce"] asString] localizedDescription:[applePayCard[@"description"] asString] type:cardType json:applePayCard]; + + completionBlock(tokenized, nil); + [self.apiClient sendAnalyticsEvent:@"ios.apple-pay.success"]; + }]; + }]; +} + +#pragma mark - Helpers + +- (NSDictionary *)parametersForPaymentToken:(PKPaymentToken *)token NS_AVAILABLE_IOS(8_0) { + NSMutableDictionary *mutableParameters = [NSMutableDictionary dictionary]; + + mutableParameters[@"paymentData"] = [token.paymentData base64EncodedStringWithOptions:0]; + mutableParameters[@"transactionIdentifier"] = token.transactionIdentifier; + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 9.0, watchOS 3.0, *)) { +#else + if ([PKPaymentMethod class]) { +#endif + mutableParameters[@"paymentInstrumentName"] = token.paymentMethod.displayName; + mutableParameters[@"paymentNetwork"] = token.paymentMethod.network; + } else { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 8.0, *)) { +#endif + mutableParameters[@"paymentInstrumentName"] = token.paymentInstrumentName; + mutableParameters[@"paymentNetwork"] = token.paymentNetwork; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + } +#endif +#pragma clang diagnostic pop + } + + return [mutableParameters copy]; +} + +- (void)invokeBlock:(nonnull void (^)(PKPaymentRequest * _Nullable, NSError * _Nullable))completion onMainThreadWithPaymentRequest:(nullable PKPaymentRequest *)paymentRequest error:(nullable NSError *)error NS_AVAILABLE_IOS(8_0) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(paymentRequest, error); + }); +} + +@end diff --git a/Pods/Braintree/BraintreeApplePay/BTApplePayClient_Internal.h b/Pods/Braintree/BraintreeApplePay/BTApplePayClient_Internal.h new file mode 100644 index 0000000..a27e3d6 --- /dev/null +++ b/Pods/Braintree/BraintreeApplePay/BTApplePayClient_Internal.h @@ -0,0 +1,9 @@ +#import "BTApplePayClient.h" + +@interface BTApplePayClient () +/** + @brief Exposed for testing to get the instance of BTAPIClient +*/ +@property (nonatomic, strong) BTAPIClient *apiClient; + +@end diff --git a/Pods/Braintree/BraintreeApplePay/BTConfiguration+ApplePay.m b/Pods/Braintree/BraintreeApplePay/BTConfiguration+ApplePay.m new file mode 100644 index 0000000..ddecf55 --- /dev/null +++ b/Pods/Braintree/BraintreeApplePay/BTConfiguration+ApplePay.m @@ -0,0 +1,71 @@ +#import "BTConfiguration+ApplePay.h" +#import + +@implementation BTConfiguration (ApplePay) + +- (BOOL)isApplePayEnabled { + BTJSON *applePayConfiguration = self.json[@"applePay"]; + return [applePayConfiguration[@"status"] isString] && ![[applePayConfiguration[@"status"] asString] isEqualToString:@"off"]; +} + +- (BOOL)canMakeApplePayPayments { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 8.0, watchOS 3.0, *)) { +#endif + return [PKPaymentAuthorizationViewController canMakePaymentsUsingNetworks:self.applePaySupportedNetworks]; + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + } else { + return NO; + } +#endif +} + +- (NSString *)applePayCountryCode { + return [self.json[@"applePay"][@"countryCode"] asString]; +} + +- (NSString *)applePayCurrencyCode { + return [self.json[@"applePay"][@"currencyCode"] asString]; +} + +- (NSString *)applePayMerchantIdentifier { + return [self.json[@"applePay"][@"merchantIdentifier"] asString]; +} + +- (NSArray *)applePaySupportedNetworks { + NSArray *gatewaySupportedNetworks = [self.json[@"applePay"][@"supportedNetworks"] asStringArray]; + + NSMutableArray *supportedNetworks = [NSMutableArray new]; + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 8.0, watchOS 3.0, *)) { +#endif + for (NSString *gatewaySupportedNetwork in gatewaySupportedNetworks) { + if ([gatewaySupportedNetwork localizedCaseInsensitiveCompare:@"visa"] == NSOrderedSame) { + [supportedNetworks addObject:PKPaymentNetworkVisa]; + } else if ([gatewaySupportedNetwork localizedCaseInsensitiveCompare:@"mastercard"] == NSOrderedSame) { + [supportedNetworks addObject:PKPaymentNetworkMasterCard]; + } else if ([gatewaySupportedNetwork localizedCaseInsensitiveCompare:@"amex"] == NSOrderedSame) { + [supportedNetworks addObject:PKPaymentNetworkAmex]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + } else if ([gatewaySupportedNetwork localizedCaseInsensitiveCompare:@"discover"] == NSOrderedSame) { + if (@available(iOS 9.0, watchOS 3.0, *)) { + [supportedNetworks addObject:PKPaymentNetworkDiscover]; + } + } +#else + } else if (&PKPaymentNetworkDiscover != NULL && [gatewaySupportedNetwork localizedCaseInsensitiveCompare:@"discover"] == NSOrderedSame) { // Very important to check that this constant is available first! + [supportedNetworks addObject:PKPaymentNetworkDiscover]; + } +#endif + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + } +#endif + } + + return [supportedNetworks copy]; +} + +@end diff --git a/Pods/Braintree/BraintreeApplePay/Public/BTApplePayCardNonce.h b/Pods/Braintree/BraintreeApplePay/Public/BTApplePayCardNonce.h new file mode 100644 index 0000000..53c8959 --- /dev/null +++ b/Pods/Braintree/BraintreeApplePay/Public/BTApplePayCardNonce.h @@ -0,0 +1,21 @@ +#import +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface BTApplePayCardNonce : BTPaymentMethodNonce + +/** + @brief The BIN data for the card number associated with this nonce. + */ +@property (nonatomic, readonly, strong) BTBinData *binData; + +- (nullable instancetype)initWithNonce:(NSString *)nonce localizedDescription:(nullable NSString *)description type:(NSString *)type json:(BTJSON *)json; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeApplePay/Public/BTApplePayClient.h b/Pods/Braintree/BraintreeApplePay/Public/BTApplePayClient.h new file mode 100644 index 0000000..333beec --- /dev/null +++ b/Pods/Braintree/BraintreeApplePay/Public/BTApplePayClient.h @@ -0,0 +1,57 @@ +#import +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif + +#import "BTApplePayCardNonce.h" + +NS_ASSUME_NONNULL_BEGIN + +extern NSString * const BTApplePayErrorDomain; +typedef NS_ENUM(NSInteger, BTApplePayErrorType) { + BTApplePayErrorTypeUnknown = 0, + + /// Apple Pay is disabled in the Braintree Control Panel + BTApplePayErrorTypeUnsupported, + + /// Braintree SDK is integrated incorrectly + BTApplePayErrorTypeIntegration, +}; + +@interface BTApplePayClient : NSObject + +/** + @brief Creates an Apple Pay client. + + @param apiClient An API client +*/ +- (instancetype)initWithAPIClient:(BTAPIClient *)apiClient NS_DESIGNATED_INITIALIZER; + + +- (instancetype)init __attribute__((unavailable("Please use initWithAPIClient:"))); + +/** + @brief Creates a `PKPaymentRequest` with values from your Braintree Apple Pay configuration. + + @discussion It populates the following values of `PKPaymentRequest`: `countryCode`, `currencyCode`, `merchantIdentifier`, `supportedNetworks`. + + @param completion A completion block that returns the payment request or an error. This block is invoked on the main thread. +*/ +- (void)paymentRequest:(void (^)(PKPaymentRequest * _Nullable paymentRequest, NSError * _Nullable error))completion NS_AVAILABLE_IOS(8_0); + +/** + @brief Tokenizes an Apple Pay payment. + + @param payment A `PKPayment` instance, typically obtained by presenting a `PKPaymentAuthorizationViewController` + @param completionBlock A completion block that is invoked when tokenization has completed. If tokenization succeeds, + `tokenizedApplePayPayment` will contain a nonce and `error` will be `nil`; if it fails, + `tokenizedApplePayPayment` will be `nil` and `error` will describe the failure. +*/ +- (void)tokenizeApplePayPayment:(PKPayment *)payment + completion:(void (^)(BTApplePayCardNonce * _Nullable tokenizedApplePayPayment, NSError * _Nullable error))completionBlock NS_AVAILABLE_IOS(8_0); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeApplePay/Public/BTConfiguration+ApplePay.h b/Pods/Braintree/BraintreeApplePay/Public/BTConfiguration+ApplePay.h new file mode 100644 index 0000000..934f381 --- /dev/null +++ b/Pods/Braintree/BraintreeApplePay/Public/BTConfiguration+ApplePay.h @@ -0,0 +1,40 @@ +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif +#import + +@interface BTConfiguration (ApplePay) + +/** + @brief Indicates whether Apple Pay is enabled for your merchant account. +*/ +@property (nonatomic, readonly, assign) BOOL isApplePayEnabled; + +/** + @brief The Apple Pay payment networks supported by your Braintree merchant account. +*/ +@property (nonatomic, readonly, nullable) NSArray *applePaySupportedNetworks; + +/** + @brief Indicates if the Apple Pay merchant enabled payment networks are supported on this device. +*/ +@property (nonatomic, readonly, assign) BOOL canMakeApplePayPayments; + +/** + @brief The country code for your Braintree merchant account. +*/ +@property (nonatomic, readonly, nullable) NSString *applePayCountryCode; + +/** + @brief The Apple Pay currency code supported by your Braintree merchant account. +*/ +@property (nonatomic, readonly, nullable) NSString *applePayCurrencyCode; + +/** + @brief The Apple Pay merchant identifier associated with your Braintree merchant account. +*/ +@property (nonatomic, readonly, nullable) NSString *applePayMerchantIdentifier; + +@end diff --git a/Pods/Braintree/BraintreeApplePay/Public/BraintreeApplePay.h b/Pods/Braintree/BraintreeApplePay/Public/BraintreeApplePay.h new file mode 100644 index 0000000..58e5beb --- /dev/null +++ b/Pods/Braintree/BraintreeApplePay/Public/BraintreeApplePay.h @@ -0,0 +1,14 @@ +#import + +FOUNDATION_EXPORT double BraintreeApplePayVersionNumber; + +FOUNDATION_EXPORT const unsigned char BraintreeApplePayVersionString[]; + +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif +#import "BTApplePayClient.h" +#import "BTConfiguration+ApplePay.h" +#import "BTApplePayCardNonce.h" diff --git a/Pods/Braintree/BraintreeCard/BTCard.m b/Pods/Braintree/BraintreeCard/BTCard.m new file mode 100644 index 0000000..c8016e1 --- /dev/null +++ b/Pods/Braintree/BraintreeCard/BTCard.m @@ -0,0 +1,141 @@ +#import "BTCard_Internal.h" +#import "BTJSON.h" + +@interface BTCard () +@property (nonatomic, strong) NSMutableDictionary *mutableParameters; +@end + +@implementation BTCard + +- (instancetype)init { + return [self initWithParameters:@{}]; +} + +- (nonnull instancetype)initWithParameters:(NSDictionary *)parameters { + if (self = [super init]) { + _mutableParameters = [parameters mutableCopy]; + _number = parameters[@"number"]; + NSArray *components = [parameters[@"expiration_date"] componentsSeparatedByString:@"/"]; + if (components.count == 2) { + _expirationMonth = components[0]; + _expirationYear = components[1]; + } + _postalCode = parameters[@"billing_address"][@"postal_code"]; + _cvv = parameters[@"cvv"]; + + _streetAddress = parameters[@"billing_address"][@"street_address"]; + _extendedAddress = parameters[@"billing_address"][@"extended_address"]; + _locality = parameters[@"billing_address"][@"locality"]; + _region = parameters[@"billing_address"][@"region"]; + _countryName = parameters[@"billing_address"][@"country_name"]; + _countryCodeAlpha2 = parameters[@"billing_address"][@"country_code_alpha2"]; + _countryCodeAlpha3 = parameters[@"billing_address"][@"country_code_alpha3"]; + _countryCodeNumeric = parameters[@"billing_address"][@"country_code_numeric"]; + _cardholderName = parameters[@"cardholder_name"]; + _firstName = parameters[@"billing_address"][@"first_name"]; + _lastName = parameters[@"billing_address"][@"last_name"]; + _company = parameters[@"billing_address"][@"company"]; + + _shouldValidate = [parameters[@"options"][@"validate"] boolValue]; + } + return self; +} + +- (instancetype)initWithNumber:(NSString *)number + expirationMonth:(NSString *)expirationMonth + expirationYear:(NSString *)expirationYear + cvv:(NSString *)cvv +{ + if (self = [self initWithParameters:@{}]) { + _number = number; + _expirationMonth = expirationMonth; + _expirationYear = expirationYear; + _cvv = cvv; + } + return self; +} + +#pragma mark - + +- (NSDictionary *)parameters { + NSMutableDictionary *p = [self.mutableParameters mutableCopy]; + if (self.number) { + p[@"number"] = self.number; + } + if (self.expirationMonth && self.expirationYear) { + p[@"expiration_date"] = [NSString stringWithFormat:@"%@/%@", self.expirationMonth, self.expirationYear]; + } + if (self.cvv) { + p[@"cvv"] = self.cvv; + } + if (self.cardholderName) { + p[@"cardholder_name"] = self.cardholderName; + } + + NSMutableDictionary *billingAddressDictionary = [NSMutableDictionary new]; + if ([p[@"billing_address"] isKindOfClass:[NSDictionary class]]) { + [billingAddressDictionary addEntriesFromDictionary:p[@"billing_address"]]; + } + + if (self.firstName) { + billingAddressDictionary[@"first_name"] = self.firstName; + } + + if (self.lastName) { + billingAddressDictionary[@"last_name"] = self.lastName; + } + + if (self.company) { + billingAddressDictionary[@"company"] = self.company; + } + + if (self.postalCode) { + billingAddressDictionary[@"postal_code"] = self.postalCode; + } + + if (self.streetAddress) { + billingAddressDictionary[@"street_address"] = self.streetAddress; + } + + if (self.extendedAddress) { + billingAddressDictionary[@"extended_address"] = self.extendedAddress; + } + + if (self.locality) { + billingAddressDictionary[@"locality"] = self.locality; + } + + if (self.region) { + billingAddressDictionary[@"region"] = self.region; + } + + if (self.countryName) { + billingAddressDictionary[@"country_name"] = self.countryName; + } + + if (self.countryCodeAlpha2) { + billingAddressDictionary[@"country_code_alpha2"] = self.countryCodeAlpha2; + } + + if (self.countryCodeAlpha3) { + billingAddressDictionary[@"country_code_alpha3"] = self.countryCodeAlpha3; + } + + if (self.countryCodeNumeric) { + billingAddressDictionary[@"country_code_numeric"] = self.countryCodeNumeric; + } + + if (billingAddressDictionary.count > 0) { + p[@"billing_address"] = [billingAddressDictionary copy]; + } + + NSMutableDictionary *optionsDictionary = [NSMutableDictionary new]; + if ([p[@"options"] isKindOfClass:[NSDictionary class]]) { + [optionsDictionary addEntriesFromDictionary:p[@"options"]]; + } + optionsDictionary[@"validate"] = @(self.shouldValidate); + p[@"options"] = [optionsDictionary copy]; + return [p copy]; +} + +@end diff --git a/Pods/Braintree/BraintreeCard/BTCardClient.m b/Pods/Braintree/BraintreeCard/BTCardClient.m new file mode 100644 index 0000000..1d6691a --- /dev/null +++ b/Pods/Braintree/BraintreeCard/BTCardClient.m @@ -0,0 +1,163 @@ +#import "BTErrors.h" +#import "BTCardClient_Internal.h" +#import "BTCardNonce_Internal.h" +#import "BTCardRequest.h" +#import "BTClientMetadata.h" +#import "BTHTTP.h" +#import "BTJSON.h" +#import "BTPaymentMethodNonceParser.h" +#import "BTTokenizationService.h" +#if __has_include("BraintreeCore.h") +#import "BTAPIClient_Internal.h" +#import "BTCard_Internal.h" +#else +#import +#import +#endif + +NSString *const BTCardClientErrorDomain = @"com.braintreepayments.BTCardClientErrorDomain"; + +@interface BTCardClient () +@end + +@implementation BTCardClient + ++ (void)load { + if (self == [BTCardClient class]) { + [[BTTokenizationService sharedService] registerType:@"Card" withTokenizationBlock:^(BTAPIClient *apiClient, NSDictionary *options, void (^completionBlock)(BTPaymentMethodNonce *paymentMethodNonce, NSError *error)) { + BTCardClient *client = [[BTCardClient alloc] initWithAPIClient:apiClient]; + [client tokenizeCard:[[BTCard alloc] initWithParameters:options] completion:completionBlock]; + }]; + + [[BTPaymentMethodNonceParser sharedParser] registerType:@"CreditCard" withParsingBlock:^BTPaymentMethodNonce * _Nullable(BTJSON * _Nonnull creditCard) { + return [BTCardNonce cardNonceWithJSON:creditCard]; + }]; + } +} + +- (instancetype)initWithAPIClient:(BTAPIClient *)apiClient { + if (!apiClient) { + return nil; + } + if (self = [super init]) { + self.apiClient = apiClient; + } + return self; +} + +- (instancetype)init { + return nil; +} + +- (void)tokenizeCard:(BTCard *)card completion:(void (^)(BTCardNonce *tokenizedCard, NSError *error))completion { + BTCardRequest *request = [[BTCardRequest alloc] initWithCard:card]; + [self tokenizeCard:request options:nil completion:completion]; +} + + +- (void)tokenizeCard:(BTCardRequest *)request options:(NSDictionary *)options completion:(void (^)(BTCardNonce * _Nullable, NSError * _Nullable))completionBlock +{ + if (!self.apiClient) { + NSError *error = [NSError errorWithDomain:BTCardClientErrorDomain + code:BTCardClientErrorTypeIntegration + userInfo:@{NSLocalizedDescriptionKey: @"BTCardClient tokenization failed because BTAPIClient is nil."}]; + completionBlock(nil, error); + return; + } + + NSMutableDictionary *parameters = [NSMutableDictionary new]; + if (request.card.parameters) { + NSMutableDictionary *mutableCardParameters = [request.card.parameters mutableCopy]; + + if (request.enrollmentID) { + // Convert the immutable options dictionary so to write to it without overwriting any existing options + NSMutableDictionary *unionPayEnrollment = [NSMutableDictionary new]; + unionPayEnrollment[@"id"] = request.enrollmentID; + if (request.smsCode) { + unionPayEnrollment[@"sms_code"] = request.smsCode; + } + mutableCardParameters[@"options"] = [mutableCardParameters[@"options"] mutableCopy]; + mutableCardParameters[@"options"][@"union_pay_enrollment"] = unionPayEnrollment; + } + + parameters[@"credit_card"] = [mutableCardParameters copy]; + } + parameters[@"_meta"] = @{ + @"source" : self.apiClient.metadata.sourceString, + @"integration" : self.apiClient.metadata.integrationString, + @"sessionId" : self.apiClient.metadata.sessionId, + }; + if (options) { + parameters[@"options"] = options; + } + [self.apiClient POST:@"v1/payment_methods/credit_cards" + parameters:parameters + completion:^(BTJSON *body, __unused NSHTTPURLResponse *response, NSError *error) + { + if (error != nil) { + NSHTTPURLResponse *response = error.userInfo[BTHTTPURLResponseKey]; + NSError *callbackError = error; + + if (response.statusCode == 422) { + callbackError = [NSError errorWithDomain:BTCardClientErrorDomain + code:BTCardClientErrorTypeCustomerInputInvalid + userInfo:[self.class validationErrorUserInfo:error.userInfo]]; + } + + if (request.enrollmentID) { + [self sendUnionPayAnalyticsEvent:NO]; + } else { + [self sendAnalyticsEventWithSuccess:NO]; + } + + completionBlock(nil, callbackError); + return; + } + + BTJSON *cardJSON = body[@"creditCards"][0]; + + if (request.enrollmentID) { + [self sendUnionPayAnalyticsEvent:!cardJSON.isError]; + } else { + [self sendAnalyticsEventWithSuccess:!cardJSON.isError]; + } + + // cardNonceWithJSON returns nil when cardJSON is nil, cardJSON.asError is nil when cardJSON is non-nil + completionBlock([BTCardNonce cardNonceWithJSON:cardJSON], cardJSON.asError); + }]; +} + +#pragma mark - Analytics + +- (void)sendAnalyticsEventWithSuccess:(BOOL)success { + NSString *event = [NSString stringWithFormat:@"ios.%@.card.%@", self.apiClient.metadata.integrationString, success ? @"succeeded" : @"failed"]; + [self.apiClient sendAnalyticsEvent:event]; +} + +- (void)sendUnionPayAnalyticsEvent:(BOOL)success { + NSString *event = [NSString stringWithFormat:@"ios.%@.unionpay.nonce-%@", self.apiClient.metadata.integrationString, success ? @"received" : @"failed"]; + [self.apiClient sendAnalyticsEvent:event]; +} + +#pragma mark - Helpers + ++ (NSDictionary *)validationErrorUserInfo:(NSDictionary *)userInfo { + NSMutableDictionary *mutableUserInfo = [userInfo mutableCopy]; + BTJSON *jsonResponse = userInfo[BTHTTPJSONResponseBodyKey]; + if ([jsonResponse asDictionary]) { + mutableUserInfo[BTCustomerInputBraintreeValidationErrorsKey] = [jsonResponse asDictionary]; + + BTJSON *fieldError = [[jsonResponse[@"fieldErrors"] asArray] firstObject]; + NSString *errorMessage = [jsonResponse[@"error"][@"message"] asString]; + if (errorMessage) { + mutableUserInfo[NSLocalizedDescriptionKey] = errorMessage; + } + NSString *firstFieldErrorMessage = [fieldError[@"fieldErrors"] firstObject][@"message"]; + if (firstFieldErrorMessage) { + mutableUserInfo[NSLocalizedFailureReasonErrorKey] = firstFieldErrorMessage; + } + } + return [mutableUserInfo copy]; +} + +@end diff --git a/Pods/Braintree/BraintreeCard/BTCardClient_Internal.h b/Pods/Braintree/BraintreeCard/BTCardClient_Internal.h new file mode 100644 index 0000000..ff17858 --- /dev/null +++ b/Pods/Braintree/BraintreeCard/BTCardClient_Internal.h @@ -0,0 +1,19 @@ +#import "BTCardClient.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface BTCardClient () + +/** + @brief Exposed for testing to get the instance of BTAPIClient +*/ +@property (nonatomic, strong, readwrite) BTAPIClient *apiClient; + +/** + @brief Convenience helper method for creating friendlier, more human-readable userInfo dictionaries for 422 HTTP errors +*/ ++ (NSDictionary *)validationErrorUserInfo:(NSDictionary *)userInfo; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCard/BTCardNonce.m b/Pods/Braintree/BraintreeCard/BTCardNonce.m new file mode 100644 index 0000000..e4938be --- /dev/null +++ b/Pods/Braintree/BraintreeCard/BTCardNonce.m @@ -0,0 +1,78 @@ +#import "BTCardNonce_Internal.h" + +@implementation BTCardNonce + +- (instancetype)initWithNonce:(NSString *)nonce + description:(NSString *)description + cardNetwork:(BTCardNetwork)cardNetwork + lastTwo:(NSString *)lastTwo + isDefault:(BOOL)isDefault + cardJSON:(BTJSON *)cardJSON +{ + self = [super initWithNonce:nonce localizedDescription:description type:[BTCardNonce stringFromCardNetwork:cardNetwork] isDefault:isDefault]; + if (self) { + _cardNetwork = cardNetwork; + _lastTwo = lastTwo; + _binData = [[BTBinData alloc] initWithJSON:cardJSON[@"binData"]]; + } + return self; +} + ++ (NSString *)stringFromCardNetwork:(BTCardNetwork)cardNetwork { + switch (cardNetwork) { + case BTCardNetworkAMEX: + return @"AMEX"; + case BTCardNetworkDinersClub: + return @"DinersClub"; + case BTCardNetworkDiscover: + return @"Discover"; + case BTCardNetworkMasterCard: + return @"MasterCard"; + case BTCardNetworkVisa: + return @"Visa"; + case BTCardNetworkJCB: + return @"JCB"; + case BTCardNetworkLaser: + return @"Laser"; + case BTCardNetworkMaestro: + return @"Maestro"; + case BTCardNetworkUnionPay: + return @"UnionPay"; + case BTCardNetworkSolo: + return @"Solo"; + case BTCardNetworkSwitch: + return @"Switch"; + case BTCardNetworkUKMaestro: + return @"UKMaestro"; + case BTCardNetworkUnknown: + default: + return @"Unknown"; + } +} + ++ (instancetype)cardNonceWithJSON:(BTJSON *)cardJSON { + // Normalize the card network string in cardJSON to be lowercase so that our enum mapping is case insensitive + BTJSON *cardType = [[BTJSON alloc] initWithValue:[cardJSON[@"details"][@"cardType"] asString].lowercaseString]; + return [[[self class] alloc] initWithNonce:[cardJSON[@"nonce"] asString] + description:[cardJSON[@"description"] asString] + cardNetwork:[cardType asEnum:@{ + @"american express": @(BTCardNetworkAMEX), + @"diners club": @(BTCardNetworkDinersClub), + @"unionpay": @(BTCardNetworkUnionPay), + @"discover": @(BTCardNetworkDiscover), + @"maestro": @(BTCardNetworkMaestro), + @"mastercard": @(BTCardNetworkMasterCard), + @"jcb": @(BTCardNetworkJCB), + @"laser": @(BTCardNetworkLaser), + @"solo": @(BTCardNetworkSolo), + @"switch": @(BTCardNetworkSwitch), + @"uk maestro": @(BTCardNetworkUKMaestro), + @"visa": @(BTCardNetworkVisa),} + orDefault:BTCardNetworkUnknown] + lastTwo:[cardJSON[@"details"][@"lastTwo"] asString] + isDefault:[cardJSON[@"default"] isTrue] + cardJSON:cardJSON]; + +} + +@end diff --git a/Pods/Braintree/BraintreeCard/BTCardNonce_Internal.h b/Pods/Braintree/BraintreeCard/BTCardNonce_Internal.h new file mode 100644 index 0000000..228f01c --- /dev/null +++ b/Pods/Braintree/BraintreeCard/BTCardNonce_Internal.h @@ -0,0 +1,17 @@ +#import "BTCardNonce.h" +#import "BTJSON.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface BTCardNonce () + +- (instancetype)initWithNonce:(nonnull NSString *)nonce + description:(nullable NSString *)description + cardNetwork:(BTCardNetwork)cardNetwork + lastTwo:(nullable NSString *)lastTwo + isDefault:(BOOL)isDefault + cardJSON:(BTJSON *)cardJSON; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCard/BTCardRequest.m b/Pods/Braintree/BraintreeCard/BTCardRequest.m new file mode 100644 index 0000000..03d8ed0 --- /dev/null +++ b/Pods/Braintree/BraintreeCard/BTCardRequest.m @@ -0,0 +1,15 @@ +#import "BTCardRequest.h" + +@implementation BTCardRequest + +- (instancetype)initWithCard:(BTCard *)card { + if (!card) { + return nil; + } + if (self = [super init]) { + _card = card; + } + return self; +} + +@end diff --git a/Pods/Braintree/BraintreeCard/BTCard_Internal.h b/Pods/Braintree/BraintreeCard/BTCard_Internal.h new file mode 100644 index 0000000..d2f921f --- /dev/null +++ b/Pods/Braintree/BraintreeCard/BTCard_Internal.h @@ -0,0 +1,8 @@ +#import "BTCard.h" +#import "BTJSON.h" + +@interface BTCard () + +- (NSDictionary *)parameters; + +@end diff --git a/Pods/Braintree/BraintreeCard/Public/BTCard.h b/Pods/Braintree/BraintreeCard/Public/BTCard.h new file mode 100644 index 0000000..75bf25e --- /dev/null +++ b/Pods/Braintree/BraintreeCard/Public/BTCard.h @@ -0,0 +1,128 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + @class BTCard + @discussion The card tokenization request represents raw credit or debit card data provided by the customer. Its main purpose is to serve as the input for tokenization. +*/ +@interface BTCard : NSObject + +/** + @brief A convenience initializer for creating a card tokenization request. +*/ +- (instancetype)initWithNumber:(NSString *)number + expirationMonth:(NSString *)expirationMonth + expirationYear:(NSString *)expirationYear + cvv:(nullable NSString *)cvv; + +- (instancetype)initWithParameters:(NSDictionary *)parameters NS_DESIGNATED_INITIALIZER; + +/** + @brief The card number +*/ +@property (nonatomic, nullable, copy) NSString *number; + +/** + @brief The expiration month as a one or two-digit number on the Gregorian calendar +*/ +@property (nonatomic, nullable, copy) NSString *expirationMonth; + +/** + @brief The expiration year as a two or four-digit number on the Gregorian calendar +*/ +@property (nonatomic, nullable, copy) NSString *expirationYear; + +/** + @brief The card CVV +*/ +@property (nonatomic, nullable, copy) NSString *cvv; + +/** + @brief The postal code associated with the card's billing address +*/ + +@property (nonatomic, nullable, copy) NSString *postalCode; + +/** + @brief Optional: the cardholder's name. +*/ +@property (nonatomic, nullable, copy) NSString *cardholderName; + +/** + @brief Optional: first name on the card. + */ +@property (nonatomic, nullable, copy) NSString *firstName; + +/** + @brief Optional: last name on the card. + */ +@property (nonatomic, nullable, copy) NSString *lastName; + +/** + @brief Optional: company name associated with the card. + */ +@property (nonatomic, nullable, copy) NSString *company; + +/** + @brief Optional: the street address associated with the card's billing address +*/ +@property (nonatomic, nullable, copy) NSString *streetAddress; + +/** + @brief Optional: the extended address associated with the card's billing address + */ +@property (nonatomic, nullable, copy) NSString *extendedAddress; + +/** + @brief Optional: the city associated with the card's billing address +*/ +@property (nonatomic, nullable, copy) NSString *locality; + +/** + @brief Optional: the state/province associated with the card's billing address +*/ +@property (nonatomic, nullable, copy) NSString *region; + +/** + @brief Optional: the country name associated with the card's billing address. + + @note Braintree only accepts specific country names. + @see https://developers.braintreepayments.com/reference/general/countries#list-of-countries +*/ +@property (nonatomic, nullable, copy) NSString *countryName; + +/** + @brief Optional: the ISO 3166-1 alpha-2 country code specified in the card's billing address. + + @note Braintree only accepts specific alpha-2 values. + @see https://developers.braintreepayments.com/reference/general/countries#list-of-countries +*/ +@property (nonatomic, nullable, copy) NSString *countryCodeAlpha2; + +/** + @brief Optional: The ISO 3166-1 alpha-3 country code specified in the card's billing address. + + @note Braintree only accepts specific alpha-3 values. + @see https://developers.braintreepayments.com/reference/general/countries#list-of-countries + */ +@property (nonatomic, nullable, copy) NSString *countryCodeAlpha3; + +/** + @brief Optional: The ISO 3166-1 numeric country code specified in the card's billing address. + + @note Braintree only accepts specific numeric values. + @see https://developers.braintreepayments.com/reference/general/countries#list-of-countries + */ +@property (nonatomic, nullable, copy) NSString *countryCodeNumeric; + +/** + @brief Controls whether or not to return validations and/or verification results. By default, this is not enabled. + + @note Use this flag with caution. By enabling client-side validation, certain tokenize card requests may result in adding the card to the vault. These semantics are not currently documented. +*/ +@property (nonatomic, assign) BOOL shouldValidate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCard/Public/BTCardClient.h b/Pods/Braintree/BraintreeCard/Public/BTCardClient.h new file mode 100644 index 0000000..c52c15d --- /dev/null +++ b/Pods/Braintree/BraintreeCard/Public/BTCardClient.h @@ -0,0 +1,64 @@ +#import +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif +#import "BTCard.h" +#import "BTCardNonce.h" + +@class BTCardRequest; + +NS_ASSUME_NONNULL_BEGIN + +extern NSString * const BTCardClientErrorDomain; + +typedef NS_ENUM(NSInteger, BTCardClientErrorType) { + BTCardClientErrorTypeUnknown = 0, + + /// Braintree SDK is integrated incorrectly + BTCardClientErrorTypeIntegration, + + /// Payment option (e.g. UnionPay) is not enabled for this merchant account + BTCardClientErrorTypePaymentOptionNotEnabled, + + /// Customer provided invalid input + BTCardClientErrorTypeCustomerInputInvalid, +}; + +@interface BTCardClient : NSObject + +/** + @brief Creates a card client. + + @param apiClient An API client +*/ +- (instancetype)initWithAPIClient:(BTAPIClient *)apiClient NS_DESIGNATED_INITIALIZER; + +- (instancetype)init __attribute__((unavailable("Please use initWithAPIClient:"))); + +/** + @brief Tokenizes a card. + + @param card The card to tokenize. It must have a valid number and expiration date. + @param completion A completion block that is invoked when card tokenization has completed. If tokenization succeeds, + `tokenizedCard` will contain a nonce and `error` will be `nil`; if it fails, `tokenizedCard` will be `nil` and `error` + will describe the failure. +*/ +- (void)tokenizeCard:(BTCard *)card completion:(void (^)(BTCardNonce * _Nullable tokenizedCard, NSError * _Nullable error))completion; + +/** + @brief Tokenizes a card. + + @param request A card tokenization request that contains an enrolled card, the enrollment ID from `enrollUnionPayCard:completion:`, + and the enrollment auth code sent to the mobile phone number. + @param options A dictionary containing additional options to send when performing tokenization. Optional. + @param completion A completion block that is invoked when card tokenization has completed. If tokenization succeeds, `tokenizedCard` will contain a nonce and `error` will be `nil`; if it fails, `tokenizedCard` will be `nil` and `error` will describe the failure. +*/ +- (void)tokenizeCard:(BTCardRequest *)request + options:(nullable NSDictionary *)options + completion:(void (^)(BTCardNonce * _Nullable tokenizedCard, NSError * _Nullable error))completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCard/Public/BTCardNonce.h b/Pods/Braintree/BraintreeCard/Public/BTCardNonce.h new file mode 100644 index 0000000..fe309a2 --- /dev/null +++ b/Pods/Braintree/BraintreeCard/Public/BTCardNonce.h @@ -0,0 +1,36 @@ +#import +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface BTCardNonce : BTPaymentMethodNonce + +/** + @brief The card network. +*/ +@property (nonatomic, readonly, assign) BTCardNetwork cardNetwork; + +/** + @brief The last two digits of the card, if available. +*/ +@property (nonatomic, nullable, readonly, copy) NSString *lastTwo; + +/** + @brief The BIN data for the card number associated with this nonce. + */ +@property (nonatomic, readonly, strong) BTBinData *binData; + +#pragma mark - Internal + +/** + @brief Create a `BTCardNonce` object from JSON. +*/ ++ (instancetype)cardNonceWithJSON:(BTJSON *)cardJSON; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCard/Public/BTCardRequest.h b/Pods/Braintree/BraintreeCard/Public/BTCardRequest.h new file mode 100644 index 0000000..21499b0 --- /dev/null +++ b/Pods/Braintree/BraintreeCard/Public/BTCardRequest.h @@ -0,0 +1,37 @@ +#import "BTCard.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface BTCardRequest : NSObject + +- (instancetype)initWithCard:(BTCard *)card; + +@property (nonatomic, strong) BTCard *card; + +#pragma mark - UnionPay properties + +/** + @brief The mobile phone number to use to verify the enrollment via SMS. +*/ +@property (nonatomic, copy, nullable) NSString *mobilePhoneNumber; + +/** + @brief The country code for the mobile phone number. This string should only contain digits. + @note By default, this is set to 62. +*/ +@property (nonatomic, copy, nullable) NSString *mobileCountryCode; + +/** + @brief The enrollment verification code sent via SMS to the mobile phone number. The code is needed to tokenize a UnionPay card that requires enrollment. +*/ +@property (nonatomic, copy, nullable) NSString *smsCode; + +/** + @brief The UnionPay enrollment ID +*/ +@property (nonatomic, copy, nullable) NSString *enrollmentID; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCard/Public/BraintreeCard.h b/Pods/Braintree/BraintreeCard/Public/BraintreeCard.h new file mode 100644 index 0000000..f4160ef --- /dev/null +++ b/Pods/Braintree/BraintreeCard/Public/BraintreeCard.h @@ -0,0 +1,15 @@ +#import + +FOUNDATION_EXPORT double BraintreeCardVersionNumber; + +FOUNDATION_EXPORT const unsigned char BraintreeCardVersionString[]; + +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif +#import "BTCardClient.h" +#import "BTCard.h" +#import "BTCardNonce.h" +#import "BTCardRequest.h" diff --git a/Pods/Braintree/BraintreeCore/BTAPIClient.m b/Pods/Braintree/BraintreeCore/BTAPIClient.m new file mode 100644 index 0000000..536ed71 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTAPIClient.m @@ -0,0 +1,345 @@ +#import "BTAnalyticsMetadata.h" +#import "BTAnalyticsService.h" +#import "BTAPIClient_Internal.h" +#import "BTClientToken.h" +#import "BTLogger_Internal.h" +#import "BTPaymentMethodNonce.h" +#import "BTPaymentMethodNonceParser.h" + +NSString *const BTAPIClientErrorDomain = @"com.braintreepayments.BTAPIClientErrorDomain"; + +@interface BTAPIClient () +@property (nonatomic, strong) dispatch_queue_t configurationQueue; +@end + +@implementation BTAPIClient + +- (nullable instancetype)initWithAuthorization:(NSString *)authorization { + return [self initWithAuthorization:authorization sendAnalyticsEvent:YES]; +} + +- (nullable instancetype)initWithAuthorization:(NSString *)authorization sendAnalyticsEvent:(BOOL)sendAnalyticsEvent { + if(![authorization isKindOfClass:[NSString class]]) { + NSString *reason = @"BTClient could not initialize because the provided authorization was invalid"; + [[BTLogger sharedLogger] error:reason]; + return nil; + } + + if (self = [super init]) { + _metadata = [[BTClientMetadata alloc] init]; + _configurationQueue = dispatch_queue_create("com.braintreepayments.BTAPIClient", DISPATCH_QUEUE_SERIAL); + + NSRegularExpression *isTokenizationKeyRegExp = [NSRegularExpression regularExpressionWithPattern:@"^[a-zA-Z0-9]+_[a-zA-Z0-9]+_[a-zA-Z0-9_]+$" options:0 error:NULL]; + NSTextCheckingResult *tokenizationKeyMatch = [isTokenizationKeyRegExp firstMatchInString:authorization options:0 range: NSMakeRange(0, authorization.length)]; + + if (tokenizationKeyMatch) { + NSURL *baseURL = [BTAPIClient baseURLFromTokenizationKey:authorization]; + + if (!baseURL) { + NSString *reason = @"BTClient could not initialize because the provided tokenization key was invalid"; + [[BTLogger sharedLogger] error:reason]; + return nil; + } + + _tokenizationKey = authorization; + + _configurationHTTP = [[BTHTTP alloc] initWithBaseURL:baseURL tokenizationKey:authorization]; + + if (sendAnalyticsEvent) { + [self queueAnalyticsEvent:@"ios.started.client-key"]; + } + } else { + NSError *error; + _clientToken = [[BTClientToken alloc] initWithClientToken:authorization error:&error]; + if (error) { [[BTLogger sharedLogger] error:[error localizedDescription]]; } + if (!_clientToken) { + NSString *reason = @"BTClient could not initialize because the provided clientToken was invalid"; + [[BTLogger sharedLogger] error:reason]; + return nil; + } + + _configurationHTTP = [[BTHTTP alloc] initWithClientToken:self.clientToken]; + + if (sendAnalyticsEvent) { + [self queueAnalyticsEvent:@"ios.started.client-token"]; + } + } + + // BTHTTP's default NSURLSession does not cache responses, but we want the BTHTTP instance that fetches configuration to cache aggressively + NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; + static NSURLCache *configurationCache; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + configurationCache = [[NSURLCache alloc] initWithMemoryCapacity:1 * 1024 * 1024 diskCapacity:0 diskPath:nil]; + }); + configuration.URLCache = configurationCache; + configuration.requestCachePolicy = NSURLRequestReturnCacheDataElseLoad; + _configurationHTTP.session = [NSURLSession sessionWithConfiguration:configuration]; + + // Kickoff the background request to fetch the config + [self fetchOrReturnRemoteConfiguration:^(__unused BTConfiguration * _Nullable configuration, __unused NSError * _Nullable error) { + //noop + }]; + } + + return self; +} + +- (instancetype)copyWithSource:(BTClientMetadataSourceType)source + integration:(BTClientMetadataIntegrationType)integration +{ + BTAPIClient *copiedClient; + + if (self.clientToken) { + copiedClient = [[[self class] alloc] initWithAuthorization:self.clientToken.originalValue sendAnalyticsEvent:NO]; + } else if (self.tokenizationKey) { + copiedClient = [[[self class] alloc] initWithAuthorization:self.tokenizationKey sendAnalyticsEvent:NO]; + } else { + NSAssert(NO, @"Cannot copy an API client that does not specify a client token or tokenization key"); + } + + if (copiedClient) { + BTMutableClientMetadata *mutableMetadata = [self.metadata mutableCopy]; + mutableMetadata.source = source; + mutableMetadata.integration = integration; + copiedClient->_metadata = [mutableMetadata copy]; + } + + return copiedClient; +} + +#pragma mark - Base URL + +/// Gets base URL from tokenization key +/// +/// @param tokenizationKey The tokenization key +/// +/// @return Base URL for environment, or `nil` if tokenization key is invalid ++ (NSURL *)baseURLFromTokenizationKey:(NSString *)tokenizationKey { + NSRegularExpression *regExp = [NSRegularExpression regularExpressionWithPattern:@"([a-zA-Z0-9]+)_[a-zA-Z0-9]+_([a-zA-Z0-9_]+)" options:0 error:NULL]; + + NSArray *results = [regExp matchesInString:tokenizationKey options:0 range:NSMakeRange(0, tokenizationKey.length)]; + + if (results.count != 1 || [[results firstObject] numberOfRanges] != 3) { + return nil; + } + + NSString *environment = [tokenizationKey substringWithRange:[results[0] rangeAtIndex:1]]; + NSString *merchantID = [tokenizationKey substringWithRange:[results[0] rangeAtIndex:2]]; + + NSURLComponents *components = [[NSURLComponents alloc] init]; + components.scheme = [BTAPIClient schemeForEnvironmentString:environment]; + NSString *host = [BTAPIClient hostForEnvironmentString:environment]; + NSArray *hostComponents = [host componentsSeparatedByString:@":"]; + components.host = hostComponents[0]; + if (hostComponents.count > 1) { + NSString *portString = hostComponents[1]; + components.port = @(portString.integerValue); + } + components.path = [BTAPIClient clientApiBasePathForMerchantID:merchantID]; + if (!components.host || !components.path) { + return nil; + } + + return components.URL; +} + ++ (NSString *)schemeForEnvironmentString:(NSString *)environment { + if ([[environment lowercaseString] isEqualToString:@"development"]) { + return @"http"; + } + return @"https"; +} + ++ (NSString *)hostForEnvironmentString:(NSString *)environment { + if ([[environment lowercaseString] isEqualToString:@"sandbox"]) { + return @"sandbox.braintreegateway.com"; + } else if ([[environment lowercaseString] isEqualToString:@"production"]) { + return @"api.braintreegateway.com:443"; + } else if ([[environment lowercaseString] isEqualToString:@"development"]) { + return @"localhost:3000"; + } else { + return nil; + } +} + ++ (NSString *)clientApiBasePathForMerchantID:(NSString *)merchantID { + if (merchantID.length == 0) { + return nil; + } + + return [NSString stringWithFormat:@"/merchants/%@/client_api", merchantID]; +} + +# pragma mark - Payment Methods + +- (void)fetchPaymentMethodNonces:(void (^)(NSArray *, NSError *))completion { + [self fetchPaymentMethodNonces:NO completion:completion]; +} + +- (void)fetchPaymentMethodNonces:(BOOL)defaultFirst completion:(void (^)(NSArray *, NSError *))completion { + if (!self.clientToken) { + NSError *error = [NSError errorWithDomain:BTAPIClientErrorDomain code:BTAPIClientErrorTypeNotAuthorized userInfo:@{ NSLocalizedDescriptionKey : @"Cannot fetch payment method nonces with a tokenization key", NSLocalizedRecoverySuggestionErrorKey : @"This endpoint requires a client token for authorization"}]; + if (completion) { + completion(nil, error); + } + return; + } + + NSString *defaultFirstValue = defaultFirst ? @"true" : @"false"; + + [self GET:@"v1/payment_methods" + parameters:@{@"default_first": defaultFirstValue, + @"session_id": self.metadata.sessionId} + completion:^(BTJSON * _Nullable body, __unused NSHTTPURLResponse * _Nullable response, NSError * _Nullable error) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (completion) { + if (error) { + completion(nil, error); + } else { + NSMutableArray *paymentMethodNonces = [NSMutableArray array]; + for (NSDictionary *paymentInfo in [body[@"paymentMethods"] asArray]) { + BTJSON *paymentInfoJSON = [[BTJSON alloc] initWithValue:paymentInfo]; + BTPaymentMethodNonce *paymentMethodNonce = [[BTPaymentMethodNonceParser sharedParser] parseJSON:paymentInfoJSON withParsingBlockForType:[paymentInfoJSON[@"type"] asString]]; + if (paymentMethodNonce) { + [paymentMethodNonces addObject:paymentMethodNonce]; + } + } + completion(paymentMethodNonces, nil); + } + } + }); + }]; +} + +#pragma mark - Remote Configuration + +- (void)fetchOrReturnRemoteConfiguration:(void (^)(BTConfiguration *, NSError *))completionBlock { + // Guarantee that multiple calls to this method will successfully obtain configuration exactly once. + // + // Rules: + // - If cachedConfiguration is present, return it without a request + // - If cachedConfiguration is not present, fetch it and cache the succesful response + // - If fetching fails, return error and the next queued will try to fetch again + // + // Note: Configuration queue is SERIAL. This helps ensure that each request for configuration + // is processed independently. Thus, the check for cached configuration and the fetch is an + // atomic operation with respect to other calls to this method. + // + // Note: Uses dispatch_semaphore to block the configuration queue when the configuration fetch + // request is waiting to return. In this context, it is OK to block, as the configuration + // queue is a background queue to guarantee atomic access to the remote configuration resource. + dispatch_async(self.configurationQueue, ^{ + __block NSError *fetchError; + + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + __block BTConfiguration *configuration; + NSString *configPath = self.tokenizationKey ? @"v1/configuration" : [self.clientToken.configURL absoluteString]; + [self.configurationHTTP GET:configPath parameters:@{ @"configVersion": @"3" } completion:^(BTJSON * _Nullable body, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error) { + if (error) { + fetchError = error; + } else if (response.statusCode != 200) { + NSError *configurationDomainError = + [NSError errorWithDomain:BTAPIClientErrorDomain + code:BTAPIClientErrorTypeConfigurationUnavailable + userInfo:@{ + NSLocalizedFailureReasonErrorKey: @"Unable to fetch remote configuration from Braintree API at this time." + }]; + fetchError = configurationDomainError; + } else { + configuration = [[BTConfiguration alloc] initWithJSON:body]; + if (!_http) { + NSURL *baseURL = [configuration.json[@"clientApiUrl"] asURL]; + if (self.clientToken) { + _http = [[BTHTTP alloc] initWithBaseURL:baseURL authorizationFingerprint:self.clientToken.authorizationFingerprint]; + } else if (self.tokenizationKey) { + _http = [[BTHTTP alloc] initWithBaseURL:baseURL tokenizationKey:self.tokenizationKey]; + } + } + } + + // Important: Unlock semaphore in all cases + dispatch_semaphore_signal(semaphore); + }]; + + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + + dispatch_async(dispatch_get_main_queue(), ^{ + completionBlock(configuration, fetchError); + }); + }); +} + +#pragma mark - Analytics + +/// By default, the `BTAnalyticsService` instance is static/shared so that only one queue of events exists. +/// The "singleton" is managed here because the analytics service depends on `BTAPIClient`. +- (BTAnalyticsService *)analyticsService { + static BTAnalyticsService *analyticsService; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + analyticsService = [[BTAnalyticsService alloc] initWithAPIClient:self]; + analyticsService.flushThreshold = 5; + }); + + // The analytics service may be overridden by unit tests. In that case, return the ivar and not the singleton + if (_analyticsService) return _analyticsService; + + return analyticsService; +} + +- (void)sendAnalyticsEvent:(NSString *)eventKind { + [self.analyticsService sendAnalyticsEvent:eventKind completion:nil]; +} + +- (void)queueAnalyticsEvent:(NSString *)eventKind { + [self.analyticsService sendAnalyticsEvent:eventKind]; +} + +- (NSDictionary *)metaParameters { + NSMutableDictionary *metaParameters = [NSMutableDictionary dictionaryWithDictionary:self.metadata.parameters]; + [metaParameters addEntriesFromDictionary:[BTAnalyticsMetadata metadata]]; + + return [metaParameters copy]; +} + +#pragma mark - HTTP Operations + +- (void)GET:(NSString *)endpoint parameters:(NSDictionary *)parameters completion:(void(^)(BTJSON *body, NSHTTPURLResponse *response, NSError *error))completionBlock { + [self fetchOrReturnRemoteConfiguration:^(__unused BTConfiguration * _Nullable configuration, __unused NSError * _Nullable error) { + if (error != nil) { + completionBlock(nil, nil, error); + return; + } + + [self.http GET:endpoint parameters:parameters completion:completionBlock]; + }]; +} + +- (void)POST:(NSString *)endpoint parameters:(NSDictionary *)parameters completion:(void(^)(BTJSON *body, NSHTTPURLResponse *response, NSError *error))completionBlock { + [self fetchOrReturnRemoteConfiguration:^(__unused BTConfiguration * _Nullable configuration, __unused NSError * _Nullable error) { + if (error != nil) { + completionBlock(nil, nil, error); + return; + } + + NSMutableDictionary *mutableParameters = [NSMutableDictionary dictionary]; + mutableParameters[@"_meta"] = [self metaParameters]; + [mutableParameters addEntriesFromDictionary:parameters]; + [self.http POST:endpoint parameters:mutableParameters completion:completionBlock]; + }]; +} + +- (instancetype)init NS_UNAVAILABLE +{ + return nil; +} + +- (void)dealloc +{ + if (self.http && self.http.session) { + [self.http.session finishTasksAndInvalidate]; + } +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTAPIClient_Internal.h b/Pods/Braintree/BraintreeCore/BTAPIClient_Internal.h new file mode 100644 index 0000000..5e7c050 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTAPIClient_Internal.h @@ -0,0 +1,47 @@ +#import "BTAnalyticsService.h" +#import "BTAPIClient.h" +#import "BTClientMetadata.h" +#import "BTClientToken.h" +#import "BTHTTP.h" +#import "BTJSON.h" + +NS_ASSUME_NONNULL_BEGIN + +@class BTPaymentMethodNonce; + +@interface BTAPIClient () + +@property (nonatomic, copy, nullable) NSString *tokenizationKey; +@property (nonatomic, strong, nullable) BTClientToken *clientToken; +@property (nonatomic, strong) BTHTTP *http; +@property (nonatomic, strong) BTHTTP *configurationHTTP; + +/** + @brief Client metadata that is used for tracking the client session +*/ +@property (nonatomic, readonly, strong) BTClientMetadata *metadata; + +/** + @brief Exposed for testing analytics +*/ +@property (nonatomic, strong) BTAnalyticsService *analyticsService; + +/** + @brief Sends this event and all queued analytics events. Use `queueAnalyticsEvent` for low priority events. +*/ +- (void)sendAnalyticsEvent:(NSString *)eventName; + +/** + @brief Queues an analytics event to be sent. + */ +- (void)queueAnalyticsEvent:(NSString *)eventName; + +/** + @brief An internal initializer to toggle whether to send an analytics event during initialization. + @discussion This prevents copyWithSource:integration: from sending a duplicate event. It can also be used to suppress excessive network chatter during testing. +*/ +- (nullable instancetype)initWithAuthorization:(NSString *)authorization sendAnalyticsEvent:(BOOL)sendAnalyticsEvent; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCore/BTAPIPinnedCertificates.h b/Pods/Braintree/BraintreeCore/BTAPIPinnedCertificates.h new file mode 100644 index 0000000..c15b563 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTAPIPinnedCertificates.h @@ -0,0 +1,21 @@ +#import + +// :rotating_light THIS CODE IS GENERATED BY codify_certificates.sh :rotating_light: + +/** + @class BTAPIPinnedCertificates + @brief Encapsualtes our trusted x509 Certificates for Secure SSL Communication with Braintree's servers. + + @discussion This class consists of code that is generated by the codify_certificates.sh script, which takes + a set of PEM formatted certificates and encodes them in code in order to avoid storing certificates + files in an NSBundle. +*/ +@interface BTAPIPinnedCertificates : NSObject + +/** + @brief Returns the set of trusted root certificates based on the PEM files located in this directory. + + @return An array of trusted certificates encoded in the DER format, encapsulated in NSData objects. +*/ ++ (NSArray *)trustedCertificates; +@end diff --git a/Pods/Braintree/BraintreeCore/BTAPIPinnedCertificates.m b/Pods/Braintree/BraintreeCore/BTAPIPinnedCertificates.m new file mode 100644 index 0000000..da33f05 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTAPIPinnedCertificates.m @@ -0,0 +1,1022 @@ +#import "BTAPIPinnedCertificates.h" + +// :rotating_light THIS CODE IS GENERATED BY codify_certificates.sh :rotating_light: +@implementation BTAPIPinnedCertificates + ++ (NSArray *)trustedCertificates { + NSMutableArray *trustedCertificates = [NSMutableArray arrayWithCapacity:15]; + { +/* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA 2 */ +/* issuer :/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA 2 */ +unsigned char XXX_certificate[874]={ +0x30,0x82,0x03,0x66,0x30,0x82,0x02,0x4E,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, +0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, +0x44,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x16, +0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73, +0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x03,0x13, +0x14,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x47,0x6C,0x6F,0x62,0x61,0x6C, +0x20,0x43,0x41,0x20,0x32,0x30,0x1E,0x17,0x0D,0x30,0x34,0x30,0x33,0x30,0x34,0x30, +0x35,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x30,0x33,0x30,0x34,0x30,0x35, +0x30,0x30,0x30,0x30,0x5A,0x30,0x44,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06, +0x13,0x02,0x55,0x53,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47, +0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1D,0x30,0x1B, +0x06,0x03,0x55,0x04,0x03,0x13,0x14,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20, +0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x43,0x41,0x20,0x32,0x30,0x82,0x01,0x22,0x30, +0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82, +0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xEF,0x3C,0x4D,0x40, +0x3D,0x10,0xDF,0x3B,0x53,0x00,0xE1,0x67,0xFE,0x94,0x60,0x15,0x3E,0x85,0x88,0xF1, +0x89,0x0D,0x90,0xC8,0x28,0x23,0x99,0x05,0xE8,0x2B,0x20,0x9D,0xC6,0xF3,0x60,0x46, +0xD8,0xC1,0xB2,0xD5,0x8C,0x31,0xD9,0xDC,0x20,0x79,0x24,0x81,0xBF,0x35,0x32,0xFC, +0x63,0x69,0xDB,0xB1,0x2A,0x6B,0xEE,0x21,0x58,0xF2,0x08,0xE9,0x78,0xCB,0x6F,0xCB, +0xFC,0x16,0x52,0xC8,0x91,0xC4,0xFF,0x3D,0x73,0xDE,0xB1,0x3E,0xA7,0xC2,0x7D,0x66, +0xC1,0xF5,0x7E,0x52,0x24,0x1A,0xE2,0xD5,0x67,0x91,0xD0,0x82,0x10,0xD7,0x78,0x4B, +0x4F,0x2B,0x42,0x39,0xBD,0x64,0x2D,0x40,0xA0,0xB0,0x10,0xD3,0x38,0x48,0x46,0x88, +0xA1,0x0C,0xBB,0x3A,0x33,0x2A,0x62,0x98,0xFB,0x00,0x9D,0x13,0x59,0x7F,0x6F,0x3B, +0x72,0xAA,0xEE,0xA6,0x0F,0x86,0xF9,0x05,0x61,0xEA,0x67,0x7F,0x0C,0x37,0x96,0x8B, +0xE6,0x69,0x16,0x47,0x11,0xC2,0x27,0x59,0x03,0xB3,0xA6,0x60,0xC2,0x21,0x40,0x56, +0xFA,0xA0,0xC7,0x7D,0x3A,0x13,0xE3,0xEC,0x57,0xC7,0xB3,0xD6,0xAE,0x9D,0x89,0x80, +0xF7,0x01,0xE7,0x2C,0xF6,0x96,0x2B,0x13,0x0D,0x79,0x2C,0xD9,0xC0,0xE4,0x86,0x7B, +0x4B,0x8C,0x0C,0x72,0x82,0x8A,0xFB,0x17,0xCD,0x00,0x6C,0x3A,0x13,0x3C,0xB0,0x84, +0x87,0x4B,0x16,0x7A,0x29,0xB2,0x4F,0xDB,0x1D,0xD4,0x0B,0xF3,0x66,0x37,0xBD,0xD8, +0xF6,0x57,0xBB,0x5E,0x24,0x7A,0xB8,0x3C,0x8B,0xB9,0xFA,0x92,0x1A,0x1A,0x84,0x9E, +0xD8,0x74,0x8F,0xAA,0x1B,0x7F,0x5E,0xF4,0xFE,0x45,0x22,0x21,0x02,0x03,0x01,0x00, +0x01,0xA3,0x63,0x30,0x61,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04, +0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04, +0x14,0x71,0x38,0x36,0xF2,0x02,0x31,0x53,0x47,0x2B,0x6E,0xBA,0x65,0x46,0xA9,0x10, +0x15,0x58,0x20,0x05,0x09,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16, +0x80,0x14,0x71,0x38,0x36,0xF2,0x02,0x31,0x53,0x47,0x2B,0x6E,0xBA,0x65,0x46,0xA9, +0x10,0x15,0x58,0x20,0x05,0x09,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF, +0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, +0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x03,0xF7,0xB5,0x2B,0xAB,0x5D, +0x10,0xFC,0x7B,0xB2,0xB2,0x5E,0xAC,0x9B,0x0E,0x7E,0x53,0x78,0x59,0x3E,0x42,0x04, +0xFE,0x75,0xA3,0xAD,0xAC,0x81,0x4E,0xD7,0x02,0x8B,0x5E,0xC4,0x2D,0xC8,0x52,0x76, +0xC7,0x2C,0x1F,0xFC,0x81,0x32,0x98,0xD1,0x4B,0xC6,0x92,0x93,0x33,0x35,0x31,0x2F, +0xFC,0xD8,0x1D,0x44,0xDD,0xE0,0x81,0x7F,0x9D,0xE9,0x8B,0xE1,0x64,0x91,0x62,0x0B, +0x39,0x08,0x8C,0xAC,0x74,0x9D,0x59,0xD9,0x7A,0x59,0x52,0x97,0x11,0xB9,0x16,0x7B, +0x6F,0x45,0xD3,0x96,0xD9,0x31,0x7D,0x02,0x36,0x0F,0x9C,0x3B,0x6E,0xCF,0x2C,0x0D, +0x03,0x46,0x45,0xEB,0xA0,0xF4,0x7F,0x48,0x44,0xC6,0x08,0x40,0xCC,0xDE,0x1B,0x70, +0xB5,0x29,0xAD,0xBA,0x8B,0x3B,0x34,0x65,0x75,0x1B,0x71,0x21,0x1D,0x2C,0x14,0x0A, +0xB0,0x96,0x95,0xB8,0xD6,0xEA,0xF2,0x65,0xFB,0x29,0xBA,0x4F,0xEA,0x91,0x93,0x74, +0x69,0xB6,0xF2,0xFF,0xE1,0x1A,0xD0,0x0C,0xD1,0x76,0x85,0xCB,0x8A,0x25,0xBD,0x97, +0x5E,0x2C,0x6F,0x15,0x99,0x26,0xE7,0xB6,0x29,0xFF,0x22,0xEC,0xC9,0x02,0xC7,0x56, +0x00,0xCD,0x49,0xB9,0xB3,0x6C,0x7B,0x53,0x04,0x1A,0xE2,0xA8,0xC9,0xAA,0x12,0x05, +0x23,0xC2,0xCE,0xE7,0xBB,0x04,0x02,0xCC,0xC0,0x47,0xA2,0xE4,0xC4,0x29,0x2F,0x5B, +0x45,0x57,0x89,0x51,0xEE,0x3C,0xEB,0x52,0x08,0xFF,0x07,0x35,0x1E,0x9F,0x35,0x6A, +0x47,0x4A,0x56,0x98,0xD1,0x5A,0x85,0x1F,0x8C,0xF5,0x22,0xBF,0xAB,0xCE,0x83,0xF3, +0xE2,0x22,0x29,0xAE,0x7D,0x83,0x40,0xA8,0xBA,0x6C, +}; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { +/* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */ +/* issuer :/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA */ +unsigned char XXX_certificate[856]={ +0x30,0x82,0x03,0x54,0x30,0x82,0x02,0x3C,0xA0,0x03,0x02,0x01,0x02,0x02,0x03,0x02, +0x34,0x56,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05, +0x00,0x30,0x42,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, +0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72, +0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04, +0x03,0x13,0x12,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x47,0x6C,0x6F,0x62, +0x61,0x6C,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x32,0x30,0x35,0x32,0x31,0x30, +0x34,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x32,0x30,0x35,0x32,0x31,0x30,0x34, +0x30,0x30,0x30,0x30,0x5A,0x30,0x42,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06, +0x13,0x02,0x55,0x53,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47, +0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1B,0x30,0x19, +0x06,0x03,0x55,0x04,0x03,0x13,0x12,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20, +0x47,0x6C,0x6F,0x62,0x61,0x6C,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06, +0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F, +0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xDA,0xCC,0x18,0x63,0x30,0xFD, +0xF4,0x17,0x23,0x1A,0x56,0x7E,0x5B,0xDF,0x3C,0x6C,0x38,0xE4,0x71,0xB7,0x78,0x91, +0xD4,0xBC,0xA1,0xD8,0x4C,0xF8,0xA8,0x43,0xB6,0x03,0xE9,0x4D,0x21,0x07,0x08,0x88, +0xDA,0x58,0x2F,0x66,0x39,0x29,0xBD,0x05,0x78,0x8B,0x9D,0x38,0xE8,0x05,0xB7,0x6A, +0x7E,0x71,0xA4,0xE6,0xC4,0x60,0xA6,0xB0,0xEF,0x80,0xE4,0x89,0x28,0x0F,0x9E,0x25, +0xD6,0xED,0x83,0xF3,0xAD,0xA6,0x91,0xC7,0x98,0xC9,0x42,0x18,0x35,0x14,0x9D,0xAD, +0x98,0x46,0x92,0x2E,0x4F,0xCA,0xF1,0x87,0x43,0xC1,0x16,0x95,0x57,0x2D,0x50,0xEF, +0x89,0x2D,0x80,0x7A,0x57,0xAD,0xF2,0xEE,0x5F,0x6B,0xD2,0x00,0x8D,0xB9,0x14,0xF8, +0x14,0x15,0x35,0xD9,0xC0,0x46,0xA3,0x7B,0x72,0xC8,0x91,0xBF,0xC9,0x55,0x2B,0xCD, +0xD0,0x97,0x3E,0x9C,0x26,0x64,0xCC,0xDF,0xCE,0x83,0x19,0x71,0xCA,0x4E,0xE6,0xD4, +0xD5,0x7B,0xA9,0x19,0xCD,0x55,0xDE,0xC8,0xEC,0xD2,0x5E,0x38,0x53,0xE5,0x5C,0x4F, +0x8C,0x2D,0xFE,0x50,0x23,0x36,0xFC,0x66,0xE6,0xCB,0x8E,0xA4,0x39,0x19,0x00,0xB7, +0x95,0x02,0x39,0x91,0x0B,0x0E,0xFE,0x38,0x2E,0xD1,0x1D,0x05,0x9A,0xF6,0x4D,0x3E, +0x6F,0x0F,0x07,0x1D,0xAF,0x2C,0x1E,0x8F,0x60,0x39,0xE2,0xFA,0x36,0x53,0x13,0x39, +0xD4,0x5E,0x26,0x2B,0xDB,0x3D,0xA8,0x14,0xBD,0x32,0xEB,0x18,0x03,0x28,0x52,0x04, +0x71,0xE5,0xAB,0x33,0x3D,0xE1,0x38,0xBB,0x07,0x36,0x84,0x62,0x9C,0x79,0xEA,0x16, +0x30,0xF4,0x5F,0xC0,0x2B,0xE8,0x71,0x6B,0xE4,0xF9,0x02,0x03,0x01,0x00,0x01,0xA3, +0x53,0x30,0x51,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30, +0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xC0, +0x7A,0x98,0x68,0x8D,0x89,0xFB,0xAB,0x05,0x64,0x0C,0x11,0x7D,0xAA,0x7D,0x65,0xB8, +0xCA,0xCC,0x4E,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14, +0xC0,0x7A,0x98,0x68,0x8D,0x89,0xFB,0xAB,0x05,0x64,0x0C,0x11,0x7D,0xAA,0x7D,0x65, +0xB8,0xCA,0xCC,0x4E,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, +0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x35,0xE3,0x29,0x6A,0xE5,0x2F,0x5D,0x54, +0x8E,0x29,0x50,0x94,0x9F,0x99,0x1A,0x14,0xE4,0x8F,0x78,0x2A,0x62,0x94,0xA2,0x27, +0x67,0x9E,0xD0,0xCF,0x1A,0x5E,0x47,0xE9,0xC1,0xB2,0xA4,0xCF,0xDD,0x41,0x1A,0x05, +0x4E,0x9B,0x4B,0xEE,0x4A,0x6F,0x55,0x52,0xB3,0x24,0xA1,0x37,0x0A,0xEB,0x64,0x76, +0x2A,0x2E,0x2C,0xF3,0xFD,0x3B,0x75,0x90,0xBF,0xFA,0x71,0xD8,0xC7,0x3D,0x37,0xD2, +0xB5,0x05,0x95,0x62,0xB9,0xA6,0xDE,0x89,0x3D,0x36,0x7B,0x38,0x77,0x48,0x97,0xAC, +0xA6,0x20,0x8F,0x2E,0xA6,0xC9,0x0C,0xC2,0xB2,0x99,0x45,0x00,0xC7,0xCE,0x11,0x51, +0x22,0x22,0xE0,0xA5,0xEA,0xB6,0x15,0x48,0x09,0x64,0xEA,0x5E,0x4F,0x74,0xF7,0x05, +0x3E,0xC7,0x8A,0x52,0x0C,0xDB,0x15,0xB4,0xBD,0x6D,0x9B,0xE5,0xC6,0xB1,0x54,0x68, +0xA9,0xE3,0x69,0x90,0xB6,0x9A,0xA5,0x0F,0xB8,0xB9,0x3F,0x20,0x7D,0xAE,0x4A,0xB5, +0xB8,0x9C,0xE4,0x1D,0xB6,0xAB,0xE6,0x94,0xA5,0xC1,0xC7,0x83,0xAD,0xDB,0xF5,0x27, +0x87,0x0E,0x04,0x6C,0xD5,0xFF,0xDD,0xA0,0x5D,0xED,0x87,0x52,0xB7,0x2B,0x15,0x02, +0xAE,0x39,0xA6,0x6A,0x74,0xE9,0xDA,0xC4,0xE7,0xBC,0x4D,0x34,0x1E,0xA9,0x5C,0x4D, +0x33,0x5F,0x92,0x09,0x2F,0x88,0x66,0x5D,0x77,0x97,0xC7,0x1D,0x76,0x13,0xA9,0xD5, +0xE5,0xF1,0x16,0x09,0x11,0x35,0xD5,0xAC,0xDB,0x24,0x71,0x70,0x2C,0x98,0x56,0x0B, +0xD9,0x17,0xB4,0xD1,0xE3,0x51,0x2B,0x5E,0x75,0xE8,0xD5,0xD0,0xDC,0x4F,0x34,0xED, +0xC2,0x05,0x66,0x80,0xA1,0xCB,0xE6,0x33, +}; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { +/* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Universal CA 2 */ +/* issuer :/C=US/O=GeoTrust Inc./CN=GeoTrust Universal CA 2 */ +unsigned char XXX_certificate[1392]={ +0x30,0x82,0x05,0x6C,0x30,0x82,0x03,0x54,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, +0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, +0x47,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x16, +0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73, +0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13, +0x17,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x55,0x6E,0x69,0x76,0x65,0x72, +0x73,0x61,0x6C,0x20,0x43,0x41,0x20,0x32,0x30,0x1E,0x17,0x0D,0x30,0x34,0x30,0x33, +0x30,0x34,0x30,0x35,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x39,0x30,0x33,0x30, +0x34,0x30,0x35,0x30,0x30,0x30,0x30,0x5A,0x30,0x47,0x31,0x0B,0x30,0x09,0x06,0x03, +0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A, +0x13,0x0D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31, +0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17,0x47,0x65,0x6F,0x54,0x72,0x75, +0x73,0x74,0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x20, +0x32,0x30,0x82,0x02,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, +0x01,0x01,0x05,0x00,0x03,0x82,0x02,0x0F,0x00,0x30,0x82,0x02,0x0A,0x02,0x82,0x02, +0x01,0x00,0xB3,0x54,0x52,0xC1,0xC9,0x3E,0xF2,0xD9,0xDC,0xB1,0x53,0x1A,0x59,0x29, +0xE7,0xB1,0xC3,0x45,0x28,0xE5,0xD7,0xD1,0xED,0xC5,0xC5,0x4B,0xA1,0xAA,0x74,0x7B, +0x57,0xAF,0x4A,0x26,0xFC,0xD8,0xF5,0x5E,0xA7,0x6E,0x19,0xDB,0x74,0x0C,0x4F,0x35, +0x5B,0x32,0x0B,0x01,0xE3,0xDB,0xEB,0x7A,0x77,0x35,0xEA,0xAA,0x5A,0xE0,0xD6,0xE8, +0xA1,0x57,0x94,0xF0,0x90,0xA3,0x74,0x56,0x94,0x44,0x30,0x03,0x1E,0x5C,0x4E,0x2B, +0x85,0x26,0x74,0x82,0x7A,0x0C,0x76,0xA0,0x6F,0x4D,0xCE,0x41,0x2D,0xA0,0x15,0x06, +0x14,0x5F,0xB7,0x42,0xCD,0x7B,0x8F,0x58,0x61,0x34,0xDC,0x2A,0x08,0xF9,0x2E,0xC3, +0x01,0xA6,0x22,0x44,0x1C,0x4C,0x07,0x82,0xE6,0x5B,0xCE,0xD0,0x4A,0x7C,0x04,0xD3, +0x19,0x73,0x27,0xF0,0xAA,0x98,0x7F,0x2E,0xAF,0x4E,0xEB,0x87,0x1E,0x24,0x77,0x6A, +0x5D,0xB6,0xE8,0x5B,0x45,0xBA,0xDC,0xC3,0xA1,0x05,0x6F,0x56,0x8E,0x8F,0x10,0x26, +0xA5,0x49,0xC3,0x2E,0xD7,0x41,0x87,0x22,0xE0,0x4F,0x86,0xCA,0x60,0xB5,0xEA,0xA1, +0x63,0xC0,0x01,0x97,0x10,0x79,0xBD,0x00,0x3C,0x12,0x6D,0x2B,0x15,0xB1,0xAC,0x4B, +0xB1,0xEE,0x18,0xB9,0x4E,0x96,0xDC,0xDC,0x76,0xFF,0x3B,0xBE,0xCF,0x5F,0x03,0xC0, +0xFC,0x3B,0xE8,0xBE,0x46,0x1B,0xFF,0xDA,0x40,0xC2,0x52,0xF7,0xFE,0xE3,0x3A,0xF7, +0x6A,0x77,0x35,0xD0,0xDA,0x8D,0xEB,0x5E,0x18,0x6A,0x31,0xC7,0x1E,0xBA,0x3C,0x1B, +0x28,0xD6,0x6B,0x54,0xC6,0xAA,0x5B,0xD7,0xA2,0x2C,0x1B,0x19,0xCC,0xA2,0x02,0xF6, +0x9B,0x59,0xBD,0x37,0x6B,0x86,0xB5,0x6D,0x82,0xBA,0xD8,0xEA,0xC9,0x56,0xBC,0xA9, +0x36,0x58,0xFD,0x3E,0x19,0xF3,0xED,0x0C,0x26,0xA9,0x93,0x38,0xF8,0x4F,0xC1,0x5D, +0x22,0x06,0xD0,0x97,0xEA,0xE1,0xAD,0xC6,0x55,0xE0,0x81,0x2B,0x28,0x83,0x3A,0xFA, +0xF4,0x7B,0x21,0x51,0x00,0xBE,0x52,0x38,0xCE,0xCD,0x66,0x79,0xA8,0xF4,0x81,0x56, +0xE2,0xD0,0x83,0x09,0x47,0x51,0x5B,0x50,0x6A,0xCF,0xDB,0x48,0x1A,0x5D,0x3E,0xF7, +0xCB,0xF6,0x65,0xF7,0x6C,0xF1,0x95,0xF8,0x02,0x3B,0x32,0x56,0x82,0x39,0x7A,0x5B, +0xBD,0x2F,0x89,0x1B,0xBF,0xA1,0xB4,0xE8,0xFF,0x7F,0x8D,0x8C,0xDF,0x03,0xF1,0x60, +0x4E,0x58,0x11,0x4C,0xEB,0xA3,0x3F,0x10,0x2B,0x83,0x9A,0x01,0x73,0xD9,0x94,0x6D, +0x84,0x00,0x27,0x66,0xAC,0xF0,0x70,0x40,0x09,0x42,0x92,0xAD,0x4F,0x93,0x0D,0x61, +0x09,0x51,0x24,0xD8,0x92,0xD5,0x0B,0x94,0x61,0xB2,0x87,0xB2,0xED,0xFF,0x9A,0x35, +0xFF,0x85,0x54,0xCA,0xED,0x44,0x43,0xAC,0x1B,0x3C,0x16,0x6B,0x48,0x4A,0x0A,0x1C, +0x40,0x88,0x1F,0x92,0xC2,0x0B,0x00,0x05,0xFF,0xF2,0xC8,0x02,0x4A,0xA4,0xAA,0xA9, +0xCC,0x99,0x96,0x9C,0x2F,0x58,0xE0,0x7D,0xE1,0xBE,0xBB,0x07,0xDC,0x5F,0x04,0x72, +0x5C,0x31,0x34,0xC3,0xEC,0x5F,0x2D,0xE0,0x3D,0x64,0x90,0x22,0xE6,0xD1,0xEC,0xB8, +0x2E,0xDD,0x59,0xAE,0xD9,0xA1,0x37,0xBF,0x54,0x35,0xDC,0x73,0x32,0x4F,0x8C,0x04, +0x1E,0x33,0xB2,0xC9,0x46,0xF1,0xD8,0x5C,0xC8,0x55,0x50,0xC9,0x68,0xBD,0xA8,0xBA, +0x36,0x09,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,0x0F,0x06,0x03,0x55, +0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03, +0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x76,0xF3,0x55,0xE1,0xFA,0xA4,0x36,0xFB,0xF0, +0x9F,0x5C,0x62,0x71,0xED,0x3C,0xF4,0x47,0x38,0x10,0x2B,0x30,0x1F,0x06,0x03,0x55, +0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x76,0xF3,0x55,0xE1,0xFA,0xA4,0x36,0xFB, +0xF0,0x9F,0x5C,0x62,0x71,0xED,0x3C,0xF4,0x47,0x38,0x10,0x2B,0x30,0x0E,0x06,0x03, +0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0D,0x06,0x09, +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x02,0x01,0x00, +0x66,0xC1,0xC6,0x23,0xF3,0xD9,0xE0,0x2E,0x6E,0x5F,0xE8,0xCF,0xAE,0xB0,0xB0,0x25, +0x4D,0x2B,0xF8,0x3B,0x58,0x9B,0x40,0x24,0x37,0x5A,0xCB,0xAB,0x16,0x49,0xFF,0xB3, +0x75,0x79,0x33,0xA1,0x2F,0x6D,0x70,0x17,0x34,0x91,0xFE,0x67,0x7E,0x8F,0xEC,0x9B, +0xE5,0x5E,0x82,0xA9,0x55,0x1F,0x2F,0xDC,0xD4,0x51,0x07,0x12,0xFE,0xAC,0x16,0x3E, +0x2C,0x35,0xC6,0x63,0xFC,0xDC,0x10,0xEB,0x0D,0xA3,0xAA,0xD0,0x7C,0xCC,0xD1,0xD0, +0x2F,0x51,0x2E,0xC4,0x14,0x5A,0xDE,0xE8,0x19,0xE1,0x3E,0xC6,0xCC,0xA4,0x29,0xE7, +0x2E,0x84,0xAA,0x06,0x30,0x78,0x76,0x54,0x73,0x28,0x98,0x59,0x38,0xE0,0x00,0x0D, +0x62,0xD3,0x42,0x7D,0x21,0x9F,0xAE,0x3D,0x3A,0x8C,0xD5,0xFA,0x77,0x0D,0x18,0x2B, +0x16,0x0E,0x5F,0x36,0xE1,0xFC,0x2A,0xB5,0x30,0x24,0xCF,0xE0,0x63,0x0C,0x7B,0x58, +0x1A,0xFE,0x99,0xBA,0x42,0x12,0xB1,0x91,0xF4,0x7C,0x68,0xE2,0xC8,0xE8,0xAF,0x2C, +0xEA,0xC9,0x7E,0xAE,0xBB,0x2A,0x3D,0x0D,0x15,0xDC,0x34,0x95,0xB6,0x18,0x74,0xA8, +0x6A,0x0F,0xC7,0xB4,0xF4,0x13,0xC4,0xE4,0x5B,0xED,0x0A,0xD2,0xA4,0x97,0x4C,0x2A, +0xED,0x2F,0x6C,0x12,0x89,0x3D,0xF1,0x27,0x70,0xAA,0x6A,0x03,0x52,0x21,0x9F,0x40, +0xA8,0x67,0x50,0xF2,0xF3,0x5A,0x1F,0xDF,0xDF,0x23,0xF6,0xDC,0x78,0x4E,0xE6,0x98, +0x4F,0x55,0x3A,0x53,0xE3,0xEF,0xF2,0xF4,0x9F,0xC7,0x7C,0xD8,0x58,0xAF,0x29,0x22, +0x97,0xB8,0xE0,0xBD,0x91,0x2E,0xB0,0x76,0xEC,0x57,0x11,0xCF,0xEF,0x29,0x44,0xF3, +0xE9,0x85,0x7A,0x60,0x63,0xE4,0x5D,0x33,0x89,0x17,0xD9,0x31,0xAA,0xDA,0xD6,0xF3, +0x18,0x35,0x72,0xCF,0x87,0x2B,0x2F,0x63,0x23,0x84,0x5D,0x84,0x8C,0x3F,0x57,0xA0, +0x88,0xFC,0x99,0x91,0x28,0x26,0x69,0x99,0xD4,0x8F,0x97,0x44,0xBE,0x8E,0xD5,0x48, +0xB1,0xA4,0x28,0x29,0xF1,0x15,0xB4,0xE1,0xE5,0x9E,0xDD,0xF8,0x8F,0xA6,0x6F,0x26, +0xD7,0x09,0x3C,0x3A,0x1C,0x11,0x0E,0xA6,0x6C,0x37,0xF7,0xAD,0x44,0x87,0x2C,0x28, +0xC7,0xD8,0x74,0x82,0xB3,0xD0,0x6F,0x4A,0x57,0xBB,0x35,0x29,0x27,0xA0,0x8B,0xE8, +0x21,0xA7,0x87,0x64,0x36,0x5D,0xCC,0xD8,0x16,0xAC,0xC7,0xB2,0x27,0x40,0x92,0x55, +0x38,0x28,0x8D,0x51,0x6E,0xDD,0x14,0x67,0x53,0x6C,0x71,0x5C,0x26,0x84,0x4D,0x75, +0x5A,0xB6,0x7E,0x60,0x56,0xA9,0x4D,0xAD,0xFB,0x9B,0x1E,0x97,0xF3,0x0D,0xD9,0xD2, +0x97,0x54,0x77,0xDA,0x3D,0x12,0xB7,0xE0,0x1E,0xEF,0x08,0x06,0xAC,0xF9,0x85,0x87, +0xE9,0xA2,0xDC,0xAF,0x7E,0x18,0x12,0x83,0xFD,0x56,0x17,0x41,0x2E,0xD5,0x29,0x82, +0x7D,0x99,0xF4,0x31,0xF6,0x71,0xA9,0xCF,0x2C,0x01,0x27,0xA5,0x05,0xB9,0xAA,0xB2, +0x48,0x4E,0x2A,0xEF,0x9F,0x93,0x52,0x51,0x95,0x3C,0x52,0x73,0x8E,0x56,0x4C,0x17, +0x40,0xC0,0x09,0x28,0xE4,0x8B,0x6A,0x48,0x53,0xDB,0xEC,0xCD,0x55,0x55,0xF1,0xC6, +0xF8,0xE9,0xA2,0x2C,0x4C,0xA6,0xD1,0x26,0x5F,0x7E,0xAF,0x5A,0x4C,0xDA,0x1F,0xA6, +0xF2,0x1C,0x2C,0x7E,0xAE,0x02,0x16,0xD2,0x56,0xD0,0x2F,0x57,0x53,0x47,0xE8,0x92, +}; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { +/* subject:/C=US/O=GeoTrust Inc./CN=GeoTrust Universal CA */ +/* issuer :/C=US/O=GeoTrust Inc./CN=GeoTrust Universal CA */ +unsigned char XXX_certificate[1388]={ +0x30,0x82,0x05,0x68,0x30,0x82,0x03,0x50,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, +0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, +0x45,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x16, +0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D,0x47,0x65,0x6F,0x54,0x72,0x75,0x73, +0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x13, +0x15,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x55,0x6E,0x69,0x76,0x65,0x72, +0x73,0x61,0x6C,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x34,0x30,0x33,0x30,0x34, +0x30,0x35,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x39,0x30,0x33,0x30,0x34,0x30, +0x35,0x30,0x30,0x30,0x30,0x5A,0x30,0x45,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04, +0x06,0x13,0x02,0x55,0x53,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x0A,0x13,0x0D, +0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1E,0x30, +0x1C,0x06,0x03,0x55,0x04,0x03,0x13,0x15,0x47,0x65,0x6F,0x54,0x72,0x75,0x73,0x74, +0x20,0x55,0x6E,0x69,0x76,0x65,0x72,0x73,0x61,0x6C,0x20,0x43,0x41,0x30,0x82,0x02, +0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00, +0x03,0x82,0x02,0x0F,0x00,0x30,0x82,0x02,0x0A,0x02,0x82,0x02,0x01,0x00,0xA6,0x15, +0x55,0xA0,0xA3,0xC6,0xE0,0x1F,0x8C,0x9D,0x21,0x50,0xD7,0xC1,0xBE,0x2B,0x5B,0xB5, +0xA4,0x9E,0xA1,0xD9,0x72,0x58,0xBD,0x00,0x1B,0x4C,0xBF,0x61,0xC9,0x14,0x1D,0x45, +0x82,0xAB,0xC6,0x1D,0x80,0xD6,0x3D,0xEB,0x10,0x9C,0x3A,0xAF,0x6D,0x24,0xF8,0xBC, +0x71,0x01,0x9E,0x06,0xF5,0x7C,0x5F,0x1E,0xC1,0x0E,0x55,0xCA,0x83,0x9A,0x59,0x30, +0xAE,0x19,0xCB,0x30,0x48,0x95,0xED,0x22,0x37,0x8D,0xF4,0x4A,0x9A,0x72,0x66,0x3E, +0xAD,0x95,0xC0,0xE0,0x16,0x00,0xE0,0x10,0x1F,0x2B,0x31,0x0E,0xD7,0x94,0x54,0xD3, +0x42,0x33,0xA0,0x34,0x1D,0x1E,0x45,0x76,0xDD,0x4F,0xCA,0x18,0x37,0xEC,0x85,0x15, +0x7A,0x19,0x08,0xFC,0xD5,0xC7,0x9C,0xF0,0xF2,0xA9,0x2E,0x10,0xA9,0x92,0xE6,0x3D, +0x58,0x3D,0xA9,0x16,0x68,0x3C,0x2F,0x75,0x21,0x18,0x7F,0x28,0x77,0xA5,0xE1,0x61, +0x17,0xB7,0xA6,0xE9,0xF8,0x1E,0x99,0xDB,0x73,0x6E,0xF4,0x0A,0xA2,0x21,0x6C,0xEE, +0xDA,0xAA,0x85,0x92,0x66,0xAF,0xF6,0x7A,0x6B,0x82,0xDA,0xBA,0x22,0x08,0x35,0x0F, +0xCF,0x42,0xF1,0x35,0xFA,0x6A,0xEE,0x7E,0x2B,0x25,0xCC,0x3A,0x11,0xE4,0x6D,0xAF, +0x73,0xB2,0x76,0x1D,0xAD,0xD0,0xB2,0x78,0x67,0x1A,0xA4,0x39,0x1C,0x51,0x0B,0x67, +0x56,0x83,0xFD,0x38,0x5D,0x0D,0xCE,0xDD,0xF0,0xBB,0x2B,0x96,0x1F,0xDE,0x7B,0x32, +0x52,0xFD,0x1D,0xBB,0xB5,0x06,0xA1,0xB2,0x21,0x5E,0xA5,0xD6,0x95,0x68,0x7F,0xF0, +0x99,0x9E,0xDC,0x45,0x08,0x3E,0xE7,0xD2,0x09,0x0D,0x35,0x94,0xDD,0x80,0x4E,0x53, +0x97,0xD7,0xB5,0x09,0x44,0x20,0x64,0x16,0x17,0x03,0x02,0x4C,0x53,0x0D,0x68,0xDE, +0xD5,0xAA,0x72,0x4D,0x93,0x6D,0x82,0x0E,0xDB,0x9C,0xBD,0xCF,0xB4,0xF3,0x5C,0x5D, +0x54,0x7A,0x69,0x09,0x96,0xD6,0xDB,0x11,0xC1,0x8D,0x75,0xA8,0xB4,0xCF,0x39,0xC8, +0xCE,0x3C,0xBC,0x24,0x7C,0xE6,0x62,0xCA,0xE1,0xBD,0x7D,0xA7,0xBD,0x57,0x65,0x0B, +0xE4,0xFE,0x25,0xED,0xB6,0x69,0x10,0xDC,0x28,0x1A,0x46,0xBD,0x01,0x1D,0xD0,0x97, +0xB5,0xE1,0x98,0x3B,0xC0,0x37,0x64,0xD6,0x3D,0x94,0xEE,0x0B,0xE1,0xF5,0x28,0xAE, +0x0B,0x56,0xBF,0x71,0x8B,0x23,0x29,0x41,0x8E,0x86,0xC5,0x4B,0x52,0x7B,0xD8,0x71, +0xAB,0x1F,0x8A,0x15,0xA6,0x3B,0x83,0x5A,0xD7,0x58,0x01,0x51,0xC6,0x4C,0x41,0xD9, +0x7F,0xD8,0x41,0x67,0x72,0xA2,0x28,0xDF,0x60,0x83,0xA9,0x9E,0xC8,0x7B,0xFC,0x53, +0x73,0x72,0x59,0xF5,0x93,0x7A,0x17,0x76,0x0E,0xCE,0xF7,0xE5,0x5C,0xD9,0x0B,0x55, +0x34,0xA2,0xAA,0x5B,0xB5,0x6A,0x54,0xE7,0x13,0xCA,0x57,0xEC,0x97,0x6D,0xF4,0x5E, +0x06,0x2F,0x45,0x8B,0x58,0xD4,0x23,0x16,0x92,0xE4,0x16,0x6E,0x28,0x63,0x59,0x30, +0xDF,0x50,0x01,0x9C,0x63,0x89,0x1A,0x9F,0xDB,0x17,0x94,0x82,0x70,0x37,0xC3,0x24, +0x9E,0x9A,0x47,0xD6,0x5A,0xCA,0x4E,0xA8,0x69,0x89,0x72,0x1F,0x91,0x6C,0xDB,0x7E, +0x9E,0x1B,0xAD,0xC7,0x1F,0x73,0xDD,0x2C,0x4F,0x19,0x65,0xFD,0x7F,0x93,0x40,0x10, +0x2E,0xD2,0xF0,0xED,0x3C,0x9E,0x2E,0x28,0x3E,0x69,0x26,0x33,0xC5,0x7B,0x02,0x03, +0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01, +0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04, +0x16,0x04,0x14,0xDA,0xBB,0x2E,0xAA,0xB0,0x0C,0xB8,0x88,0x26,0x51,0x74,0x5C,0x6D, +0x03,0xD3,0xC0,0xD8,0x8F,0x7A,0xD6,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18, +0x30,0x16,0x80,0x14,0xDA,0xBB,0x2E,0xAA,0xB0,0x0C,0xB8,0x88,0x26,0x51,0x74,0x5C, +0x6D,0x03,0xD3,0xC0,0xD8,0x8F,0x7A,0xD6,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01, +0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x86,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, +0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x31,0x78,0xE6,0xC7, +0xB5,0xDF,0xB8,0x94,0x40,0xC9,0x71,0xC4,0xA8,0x35,0xEC,0x46,0x1D,0xC2,0x85,0xF3, +0x28,0x58,0x86,0xB0,0x0B,0xFC,0x8E,0xB2,0x39,0x8F,0x44,0x55,0xAB,0x64,0x84,0x5C, +0x69,0xA9,0xD0,0x9A,0x38,0x3C,0xFA,0xE5,0x1F,0x35,0xE5,0x44,0xE3,0x80,0x79,0x94, +0x68,0xA4,0xBB,0xC4,0x9F,0x3D,0xE1,0x34,0xCD,0x30,0x46,0x8B,0x54,0x2B,0x95,0xA5, +0xEF,0xF7,0x3F,0x99,0x84,0xFD,0x35,0xE6,0xCF,0x31,0xC6,0xDC,0x6A,0xBF,0xA7,0xD7, +0x23,0x08,0xE1,0x98,0x5E,0xC3,0x5A,0x08,0x76,0xA9,0xA6,0xAF,0x77,0x2F,0xB7,0x60, +0xBD,0x44,0x46,0x6A,0xEF,0x97,0xFF,0x73,0x95,0xC1,0x8E,0xE8,0x93,0xFB,0xFD,0x31, +0xB7,0xEC,0x57,0x11,0x11,0x45,0x9B,0x30,0xF1,0x1A,0x88,0x39,0xC1,0x4F,0x3C,0xA7, +0x00,0xD5,0xC7,0xFC,0xAB,0x6D,0x80,0x22,0x70,0xA5,0x0C,0xE0,0x5D,0x04,0x29,0x02, +0xFB,0xCB,0xA0,0x91,0xD1,0x7C,0xD6,0xC3,0x7E,0x50,0xD5,0x9D,0x58,0xBE,0x41,0x38, +0xEB,0xB9,0x75,0x3C,0x15,0xD9,0x9B,0xC9,0x4A,0x83,0x59,0xC0,0xDA,0x53,0xFD,0x33, +0xBB,0x36,0x18,0x9B,0x85,0x0F,0x15,0xDD,0xEE,0x2D,0xAC,0x76,0x93,0xB9,0xD9,0x01, +0x8D,0x48,0x10,0xA8,0xFB,0xF5,0x38,0x86,0xF1,0xDB,0x0A,0xC6,0xBD,0x84,0xA3,0x23, +0x41,0xDE,0xD6,0x77,0x6F,0x85,0xD4,0x85,0x1C,0x50,0xE0,0xAE,0x51,0x8A,0xBA,0x8D, +0x3E,0x76,0xE2,0xB9,0xCA,0x27,0xF2,0x5F,0x9F,0xEF,0x6E,0x59,0x0D,0x06,0xD8,0x2B, +0x17,0xA4,0xD2,0x7C,0x6B,0xBB,0x5F,0x14,0x1A,0x48,0x8F,0x1A,0x4C,0xE7,0xB3,0x47, +0x1C,0x8E,0x4C,0x45,0x2B,0x20,0xEE,0x48,0xDF,0xE7,0xDD,0x09,0x8E,0x18,0xA8,0xDA, +0x40,0x8D,0x92,0x26,0x11,0x53,0x61,0x73,0x5D,0xEB,0xBD,0xE7,0xC4,0x4D,0x29,0x37, +0x61,0xEB,0xAC,0x39,0x2D,0x67,0x2E,0x16,0xD6,0xF5,0x00,0x83,0x85,0xA1,0xCC,0x7F, +0x76,0xC4,0x7D,0xE4,0xB7,0x4B,0x66,0xEF,0x03,0x45,0x60,0x69,0xB6,0x0C,0x52,0x96, +0x92,0x84,0x5E,0xA6,0xA3,0xB5,0xA4,0x3E,0x2B,0xD9,0xCC,0xD8,0x1B,0x47,0xAA,0xF2, +0x44,0xDA,0x4F,0xF9,0x03,0xE8,0xF0,0x14,0xCB,0x3F,0xF3,0x83,0xDE,0xD0,0xC1,0x54, +0xE3,0xB7,0xE8,0x0A,0x37,0x4D,0x8B,0x20,0x59,0x03,0x30,0x19,0xA1,0x2C,0xC8,0xBD, +0x11,0x1F,0xDF,0xAE,0xC9,0x4A,0xC5,0xF3,0x27,0x66,0x66,0x86,0xAC,0x68,0x91,0xFF, +0xD9,0xE6,0x53,0x1C,0x0F,0x8B,0x5C,0x69,0x65,0x0A,0x26,0xC8,0x1E,0x34,0xC3,0x5D, +0x51,0x7B,0xD7,0xA9,0x9C,0x06,0xA1,0x36,0xDD,0xD5,0x89,0x94,0xBC,0xD9,0xE4,0x2D, +0x0C,0x5E,0x09,0x6C,0x08,0x97,0x7C,0xA3,0x3D,0x7C,0x93,0xFF,0x3F,0xA1,0x14,0xA7, +0xCF,0xB5,0x5D,0xEB,0xDB,0xDB,0x1C,0xC4,0x76,0xDF,0x88,0xB9,0xBD,0x45,0x05,0x95, +0x1B,0xAE,0xFC,0x46,0x6A,0x4C,0xAF,0x48,0xE3,0xCE,0xAE,0x0F,0xD2,0x7E,0xEB,0xE6, +0x6C,0x9C,0x4F,0x81,0x6A,0x7A,0x64,0xAC,0xBB,0x3E,0xD5,0xE7,0xCB,0x76,0x2E,0xC5, +0xA7,0x48,0xC1,0x5C,0x90,0x0F,0xCB,0xC8,0x3F,0xFA,0xE6,0x32,0xE1,0x8D,0x1B,0x6F, +0xA4,0xE6,0x8E,0xD8,0xF9,0x29,0x48,0x8A,0xCE,0x73,0xFE,0x2C, +}; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { +/* subject:/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 */ +/* issuer :/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./CN=Go Daddy Root Certificate Authority - G2 */ +unsigned char XXX_certificate[969]={ +0x30,0x82,0x03,0xC5,0x30,0x82,0x02,0xAD,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x00, +0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30, +0x81,0x83,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31, +0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x08,0x13,0x07,0x41,0x72,0x69,0x7A,0x6F,0x6E, +0x61,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x07,0x13,0x0A,0x53,0x63,0x6F,0x74, +0x74,0x73,0x64,0x61,0x6C,0x65,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x13, +0x11,0x47,0x6F,0x44,0x61,0x64,0x64,0x79,0x2E,0x63,0x6F,0x6D,0x2C,0x20,0x49,0x6E, +0x63,0x2E,0x31,0x31,0x30,0x2F,0x06,0x03,0x55,0x04,0x03,0x13,0x28,0x47,0x6F,0x20, +0x44,0x61,0x64,0x64,0x79,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x65,0x72,0x74,0x69, +0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79, +0x20,0x2D,0x20,0x47,0x32,0x30,0x1E,0x17,0x0D,0x30,0x39,0x30,0x39,0x30,0x31,0x30, +0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x37,0x31,0x32,0x33,0x31,0x32,0x33, +0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0x83,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04, +0x06,0x13,0x02,0x55,0x53,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x08,0x13,0x07, +0x41,0x72,0x69,0x7A,0x6F,0x6E,0x61,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x07, +0x13,0x0A,0x53,0x63,0x6F,0x74,0x74,0x73,0x64,0x61,0x6C,0x65,0x31,0x1A,0x30,0x18, +0x06,0x03,0x55,0x04,0x0A,0x13,0x11,0x47,0x6F,0x44,0x61,0x64,0x64,0x79,0x2E,0x63, +0x6F,0x6D,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x31,0x30,0x2F,0x06,0x03,0x55,0x04, +0x03,0x13,0x28,0x47,0x6F,0x20,0x44,0x61,0x64,0x64,0x79,0x20,0x52,0x6F,0x6F,0x74, +0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74, +0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x32,0x30,0x82,0x01,0x22,0x30, +0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82, +0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xBF,0x71,0x62,0x08, +0xF1,0xFA,0x59,0x34,0xF7,0x1B,0xC9,0x18,0xA3,0xF7,0x80,0x49,0x58,0xE9,0x22,0x83, +0x13,0xA6,0xC5,0x20,0x43,0x01,0x3B,0x84,0xF1,0xE6,0x85,0x49,0x9F,0x27,0xEA,0xF6, +0x84,0x1B,0x4E,0xA0,0xB4,0xDB,0x70,0x98,0xC7,0x32,0x01,0xB1,0x05,0x3E,0x07,0x4E, +0xEE,0xF4,0xFA,0x4F,0x2F,0x59,0x30,0x22,0xE7,0xAB,0x19,0x56,0x6B,0xE2,0x80,0x07, +0xFC,0xF3,0x16,0x75,0x80,0x39,0x51,0x7B,0xE5,0xF9,0x35,0xB6,0x74,0x4E,0xA9,0x8D, +0x82,0x13,0xE4,0xB6,0x3F,0xA9,0x03,0x83,0xFA,0xA2,0xBE,0x8A,0x15,0x6A,0x7F,0xDE, +0x0B,0xC3,0xB6,0x19,0x14,0x05,0xCA,0xEA,0xC3,0xA8,0x04,0x94,0x3B,0x46,0x7C,0x32, +0x0D,0xF3,0x00,0x66,0x22,0xC8,0x8D,0x69,0x6D,0x36,0x8C,0x11,0x18,0xB7,0xD3,0xB2, +0x1C,0x60,0xB4,0x38,0xFA,0x02,0x8C,0xCE,0xD3,0xDD,0x46,0x07,0xDE,0x0A,0x3E,0xEB, +0x5D,0x7C,0xC8,0x7C,0xFB,0xB0,0x2B,0x53,0xA4,0x92,0x62,0x69,0x51,0x25,0x05,0x61, +0x1A,0x44,0x81,0x8C,0x2C,0xA9,0x43,0x96,0x23,0xDF,0xAC,0x3A,0x81,0x9A,0x0E,0x29, +0xC5,0x1C,0xA9,0xE9,0x5D,0x1E,0xB6,0x9E,0x9E,0x30,0x0A,0x39,0xCE,0xF1,0x88,0x80, +0xFB,0x4B,0x5D,0xCC,0x32,0xEC,0x85,0x62,0x43,0x25,0x34,0x02,0x56,0x27,0x01,0x91, +0xB4,0x3B,0x70,0x2A,0x3F,0x6E,0xB1,0xE8,0x9C,0x88,0x01,0x7D,0x9F,0xD4,0xF9,0xDB, +0x53,0x6D,0x60,0x9D,0xBF,0x2C,0xE7,0x58,0xAB,0xB8,0x5F,0x46,0xFC,0xCE,0xC4,0x1B, +0x03,0x3C,0x09,0xEB,0x49,0x31,0x5C,0x69,0x46,0xB3,0xE0,0x47,0x02,0x03,0x01,0x00, +0x01,0xA3,0x42,0x30,0x40,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04, +0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF, +0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04, +0x14,0x3A,0x9A,0x85,0x07,0x10,0x67,0x28,0xB6,0xEF,0xF6,0xBD,0x05,0x41,0x6E,0x20, +0xC1,0x94,0xDA,0x0F,0xDE,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, +0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x99,0xDB,0x5D,0x79,0xD5,0xF9,0x97, +0x59,0x67,0x03,0x61,0xF1,0x7E,0x3B,0x06,0x31,0x75,0x2D,0xA1,0x20,0x8E,0x4F,0x65, +0x87,0xB4,0xF7,0xA6,0x9C,0xBC,0xD8,0xE9,0x2F,0xD0,0xDB,0x5A,0xEE,0xCF,0x74,0x8C, +0x73,0xB4,0x38,0x42,0xDA,0x05,0x7B,0xF8,0x02,0x75,0xB8,0xFD,0xA5,0xB1,0xD7,0xAE, +0xF6,0xD7,0xDE,0x13,0xCB,0x53,0x10,0x7E,0x8A,0x46,0xD1,0x97,0xFA,0xB7,0x2E,0x2B, +0x11,0xAB,0x90,0xB0,0x27,0x80,0xF9,0xE8,0x9F,0x5A,0xE9,0x37,0x9F,0xAB,0xE4,0xDF, +0x6C,0xB3,0x85,0x17,0x9D,0x3D,0xD9,0x24,0x4F,0x79,0x91,0x35,0xD6,0x5F,0x04,0xEB, +0x80,0x83,0xAB,0x9A,0x02,0x2D,0xB5,0x10,0xF4,0xD8,0x90,0xC7,0x04,0x73,0x40,0xED, +0x72,0x25,0xA0,0xA9,0x9F,0xEC,0x9E,0xAB,0x68,0x12,0x99,0x57,0xC6,0x8F,0x12,0x3A, +0x09,0xA4,0xBD,0x44,0xFD,0x06,0x15,0x37,0xC1,0x9B,0xE4,0x32,0xA3,0xED,0x38,0xE8, +0xD8,0x64,0xF3,0x2C,0x7E,0x14,0xFC,0x02,0xEA,0x9F,0xCD,0xFF,0x07,0x68,0x17,0xDB, +0x22,0x90,0x38,0x2D,0x7A,0x8D,0xD1,0x54,0xF1,0x69,0xE3,0x5F,0x33,0xCA,0x7A,0x3D, +0x7B,0x0A,0xE3,0xCA,0x7F,0x5F,0x39,0xE5,0xE2,0x75,0xBA,0xC5,0x76,0x18,0x33,0xCE, +0x2C,0xF0,0x2F,0x4C,0xAD,0xF7,0xB1,0xE7,0xCE,0x4F,0xA8,0xC4,0x9B,0x4A,0x54,0x06, +0xC5,0x7F,0x7D,0xD5,0x08,0x0F,0xE2,0x1C,0xFE,0x7E,0x17,0xB8,0xAC,0x5E,0xF6,0xD4, +0x16,0xB2,0x43,0x09,0x0C,0x4D,0xF6,0xA7,0x6B,0xB4,0x99,0x84,0x65,0xCA,0x7A,0x88, +0xE2,0xE2,0x44,0xBE,0x5C,0xF7,0xEA,0x1C,0xF5, +}; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { +/* subject:/C=US/O=SecureTrust Corporation/CN=SecureTrust CA */ +/* issuer :/C=US/O=SecureTrust Corporation/CN=SecureTrust CA */ +unsigned char XXX_certificate[956]={ +0x30,0x82,0x03,0xB8,0x30,0x82,0x02,0xA0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x0C, +0xF0,0x8E,0x5C,0x08,0x16,0xA5,0xAD,0x42,0x7F,0xF0,0xEB,0x27,0x18,0x59,0xD0,0x30, +0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x48, +0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x20,0x30, +0x1E,0x06,0x03,0x55,0x04,0x0A,0x13,0x17,0x53,0x65,0x63,0x75,0x72,0x65,0x54,0x72, +0x75,0x73,0x74,0x20,0x43,0x6F,0x72,0x70,0x6F,0x72,0x61,0x74,0x69,0x6F,0x6E,0x31, +0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x03,0x13,0x0E,0x53,0x65,0x63,0x75,0x72,0x65, +0x54,0x72,0x75,0x73,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x31, +0x30,0x37,0x31,0x39,0x33,0x31,0x31,0x38,0x5A,0x17,0x0D,0x32,0x39,0x31,0x32,0x33, +0x31,0x31,0x39,0x34,0x30,0x35,0x35,0x5A,0x30,0x48,0x31,0x0B,0x30,0x09,0x06,0x03, +0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x0A, +0x13,0x17,0x53,0x65,0x63,0x75,0x72,0x65,0x54,0x72,0x75,0x73,0x74,0x20,0x43,0x6F, +0x72,0x70,0x6F,0x72,0x61,0x74,0x69,0x6F,0x6E,0x31,0x17,0x30,0x15,0x06,0x03,0x55, +0x04,0x03,0x13,0x0E,0x53,0x65,0x63,0x75,0x72,0x65,0x54,0x72,0x75,0x73,0x74,0x20, +0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, +0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82, +0x01,0x01,0x00,0xAB,0xA4,0x81,0xE5,0x95,0xCD,0xF5,0xF6,0x14,0x8E,0xC2,0x4F,0xCA, +0xD4,0xE2,0x78,0x95,0x58,0x9C,0x41,0xE1,0x0D,0x99,0x40,0x24,0x17,0x39,0x91,0x33, +0x66,0xE9,0xBE,0xE1,0x83,0xAF,0x62,0x5C,0x89,0xD1,0xFC,0x24,0x5B,0x61,0xB3,0xE0, +0x11,0x11,0x41,0x1C,0x1D,0x6E,0xF0,0xB8,0xBB,0xF8,0xDE,0xA7,0x81,0xBA,0xA6,0x48, +0xC6,0x9F,0x1D,0xBD,0xBE,0x8E,0xA9,0x41,0x3E,0xB8,0x94,0xED,0x29,0x1A,0xD4,0x8E, +0xD2,0x03,0x1D,0x03,0xEF,0x6D,0x0D,0x67,0x1C,0x57,0xD7,0x06,0xAD,0xCA,0xC8,0xF5, +0xFE,0x0E,0xAF,0x66,0x25,0x48,0x04,0x96,0x0B,0x5D,0xA3,0xBA,0x16,0xC3,0x08,0x4F, +0xD1,0x46,0xF8,0x14,0x5C,0xF2,0xC8,0x5E,0x01,0x99,0x6D,0xFD,0x88,0xCC,0x86,0xA8, +0xC1,0x6F,0x31,0x42,0x6C,0x52,0x3E,0x68,0xCB,0xF3,0x19,0x34,0xDF,0xBB,0x87,0x18, +0x56,0x80,0x26,0xC4,0xD0,0xDC,0xC0,0x6F,0xDF,0xDE,0xA0,0xC2,0x91,0x16,0xA0,0x64, +0x11,0x4B,0x44,0xBC,0x1E,0xF6,0xE7,0xFA,0x63,0xDE,0x66,0xAC,0x76,0xA4,0x71,0xA3, +0xEC,0x36,0x94,0x68,0x7A,0x77,0xA4,0xB1,0xE7,0x0E,0x2F,0x81,0x7A,0xE2,0xB5,0x72, +0x86,0xEF,0xA2,0x6B,0x8B,0xF0,0x0F,0xDB,0xD3,0x59,0x3F,0xBA,0x72,0xBC,0x44,0x24, +0x9C,0xE3,0x73,0xB3,0xF7,0xAF,0x57,0x2F,0x42,0x26,0x9D,0xA9,0x74,0xBA,0x00,0x52, +0xF2,0x4B,0xCD,0x53,0x7C,0x47,0x0B,0x36,0x85,0x0E,0x66,0xA9,0x08,0x97,0x16,0x34, +0x57,0xC1,0x66,0xF7,0x80,0xE3,0xED,0x70,0x54,0xC7,0x93,0xE0,0x2E,0x28,0x15,0x59, +0x87,0xBA,0xBB,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x9D,0x30,0x81,0x9A,0x30,0x13, +0x06,0x09,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x04,0x06,0x1E,0x04,0x00, +0x43,0x00,0x41,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x01,0x86, +0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01, +0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x42,0x32,0xB6,0x16, +0xFA,0x04,0xFD,0xFE,0x5D,0x4B,0x7A,0xC3,0xFD,0xF7,0x4C,0x40,0x1D,0x5A,0x43,0xAF, +0x30,0x34,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2D,0x30,0x2B,0x30,0x29,0xA0,0x27,0xA0, +0x25,0x86,0x23,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x73,0x65, +0x63,0x75,0x72,0x65,0x74,0x72,0x75,0x73,0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x53,0x54, +0x43,0x41,0x2E,0x63,0x72,0x6C,0x30,0x10,0x06,0x09,0x2B,0x06,0x01,0x04,0x01,0x82, +0x37,0x15,0x01,0x04,0x03,0x02,0x01,0x00,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, +0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x30,0xED,0x4F,0x4A, +0xE1,0x58,0x3A,0x52,0x72,0x5B,0xB5,0xA6,0xA3,0x65,0x18,0xA6,0xBB,0x51,0x3B,0x77, +0xE9,0x9D,0xEA,0xD3,0x9F,0x5C,0xE0,0x45,0x65,0x7B,0x0D,0xCA,0x5B,0xE2,0x70,0x50, +0xB2,0x94,0x05,0x14,0xAE,0x49,0xC7,0x8D,0x41,0x07,0x12,0x73,0x94,0x7E,0x0C,0x23, +0x21,0xFD,0xBC,0x10,0x7F,0x60,0x10,0x5A,0x72,0xF5,0x98,0x0E,0xAC,0xEC,0xB9,0x7F, +0xDD,0x7A,0x6F,0x5D,0xD3,0x1C,0xF4,0xFF,0x88,0x05,0x69,0x42,0xA9,0x05,0x71,0xC8, +0xB7,0xAC,0x26,0xE8,0x2E,0xB4,0x8C,0x6A,0xFF,0x71,0xDC,0xB8,0xB1,0xDF,0x99,0xBC, +0x7C,0x21,0x54,0x2B,0xE4,0x58,0xA2,0xBB,0x57,0x29,0xAE,0x9E,0xA9,0xA3,0x19,0x26, +0x0F,0x99,0x2E,0x08,0xB0,0xEF,0xFD,0x69,0xCF,0x99,0x1A,0x09,0x8D,0xE3,0xA7,0x9F, +0x2B,0xC9,0x36,0x34,0x7B,0x24,0xB3,0x78,0x4C,0x95,0x17,0xA4,0x06,0x26,0x1E,0xB6, +0x64,0x52,0x36,0x5F,0x60,0x67,0xD9,0x9C,0xC5,0x05,0x74,0x0B,0xE7,0x67,0x23,0xD2, +0x08,0xFC,0x88,0xE9,0xAE,0x8B,0x7F,0xE1,0x30,0xF4,0x37,0x7E,0xFD,0xC6,0x32,0xDA, +0x2D,0x9E,0x44,0x30,0x30,0x6C,0xEE,0x07,0xDE,0xD2,0x34,0xFC,0xD2,0xFF,0x40,0xF6, +0x4B,0xF4,0x66,0x46,0x06,0x54,0xA6,0xF2,0x32,0x0A,0x63,0x26,0x30,0x6B,0x9B,0xD1, +0xDC,0x8B,0x47,0xBA,0xE1,0xB9,0xD5,0x62,0xD0,0xA2,0xA0,0xF4,0x67,0x05,0x78,0x29, +0x63,0x1A,0x6F,0x04,0xD6,0xF8,0xC6,0x4C,0xA3,0x9A,0xB1,0x37,0xB4,0x8D,0xE5,0x28, +0x4B,0x1D,0x9E,0x2C,0xC2,0xB8,0x68,0xBC,0xED,0x02,0xEE,0x31, +}; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { +/* subject:/C=US/O=SecureTrust Corporation/CN=SecureTrust CA */ +/* issuer :/C=US/O=SecureTrust Corporation/CN=SecureTrust CA */ +unsigned char XXX_certificate[956]={ +0x30,0x82,0x03,0xB8,0x30,0x82,0x02,0xA0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x0C, +0xF0,0x8E,0x5C,0x08,0x16,0xA5,0xAD,0x42,0x7F,0xF0,0xEB,0x27,0x18,0x59,0xD0,0x30, +0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x48, +0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x20,0x30, +0x1E,0x06,0x03,0x55,0x04,0x0A,0x13,0x17,0x53,0x65,0x63,0x75,0x72,0x65,0x54,0x72, +0x75,0x73,0x74,0x20,0x43,0x6F,0x72,0x70,0x6F,0x72,0x61,0x74,0x69,0x6F,0x6E,0x31, +0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x03,0x13,0x0E,0x53,0x65,0x63,0x75,0x72,0x65, +0x54,0x72,0x75,0x73,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x31,0x31, +0x30,0x37,0x31,0x39,0x33,0x31,0x31,0x38,0x5A,0x17,0x0D,0x32,0x39,0x31,0x32,0x33, +0x31,0x31,0x39,0x34,0x30,0x35,0x35,0x5A,0x30,0x48,0x31,0x0B,0x30,0x09,0x06,0x03, +0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x0A, +0x13,0x17,0x53,0x65,0x63,0x75,0x72,0x65,0x54,0x72,0x75,0x73,0x74,0x20,0x43,0x6F, +0x72,0x70,0x6F,0x72,0x61,0x74,0x69,0x6F,0x6E,0x31,0x17,0x30,0x15,0x06,0x03,0x55, +0x04,0x03,0x13,0x0E,0x53,0x65,0x63,0x75,0x72,0x65,0x54,0x72,0x75,0x73,0x74,0x20, +0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, +0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A,0x02,0x82, +0x01,0x01,0x00,0xAB,0xA4,0x81,0xE5,0x95,0xCD,0xF5,0xF6,0x14,0x8E,0xC2,0x4F,0xCA, +0xD4,0xE2,0x78,0x95,0x58,0x9C,0x41,0xE1,0x0D,0x99,0x40,0x24,0x17,0x39,0x91,0x33, +0x66,0xE9,0xBE,0xE1,0x83,0xAF,0x62,0x5C,0x89,0xD1,0xFC,0x24,0x5B,0x61,0xB3,0xE0, +0x11,0x11,0x41,0x1C,0x1D,0x6E,0xF0,0xB8,0xBB,0xF8,0xDE,0xA7,0x81,0xBA,0xA6,0x48, +0xC6,0x9F,0x1D,0xBD,0xBE,0x8E,0xA9,0x41,0x3E,0xB8,0x94,0xED,0x29,0x1A,0xD4,0x8E, +0xD2,0x03,0x1D,0x03,0xEF,0x6D,0x0D,0x67,0x1C,0x57,0xD7,0x06,0xAD,0xCA,0xC8,0xF5, +0xFE,0x0E,0xAF,0x66,0x25,0x48,0x04,0x96,0x0B,0x5D,0xA3,0xBA,0x16,0xC3,0x08,0x4F, +0xD1,0x46,0xF8,0x14,0x5C,0xF2,0xC8,0x5E,0x01,0x99,0x6D,0xFD,0x88,0xCC,0x86,0xA8, +0xC1,0x6F,0x31,0x42,0x6C,0x52,0x3E,0x68,0xCB,0xF3,0x19,0x34,0xDF,0xBB,0x87,0x18, +0x56,0x80,0x26,0xC4,0xD0,0xDC,0xC0,0x6F,0xDF,0xDE,0xA0,0xC2,0x91,0x16,0xA0,0x64, +0x11,0x4B,0x44,0xBC,0x1E,0xF6,0xE7,0xFA,0x63,0xDE,0x66,0xAC,0x76,0xA4,0x71,0xA3, +0xEC,0x36,0x94,0x68,0x7A,0x77,0xA4,0xB1,0xE7,0x0E,0x2F,0x81,0x7A,0xE2,0xB5,0x72, +0x86,0xEF,0xA2,0x6B,0x8B,0xF0,0x0F,0xDB,0xD3,0x59,0x3F,0xBA,0x72,0xBC,0x44,0x24, +0x9C,0xE3,0x73,0xB3,0xF7,0xAF,0x57,0x2F,0x42,0x26,0x9D,0xA9,0x74,0xBA,0x00,0x52, +0xF2,0x4B,0xCD,0x53,0x7C,0x47,0x0B,0x36,0x85,0x0E,0x66,0xA9,0x08,0x97,0x16,0x34, +0x57,0xC1,0x66,0xF7,0x80,0xE3,0xED,0x70,0x54,0xC7,0x93,0xE0,0x2E,0x28,0x15,0x59, +0x87,0xBA,0xBB,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x9D,0x30,0x81,0x9A,0x30,0x13, +0x06,0x09,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x04,0x06,0x1E,0x04,0x00, +0x43,0x00,0x41,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x01,0x86, +0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01, +0xFF,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x42,0x32,0xB6,0x16, +0xFA,0x04,0xFD,0xFE,0x5D,0x4B,0x7A,0xC3,0xFD,0xF7,0x4C,0x40,0x1D,0x5A,0x43,0xAF, +0x30,0x34,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2D,0x30,0x2B,0x30,0x29,0xA0,0x27,0xA0, +0x25,0x86,0x23,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x73,0x65, +0x63,0x75,0x72,0x65,0x74,0x72,0x75,0x73,0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x53,0x54, +0x43,0x41,0x2E,0x63,0x72,0x6C,0x30,0x10,0x06,0x09,0x2B,0x06,0x01,0x04,0x01,0x82, +0x37,0x15,0x01,0x04,0x03,0x02,0x01,0x00,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, +0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x30,0xED,0x4F,0x4A, +0xE1,0x58,0x3A,0x52,0x72,0x5B,0xB5,0xA6,0xA3,0x65,0x18,0xA6,0xBB,0x51,0x3B,0x77, +0xE9,0x9D,0xEA,0xD3,0x9F,0x5C,0xE0,0x45,0x65,0x7B,0x0D,0xCA,0x5B,0xE2,0x70,0x50, +0xB2,0x94,0x05,0x14,0xAE,0x49,0xC7,0x8D,0x41,0x07,0x12,0x73,0x94,0x7E,0x0C,0x23, +0x21,0xFD,0xBC,0x10,0x7F,0x60,0x10,0x5A,0x72,0xF5,0x98,0x0E,0xAC,0xEC,0xB9,0x7F, +0xDD,0x7A,0x6F,0x5D,0xD3,0x1C,0xF4,0xFF,0x88,0x05,0x69,0x42,0xA9,0x05,0x71,0xC8, +0xB7,0xAC,0x26,0xE8,0x2E,0xB4,0x8C,0x6A,0xFF,0x71,0xDC,0xB8,0xB1,0xDF,0x99,0xBC, +0x7C,0x21,0x54,0x2B,0xE4,0x58,0xA2,0xBB,0x57,0x29,0xAE,0x9E,0xA9,0xA3,0x19,0x26, +0x0F,0x99,0x2E,0x08,0xB0,0xEF,0xFD,0x69,0xCF,0x99,0x1A,0x09,0x8D,0xE3,0xA7,0x9F, +0x2B,0xC9,0x36,0x34,0x7B,0x24,0xB3,0x78,0x4C,0x95,0x17,0xA4,0x06,0x26,0x1E,0xB6, +0x64,0x52,0x36,0x5F,0x60,0x67,0xD9,0x9C,0xC5,0x05,0x74,0x0B,0xE7,0x67,0x23,0xD2, +0x08,0xFC,0x88,0xE9,0xAE,0x8B,0x7F,0xE1,0x30,0xF4,0x37,0x7E,0xFD,0xC6,0x32,0xDA, +0x2D,0x9E,0x44,0x30,0x30,0x6C,0xEE,0x07,0xDE,0xD2,0x34,0xFC,0xD2,0xFF,0x40,0xF6, +0x4B,0xF4,0x66,0x46,0x06,0x54,0xA6,0xF2,0x32,0x0A,0x63,0x26,0x30,0x6B,0x9B,0xD1, +0xDC,0x8B,0x47,0xBA,0xE1,0xB9,0xD5,0x62,0xD0,0xA2,0xA0,0xF4,0x67,0x05,0x78,0x29, +0x63,0x1A,0x6F,0x04,0xD6,0xF8,0xC6,0x4C,0xA3,0x9A,0xB1,0x37,0xB4,0x8D,0xE5,0x28, +0x4B,0x1D,0x9E,0x2C,0xC2,0xB8,0x68,0xBC,0xED,0x02,0xEE,0x31, +}; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { +/* subject:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=VeriSign Trust Network */ +/* issuer :/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=VeriSign Trust Network */ +unsigned char XXX_certificate[774]={ +0x30,0x82,0x03,0x02,0x30,0x82,0x02,0x6B,0x02,0x10,0x7D,0xD9,0xFE,0x07,0xCF,0xA8, +0x1E,0xB7,0x10,0x79,0x67,0xFB,0xA7,0x89,0x34,0xC6,0x30,0x0D,0x06,0x09,0x2A,0x86, +0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0xC1,0x31,0x0B,0x30,0x09, +0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55, +0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E, +0x63,0x2E,0x31,0x3C,0x30,0x3A,0x06,0x03,0x55,0x04,0x0B,0x13,0x33,0x43,0x6C,0x61, +0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D, +0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F, +0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x32, +0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31,0x28,0x63,0x29,0x20,0x31, +0x39,0x39,0x38,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E, +0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69, +0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x1F,0x30,0x1D, +0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20, +0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x30,0x1E,0x17, +0x0D,0x39,0x38,0x30,0x35,0x31,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D, +0x32,0x38,0x30,0x38,0x30,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0xC1, +0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30, +0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E, +0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x3C,0x30,0x3A,0x06,0x03,0x55,0x04,0x0B,0x13, +0x33,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6C,0x69,0x63,0x20, +0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63, +0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20, +0x2D,0x20,0x47,0x32,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31,0x28, +0x63,0x29,0x20,0x31,0x39,0x39,0x38,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E, +0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74, +0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79, +0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56,0x65,0x72,0x69,0x53, +0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72, +0x6B,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, +0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xCC,0x5E, +0xD1,0x11,0x5D,0x5C,0x69,0xD0,0xAB,0xD3,0xB9,0x6A,0x4C,0x99,0x1F,0x59,0x98,0x30, +0x8E,0x16,0x85,0x20,0x46,0x6D,0x47,0x3F,0xD4,0x85,0x20,0x84,0xE1,0x6D,0xB3,0xF8, +0xA4,0xED,0x0C,0xF1,0x17,0x0F,0x3B,0xF9,0xA7,0xF9,0x25,0xD7,0xC1,0xCF,0x84,0x63, +0xF2,0x7C,0x63,0xCF,0xA2,0x47,0xF2,0xC6,0x5B,0x33,0x8E,0x64,0x40,0x04,0x68,0xC1, +0x80,0xB9,0x64,0x1C,0x45,0x77,0xC7,0xD8,0x6E,0xF5,0x95,0x29,0x3C,0x50,0xE8,0x34, +0xD7,0x78,0x1F,0xA8,0xBA,0x6D,0x43,0x91,0x95,0x8F,0x45,0x57,0x5E,0x7E,0xC5,0xFB, +0xCA,0xA4,0x04,0xEB,0xEA,0x97,0x37,0x54,0x30,0x6F,0xBB,0x01,0x47,0x32,0x33,0xCD, +0xDC,0x57,0x9B,0x64,0x69,0x61,0xF8,0x9B,0x1D,0x1C,0x89,0x4F,0x5C,0x67,0x02,0x03, +0x01,0x00,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, +0x05,0x00,0x03,0x81,0x81,0x00,0x51,0x4D,0xCD,0xBE,0x5C,0xCB,0x98,0x19,0x9C,0x15, +0xB2,0x01,0x39,0x78,0x2E,0x4D,0x0F,0x67,0x70,0x70,0x99,0xC6,0x10,0x5A,0x94,0xA4, +0x53,0x4D,0x54,0x6D,0x2B,0xAF,0x0D,0x5D,0x40,0x8B,0x64,0xD3,0xD7,0xEE,0xDE,0x56, +0x61,0x92,0x5F,0xA6,0xC4,0x1D,0x10,0x61,0x36,0xD3,0x2C,0x27,0x3C,0xE8,0x29,0x09, +0xB9,0x11,0x64,0x74,0xCC,0xB5,0x73,0x9F,0x1C,0x48,0xA9,0xBC,0x61,0x01,0xEE,0xE2, +0x17,0xA6,0x0C,0xE3,0x40,0x08,0x3B,0x0E,0xE7,0xEB,0x44,0x73,0x2A,0x9A,0xF1,0x69, +0x92,0xEF,0x71,0x14,0xC3,0x39,0xAC,0x71,0xA7,0x91,0x09,0x6F,0xE4,0x71,0x06,0xB3, +0xBA,0x59,0x57,0x26,0x79,0x00,0xF6,0xF8,0x0D,0xA2,0x33,0x30,0x28,0xD4,0xAA,0x58, +0xA0,0x9D,0x9D,0x69,0x91,0xFD, +}; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { +/* subject:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 1999 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G3 */ +/* issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 1999 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G3 */ +unsigned char XXX_certificate[1054]={ +0x30,0x82,0x04,0x1A,0x30,0x82,0x03,0x02,0x02,0x11,0x00,0x9B,0x7E,0x06,0x49,0xA3, +0x3E,0x62,0xB9,0xD5,0xEE,0x90,0x48,0x71,0x29,0xEF,0x57,0x30,0x0D,0x06,0x09,0x2A, +0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0xCA,0x31,0x0B,0x30, +0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03, +0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49, +0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56,0x65, +0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74, +0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31,0x28, +0x63,0x29,0x20,0x31,0x39,0x39,0x39,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E, +0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74, +0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79, +0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56,0x65,0x72,0x69,0x53, +0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6C, +0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69, +0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69, +0x74,0x79,0x20,0x2D,0x20,0x47,0x33,0x30,0x1E,0x17,0x0D,0x39,0x39,0x31,0x30,0x30, +0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x36,0x30,0x37,0x31,0x36, +0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0xCA,0x31,0x0B,0x30,0x09,0x06,0x03, +0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0A, +0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E, +0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56,0x65,0x72,0x69,0x53, +0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72, +0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31,0x28,0x63,0x29,0x20, +0x31,0x39,0x39,0x39,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49, +0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F,0x72, +0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x45,0x30, +0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E, +0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6C,0x69,0x63,0x20, +0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63, +0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x20, +0x2D,0x20,0x47,0x33,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, +0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01,0x0A, +0x02,0x82,0x01,0x01,0x00,0xCB,0xBA,0x9C,0x52,0xFC,0x78,0x1F,0x1A,0x1E,0x6F,0x1B, +0x37,0x73,0xBD,0xF8,0xC9,0x6B,0x94,0x12,0x30,0x4F,0xF0,0x36,0x47,0xF5,0xD0,0x91, +0x0A,0xF5,0x17,0xC8,0xA5,0x61,0xC1,0x16,0x40,0x4D,0xFB,0x8A,0x61,0x90,0xE5,0x76, +0x20,0xC1,0x11,0x06,0x7D,0xAB,0x2C,0x6E,0xA6,0xF5,0x11,0x41,0x8E,0xFA,0x2D,0xAD, +0x2A,0x61,0x59,0xA4,0x67,0x26,0x4C,0xD0,0xE8,0xBC,0x52,0x5B,0x70,0x20,0x04,0x58, +0xD1,0x7A,0xC9,0xA4,0x69,0xBC,0x83,0x17,0x64,0xAD,0x05,0x8B,0xBC,0xD0,0x58,0xCE, +0x8D,0x8C,0xF5,0xEB,0xF0,0x42,0x49,0x0B,0x9D,0x97,0x27,0x67,0x32,0x6E,0xE1,0xAE, +0x93,0x15,0x1C,0x70,0xBC,0x20,0x4D,0x2F,0x18,0xDE,0x92,0x88,0xE8,0x6C,0x85,0x57, +0x11,0x1A,0xE9,0x7E,0xE3,0x26,0x11,0x54,0xA2,0x45,0x96,0x55,0x83,0xCA,0x30,0x89, +0xE8,0xDC,0xD8,0xA3,0xED,0x2A,0x80,0x3F,0x7F,0x79,0x65,0x57,0x3E,0x15,0x20,0x66, +0x08,0x2F,0x95,0x93,0xBF,0xAA,0x47,0x2F,0xA8,0x46,0x97,0xF0,0x12,0xE2,0xFE,0xC2, +0x0A,0x2B,0x51,0xE6,0x76,0xE6,0xB7,0x46,0xB7,0xE2,0x0D,0xA6,0xCC,0xA8,0xC3,0x4C, +0x59,0x55,0x89,0xE6,0xE8,0x53,0x5C,0x1C,0xEA,0x9D,0xF0,0x62,0x16,0x0B,0xA7,0xC9, +0x5F,0x0C,0xF0,0xDE,0xC2,0x76,0xCE,0xAF,0xF7,0x6A,0xF2,0xFA,0x41,0xA6,0xA2,0x33, +0x14,0xC9,0xE5,0x7A,0x63,0xD3,0x9E,0x62,0x37,0xD5,0x85,0x65,0x9E,0x0E,0xE6,0x53, +0x24,0x74,0x1B,0x5E,0x1D,0x12,0x53,0x5B,0xC7,0x2C,0xE7,0x83,0x49,0x3B,0x15,0xAE, +0x8A,0x68,0xB9,0x57,0x97,0x02,0x03,0x01,0x00,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86, +0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x11,0x14, +0x96,0xC1,0xAB,0x92,0x08,0xF7,0x3F,0x2F,0xC9,0xB2,0xFE,0xE4,0x5A,0x9F,0x64,0xDE, +0xDB,0x21,0x4F,0x86,0x99,0x34,0x76,0x36,0x57,0xDD,0xD0,0x15,0x2F,0xC5,0xAD,0x7F, +0x15,0x1F,0x37,0x62,0x73,0x3E,0xD4,0xE7,0x5F,0xCE,0x17,0x03,0xDB,0x35,0xFA,0x2B, +0xDB,0xAE,0x60,0x09,0x5F,0x1E,0x5F,0x8F,0x6E,0xBB,0x0B,0x3D,0xEA,0x5A,0x13,0x1E, +0x0C,0x60,0x6F,0xB5,0xC0,0xB5,0x23,0x22,0x2E,0x07,0x0B,0xCB,0xA9,0x74,0xCB,0x47, +0xBB,0x1D,0xC1,0xD7,0xA5,0x6B,0xCC,0x2F,0xD2,0x42,0xFD,0x49,0xDD,0xA7,0x89,0xCF, +0x53,0xBA,0xDA,0x00,0x5A,0x28,0xBF,0x82,0xDF,0xF8,0xBA,0x13,0x1D,0x50,0x86,0x82, +0xFD,0x8E,0x30,0x8F,0x29,0x46,0xB0,0x1E,0x3D,0x35,0xDA,0x38,0x62,0x16,0x18,0x4A, +0xAD,0xE6,0xB6,0x51,0x6C,0xDE,0xAF,0x62,0xEB,0x01,0xD0,0x1E,0x24,0xFE,0x7A,0x8F, +0x12,0x1A,0x12,0x68,0xB8,0xFB,0x66,0x99,0x14,0x14,0x45,0x5C,0xAE,0xE7,0xAE,0x69, +0x17,0x81,0x2B,0x5A,0x37,0xC9,0x5E,0x2A,0xF4,0xC6,0xE2,0xA1,0x5C,0x54,0x9B,0xA6, +0x54,0x00,0xCF,0xF0,0xF1,0xC1,0xC7,0x98,0x30,0x1A,0x3B,0x36,0x16,0xDB,0xA3,0x6E, +0xEA,0xFD,0xAD,0xB2,0xC2,0xDA,0xEF,0x02,0x47,0x13,0x8A,0xC0,0xF1,0xB3,0x31,0xAD, +0x4F,0x1C,0xE1,0x4F,0x9C,0xAF,0x0F,0x0C,0x9D,0xF7,0x78,0x0D,0xD8,0xF4,0x35,0x56, +0x80,0xDA,0xB7,0x6D,0x17,0x8F,0x9D,0x1E,0x81,0x64,0xE1,0xFE,0xC5,0x45,0xBA,0xAD, +0x6B,0xB9,0x0A,0x7A,0x4E,0x4F,0x4B,0x84,0xEE,0x4B,0xF1,0x7D,0xDD,0x11, +}; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { +/* subject:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2007 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G4 */ +/* issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2007 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G4 */ +unsigned char XXX_certificate[904]={ +0x30,0x82,0x03,0x84,0x30,0x82,0x03,0x0A,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x2F, +0x80,0xFE,0x23,0x8C,0x0E,0x22,0x0F,0x48,0x67,0x12,0x28,0x91,0x87,0xAC,0xB3,0x30, +0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,0x30,0x81,0xCA,0x31,0x0B, +0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06, +0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20, +0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56, +0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65, +0x74,0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31, +0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x37,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67, +0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75, +0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C, +0x79,0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56,0x65,0x72,0x69, +0x53,0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62, +0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74, +0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72, +0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x34,0x30,0x1E,0x17,0x0D,0x30,0x37,0x31,0x31, +0x30,0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x38,0x30,0x31,0x31, +0x38,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0xCA,0x31,0x0B,0x30,0x09,0x06, +0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04, +0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63, +0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56,0x65,0x72,0x69, +0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65,0x74,0x77,0x6F, +0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31,0x28,0x63,0x29, +0x20,0x32,0x30,0x30,0x37,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20, +0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F, +0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x45, +0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56,0x65,0x72,0x69,0x53,0x69,0x67, +0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6C,0x69,0x63, +0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69, +0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79, +0x20,0x2D,0x20,0x47,0x34,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D, +0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0xA7,0x56,0x7A, +0x7C,0x52,0xDA,0x64,0x9B,0x0E,0x2D,0x5C,0xD8,0x5E,0xAC,0x92,0x3D,0xFE,0x01,0xE6, +0x19,0x4A,0x3D,0x14,0x03,0x4B,0xFA,0x60,0x27,0x20,0xD9,0x83,0x89,0x69,0xFA,0x54, +0xC6,0x9A,0x18,0x5E,0x55,0x2A,0x64,0xDE,0x06,0xF6,0x8D,0x4A,0x3B,0xAD,0x10,0x3C, +0x65,0x3D,0x90,0x88,0x04,0x89,0xE0,0x30,0x61,0xB3,0xAE,0x5D,0x01,0xA7,0x7B,0xDE, +0x7C,0xB2,0xBE,0xCA,0x65,0x61,0x00,0x86,0xAE,0xDA,0x8F,0x7B,0xD0,0x89,0xAD,0x4D, +0x1D,0x59,0x9A,0x41,0xB1,0xBC,0x47,0x80,0xDC,0x9E,0x62,0xC3,0xF9,0xA3,0x81,0xB2, +0x30,0x81,0xAF,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30, +0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04, +0x03,0x02,0x01,0x06,0x30,0x6D,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0C, +0x04,0x61,0x30,0x5F,0xA1,0x5D,0xA0,0x5B,0x30,0x59,0x30,0x57,0x30,0x55,0x16,0x09, +0x69,0x6D,0x61,0x67,0x65,0x2F,0x67,0x69,0x66,0x30,0x21,0x30,0x1F,0x30,0x07,0x06, +0x05,0x2B,0x0E,0x03,0x02,0x1A,0x04,0x14,0x8F,0xE5,0xD3,0x1A,0x86,0xAC,0x8D,0x8E, +0x6B,0xC3,0xCF,0x80,0x6A,0xD4,0x48,0x18,0x2C,0x7B,0x19,0x2E,0x30,0x25,0x16,0x23, +0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6C,0x6F,0x67,0x6F,0x2E,0x76,0x65,0x72,0x69, +0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,0x2F,0x76,0x73,0x6C,0x6F,0x67,0x6F,0x2E, +0x67,0x69,0x66,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xB3,0x16, +0x91,0xFD,0xEE,0xA6,0x6E,0xE4,0xB5,0x2E,0x49,0x8F,0x87,0x78,0x81,0x80,0xEC,0xE5, +0xB1,0xB5,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,0x03,0x68, +0x00,0x30,0x65,0x02,0x30,0x66,0x21,0x0C,0x18,0x26,0x60,0x5A,0x38,0x7B,0x56,0x42, +0xE0,0xA7,0xFC,0x36,0x84,0x51,0x91,0x20,0x2C,0x76,0x4D,0x43,0x3D,0xC4,0x1D,0x84, +0x23,0xD0,0xAC,0xD6,0x7C,0x35,0x06,0xCE,0xCD,0x69,0xBD,0x90,0x0D,0xDB,0x6C,0x48, +0x42,0x1D,0x0E,0xAA,0x42,0x02,0x31,0x00,0x9C,0x3D,0x48,0x39,0x23,0x39,0x58,0x1A, +0x15,0x12,0x59,0x6A,0x9E,0xEF,0xD5,0x59,0xB2,0x1D,0x52,0x2C,0x99,0x71,0xCD,0xC7, +0x29,0xDF,0x1B,0x2A,0x61,0x7B,0x71,0xD1,0xDE,0xF3,0xC0,0xE5,0x0D,0x3A,0x4A,0xAA, +0x2D,0xA7,0xD8,0x86,0x2A,0xDD,0x2E,0x10, +}; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { +/* subject:/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5 */ +/* issuer :/C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5 */ +unsigned char XXX_certificate[1239]={ +0x30,0x82,0x04,0xD3,0x30,0x82,0x03,0xBB,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x18, +0xDA,0xD1,0x9E,0x26,0x7D,0xE8,0xBB,0x4A,0x21,0x58,0xCD,0xCC,0x6B,0x3B,0x4A,0x30, +0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81, +0xCA,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17, +0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67, +0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B, +0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74, +0x20,0x4E,0x65,0x74,0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04, +0x0B,0x13,0x31,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x56,0x65,0x72,0x69, +0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72, +0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20, +0x6F,0x6E,0x6C,0x79,0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56, +0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20, +0x50,0x75,0x62,0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43, +0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74, +0x68,0x6F,0x72,0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x35,0x30,0x1E,0x17,0x0D,0x30, +0x36,0x31,0x31,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x36, +0x30,0x37,0x31,0x36,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0xCA,0x31,0x0B, +0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06, +0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20, +0x49,0x6E,0x63,0x2E,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x0B,0x13,0x16,0x56, +0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4E,0x65, +0x74,0x77,0x6F,0x72,0x6B,0x31,0x3A,0x30,0x38,0x06,0x03,0x55,0x04,0x0B,0x13,0x31, +0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67, +0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75, +0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C, +0x79,0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3C,0x56,0x65,0x72,0x69, +0x53,0x69,0x67,0x6E,0x20,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62, +0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74, +0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72, +0x69,0x74,0x79,0x20,0x2D,0x20,0x47,0x35,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09, +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00, +0x30,0x82,0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xAF,0x24,0x08,0x08,0x29,0x7A,0x35, +0x9E,0x60,0x0C,0xAA,0xE7,0x4B,0x3B,0x4E,0xDC,0x7C,0xBC,0x3C,0x45,0x1C,0xBB,0x2B, +0xE0,0xFE,0x29,0x02,0xF9,0x57,0x08,0xA3,0x64,0x85,0x15,0x27,0xF5,0xF1,0xAD,0xC8, +0x31,0x89,0x5D,0x22,0xE8,0x2A,0xAA,0xA6,0x42,0xB3,0x8F,0xF8,0xB9,0x55,0xB7,0xB1, +0xB7,0x4B,0xB3,0xFE,0x8F,0x7E,0x07,0x57,0xEC,0xEF,0x43,0xDB,0x66,0x62,0x15,0x61, +0xCF,0x60,0x0D,0xA4,0xD8,0xDE,0xF8,0xE0,0xC3,0x62,0x08,0x3D,0x54,0x13,0xEB,0x49, +0xCA,0x59,0x54,0x85,0x26,0xE5,0x2B,0x8F,0x1B,0x9F,0xEB,0xF5,0xA1,0x91,0xC2,0x33, +0x49,0xD8,0x43,0x63,0x6A,0x52,0x4B,0xD2,0x8F,0xE8,0x70,0x51,0x4D,0xD1,0x89,0x69, +0x7B,0xC7,0x70,0xF6,0xB3,0xDC,0x12,0x74,0xDB,0x7B,0x5D,0x4B,0x56,0xD3,0x96,0xBF, +0x15,0x77,0xA1,0xB0,0xF4,0xA2,0x25,0xF2,0xAF,0x1C,0x92,0x67,0x18,0xE5,0xF4,0x06, +0x04,0xEF,0x90,0xB9,0xE4,0x00,0xE4,0xDD,0x3A,0xB5,0x19,0xFF,0x02,0xBA,0xF4,0x3C, +0xEE,0xE0,0x8B,0xEB,0x37,0x8B,0xEC,0xF4,0xD7,0xAC,0xF2,0xF6,0xF0,0x3D,0xAF,0xDD, +0x75,0x91,0x33,0x19,0x1D,0x1C,0x40,0xCB,0x74,0x24,0x19,0x21,0x93,0xD9,0x14,0xFE, +0xAC,0x2A,0x52,0xC7,0x8F,0xD5,0x04,0x49,0xE4,0x8D,0x63,0x47,0x88,0x3C,0x69,0x83, +0xCB,0xFE,0x47,0xBD,0x2B,0x7E,0x4F,0xC5,0x95,0xAE,0x0E,0x9D,0xD4,0xD1,0x43,0xC0, +0x67,0x73,0xE3,0x14,0x08,0x7E,0xE5,0x3F,0x9F,0x73,0xB8,0x33,0x0A,0xCF,0x5D,0x3F, +0x34,0x87,0x96,0x8A,0xEE,0x53,0xE8,0x25,0x15,0x02,0x03,0x01,0x00,0x01,0xA3,0x81, +0xB2,0x30,0x81,0xAF,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05, +0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04, +0x04,0x03,0x02,0x01,0x06,0x30,0x6D,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01, +0x0C,0x04,0x61,0x30,0x5F,0xA1,0x5D,0xA0,0x5B,0x30,0x59,0x30,0x57,0x30,0x55,0x16, +0x09,0x69,0x6D,0x61,0x67,0x65,0x2F,0x67,0x69,0x66,0x30,0x21,0x30,0x1F,0x30,0x07, +0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x04,0x14,0x8F,0xE5,0xD3,0x1A,0x86,0xAC,0x8D, +0x8E,0x6B,0xC3,0xCF,0x80,0x6A,0xD4,0x48,0x18,0x2C,0x7B,0x19,0x2E,0x30,0x25,0x16, +0x23,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6C,0x6F,0x67,0x6F,0x2E,0x76,0x65,0x72, +0x69,0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,0x6D,0x2F,0x76,0x73,0x6C,0x6F,0x67,0x6F, +0x2E,0x67,0x69,0x66,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x7F, +0xD3,0x65,0xA7,0xC2,0xDD,0xEC,0xBB,0xF0,0x30,0x09,0xF3,0x43,0x39,0xFA,0x02,0xAF, +0x33,0x31,0x33,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, +0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x93,0x24,0x4A,0x30,0x5F,0x62,0xCF,0xD8,0x1A, +0x98,0x2F,0x3D,0xEA,0xDC,0x99,0x2D,0xBD,0x77,0xF6,0xA5,0x79,0x22,0x38,0xEC,0xC4, +0xA7,0xA0,0x78,0x12,0xAD,0x62,0x0E,0x45,0x70,0x64,0xC5,0xE7,0x97,0x66,0x2D,0x98, +0x09,0x7E,0x5F,0xAF,0xD6,0xCC,0x28,0x65,0xF2,0x01,0xAA,0x08,0x1A,0x47,0xDE,0xF9, +0xF9,0x7C,0x92,0x5A,0x08,0x69,0x20,0x0D,0xD9,0x3E,0x6D,0x6E,0x3C,0x0D,0x6E,0xD8, +0xE6,0x06,0x91,0x40,0x18,0xB9,0xF8,0xC1,0xED,0xDF,0xDB,0x41,0xAA,0xE0,0x96,0x20, +0xC9,0xCD,0x64,0x15,0x38,0x81,0xC9,0x94,0xEE,0xA2,0x84,0x29,0x0B,0x13,0x6F,0x8E, +0xDB,0x0C,0xDD,0x25,0x02,0xDB,0xA4,0x8B,0x19,0x44,0xD2,0x41,0x7A,0x05,0x69,0x4A, +0x58,0x4F,0x60,0xCA,0x7E,0x82,0x6A,0x0B,0x02,0xAA,0x25,0x17,0x39,0xB5,0xDB,0x7F, +0xE7,0x84,0x65,0x2A,0x95,0x8A,0xBD,0x86,0xDE,0x5E,0x81,0x16,0x83,0x2D,0x10,0xCC, +0xDE,0xFD,0xA8,0x82,0x2A,0x6D,0x28,0x1F,0x0D,0x0B,0xC4,0xE5,0xE7,0x1A,0x26,0x19, +0xE1,0xF4,0x11,0x6F,0x10,0xB5,0x95,0xFC,0xE7,0x42,0x05,0x32,0xDB,0xCE,0x9D,0x51, +0x5E,0x28,0xB6,0x9E,0x85,0xD3,0x5B,0xEF,0xA5,0x7D,0x45,0x40,0x72,0x8E,0xB7,0x0E, +0x6B,0x0E,0x06,0xFB,0x33,0x35,0x48,0x71,0xB8,0x9D,0x27,0x8B,0xC4,0x65,0x5F,0x0D, +0x86,0x76,0x9C,0x44,0x7A,0xF6,0x95,0x5C,0xF6,0x5D,0x32,0x08,0x33,0xA4,0x54,0xB6, +0x18,0x3F,0x68,0x5C,0xF2,0x42,0x4A,0x85,0x38,0x54,0x83,0x5F,0xD1,0xE8,0x2C,0xF2, +0xAC,0x11,0xD6,0xA8,0xED,0x63,0x6A, +}; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { +/* subject:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority */ +/* issuer :/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority */ +unsigned char XXX_certificate[576]={ +0x30,0x82,0x02,0x3C,0x30,0x82,0x01,0xA5,0x02,0x10,0x3C,0x91,0x31,0xCB,0x1F,0xF6, +0xD0,0x1B,0x0E,0x9A,0xB8,0xD0,0x44,0xBF,0x12,0xBE,0x30,0x0D,0x06,0x09,0x2A,0x86, +0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x5F,0x31,0x0B,0x30,0x09,0x06, +0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04, +0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63, +0x2E,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,0x0B,0x13,0x2E,0x43,0x6C,0x61,0x73, +0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61, +0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E, +0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x39,0x36, +0x30,0x31,0x32,0x39,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x38,0x30, +0x38,0x30,0x32,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x5F,0x31,0x0B,0x30,0x09, +0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55, +0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E, +0x63,0x2E,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,0x0B,0x13,0x2E,0x43,0x6C,0x61, +0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D, +0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F, +0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x81,0x9F,0x30,0x0D, +0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D, +0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xC9,0x5C,0x59,0x9E,0xF2,0x1B,0x8A,0x01, +0x14,0xB4,0x10,0xDF,0x04,0x40,0xDB,0xE3,0x57,0xAF,0x6A,0x45,0x40,0x8F,0x84,0x0C, +0x0B,0xD1,0x33,0xD9,0xD9,0x11,0xCF,0xEE,0x02,0x58,0x1F,0x25,0xF7,0x2A,0xA8,0x44, +0x05,0xAA,0xEC,0x03,0x1F,0x78,0x7F,0x9E,0x93,0xB9,0x9A,0x00,0xAA,0x23,0x7D,0xD6, +0xAC,0x85,0xA2,0x63,0x45,0xC7,0x72,0x27,0xCC,0xF4,0x4C,0xC6,0x75,0x71,0xD2,0x39, +0xEF,0x4F,0x42,0xF0,0x75,0xDF,0x0A,0x90,0xC6,0x8E,0x20,0x6F,0x98,0x0F,0xF8,0xAC, +0x23,0x5F,0x70,0x29,0x36,0xA4,0xC9,0x86,0xE7,0xB1,0x9A,0x20,0xCB,0x53,0xA5,0x85, +0xE7,0x3D,0xBE,0x7D,0x9A,0xFE,0x24,0x45,0x33,0xDC,0x76,0x15,0xED,0x0F,0xA2,0x71, +0x64,0x4C,0x65,0x2E,0x81,0x68,0x45,0xA7,0x02,0x03,0x01,0x00,0x01,0x30,0x0D,0x06, +0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00, +0x10,0x72,0x52,0xA9,0x05,0x14,0x19,0x32,0x08,0x41,0xF0,0xC5,0x6B,0x0A,0xCC,0x7E, +0x0F,0x21,0x19,0xCD,0xE4,0x67,0xDC,0x5F,0xA9,0x1B,0xE6,0xCA,0xE8,0x73,0x9D,0x22, +0xD8,0x98,0x6E,0x73,0x03,0x61,0x91,0xC5,0x7C,0xB0,0x45,0x40,0x6E,0x44,0x9D,0x8D, +0xB0,0xB1,0x96,0x74,0x61,0x2D,0x0D,0xA9,0x45,0xD2,0xA4,0x92,0x2A,0xD6,0x9A,0x75, +0x97,0x6E,0x3F,0x53,0xFD,0x45,0x99,0x60,0x1D,0xA8,0x2B,0x4C,0xF9,0x5E,0xA7,0x09, +0xD8,0x75,0x30,0xD7,0xD2,0x65,0x60,0x3D,0x67,0xD6,0x48,0x55,0x75,0x69,0x3F,0x91, +0xF5,0x48,0x0B,0x47,0x69,0x22,0x69,0x82,0x96,0xBE,0xC9,0xC8,0x38,0x86,0x4A,0x7A, +0x2C,0x73,0x19,0x48,0x69,0x4E,0x6B,0x7C,0x65,0xBF,0x0F,0xFC,0x70,0xCE,0x88,0x90, +}; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { +/* subject:/C=US/O=thawte, Inc./OU=(c) 2007 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA - G2 */ +/* issuer :/C=US/O=thawte, Inc./OU=(c) 2007 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA - G2 */ +unsigned char XXX_certificate[652]={ +0x30,0x82,0x02,0x88,0x30,0x82,0x02,0x0D,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x35, +0xFC,0x26,0x5C,0xD9,0x84,0x4F,0xC9,0x3D,0x26,0x3D,0x57,0x9B,0xAE,0xD7,0x56,0x30, +0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,0x30,0x81,0x84,0x31,0x0B, +0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,0x13,0x06, +0x03,0x55,0x04,0x0A,0x13,0x0C,0x74,0x68,0x61,0x77,0x74,0x65,0x2C,0x20,0x49,0x6E, +0x63,0x2E,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x0B,0x13,0x2F,0x28,0x63,0x29, +0x20,0x32,0x30,0x30,0x37,0x20,0x74,0x68,0x61,0x77,0x74,0x65,0x2C,0x20,0x49,0x6E, +0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69, +0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x24,0x30,0x22, +0x06,0x03,0x55,0x04,0x03,0x13,0x1B,0x74,0x68,0x61,0x77,0x74,0x65,0x20,0x50,0x72, +0x69,0x6D,0x61,0x72,0x79,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x20,0x2D,0x20, +0x47,0x32,0x30,0x1E,0x17,0x0D,0x30,0x37,0x31,0x31,0x30,0x35,0x30,0x30,0x30,0x30, +0x30,0x30,0x5A,0x17,0x0D,0x33,0x38,0x30,0x31,0x31,0x38,0x32,0x33,0x35,0x39,0x35, +0x39,0x5A,0x30,0x81,0x84,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, +0x55,0x53,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x74,0x68,0x61, +0x77,0x74,0x65,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x38,0x30,0x36,0x06,0x03,0x55, +0x04,0x0B,0x13,0x2F,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x37,0x20,0x74,0x68,0x61, +0x77,0x74,0x65,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F,0x72,0x20, +0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6F, +0x6E,0x6C,0x79,0x31,0x24,0x30,0x22,0x06,0x03,0x55,0x04,0x03,0x13,0x1B,0x74,0x68, +0x61,0x77,0x74,0x65,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x52,0x6F,0x6F, +0x74,0x20,0x43,0x41,0x20,0x2D,0x20,0x47,0x32,0x30,0x76,0x30,0x10,0x06,0x07,0x2A, +0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00, +0x04,0xA2,0xD5,0x9C,0x82,0x7B,0x95,0x9D,0xF1,0x52,0x78,0x87,0xFE,0x8A,0x16,0xBF, +0x05,0xE6,0xDF,0xA3,0x02,0x4F,0x0D,0x07,0xC6,0x00,0x51,0xBA,0x0C,0x02,0x52,0x2D, +0x22,0xA4,0x42,0x39,0xC4,0xFE,0x8F,0xEA,0xC9,0xC1,0xBE,0xD4,0x4D,0xFF,0x9F,0x7A, +0x9E,0xE2,0xB1,0x7C,0x9A,0xAD,0xA7,0x86,0x09,0x73,0x87,0xD1,0xE7,0x9A,0xE3,0x7A, +0xA5,0xAA,0x6E,0xFB,0xBA,0xB3,0x70,0xC0,0x67,0x88,0xA2,0x35,0xD4,0xA3,0x9A,0xB1, +0xFD,0xAD,0xC2,0xEF,0x31,0xFA,0xA8,0xB9,0xF3,0xFB,0x08,0xC6,0x91,0xD1,0xFB,0x29, +0x95,0xA3,0x42,0x30,0x40,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04, +0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF, +0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04, +0x14,0x9A,0xD8,0x00,0x30,0x00,0xE7,0x6B,0x7F,0x85,0x18,0xEE,0x8B,0xB6,0xCE,0x8A, +0x0C,0xF8,0x11,0xE1,0xBB,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03, +0x03,0x03,0x69,0x00,0x30,0x66,0x02,0x31,0x00,0xDD,0xF8,0xE0,0x57,0x47,0x5B,0xA7, +0xE6,0x0A,0xC3,0xBD,0xF5,0x80,0x8A,0x97,0x35,0x0D,0x1B,0x89,0x3C,0x54,0x86,0x77, +0x28,0xCA,0xA1,0xF4,0x79,0xDE,0xB5,0xE6,0x38,0xB0,0xF0,0x65,0x70,0x8C,0x7F,0x02, +0x54,0xC2,0xBF,0xFF,0xD8,0xA1,0x3E,0xD9,0xCF,0x02,0x31,0x00,0xC4,0x8D,0x94,0xFC, +0xDC,0x53,0xD2,0xDC,0x9D,0x78,0x16,0x1F,0x15,0x33,0x23,0x53,0x52,0xE3,0x5A,0x31, +0x5D,0x9D,0xCA,0xAE,0xBD,0x13,0x29,0x44,0x0D,0x27,0x5B,0xA8,0xE7,0x68,0x9C,0x12, +0xF7,0x58,0x3F,0x2E,0x72,0x02,0x57,0xA3,0x8F,0xA1,0x14,0x2E, +}; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { +/* subject:/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA */ +/* issuer :/C=US/O=thawte, Inc./OU=Certification Services Division/OU=(c) 2006 thawte, Inc. - For authorized use only/CN=thawte Primary Root CA */ +unsigned char XXX_certificate[1060]={ +0x30,0x82,0x04,0x20,0x30,0x82,0x03,0x08,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x34, +0x4E,0xD5,0x57,0x20,0xD5,0xED,0xEC,0x49,0xF4,0x2F,0xCE,0x37,0xDB,0x2B,0x6D,0x30, +0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81, +0xA9,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15, +0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x74,0x68,0x61,0x77,0x74,0x65,0x2C, +0x20,0x49,0x6E,0x63,0x2E,0x31,0x28,0x30,0x26,0x06,0x03,0x55,0x04,0x0B,0x13,0x1F, +0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x65, +0x72,0x76,0x69,0x63,0x65,0x73,0x20,0x44,0x69,0x76,0x69,0x73,0x69,0x6F,0x6E,0x31, +0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x0B,0x13,0x2F,0x28,0x63,0x29,0x20,0x32,0x30, +0x30,0x36,0x20,0x74,0x68,0x61,0x77,0x74,0x65,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20, +0x2D,0x20,0x46,0x6F,0x72,0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64, +0x20,0x75,0x73,0x65,0x20,0x6F,0x6E,0x6C,0x79,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55, +0x04,0x03,0x13,0x16,0x74,0x68,0x61,0x77,0x74,0x65,0x20,0x50,0x72,0x69,0x6D,0x61, +0x72,0x79,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x30,0x36, +0x31,0x31,0x31,0x37,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x36,0x30, +0x37,0x31,0x36,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0xA9,0x31,0x0B,0x30, +0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,0x13,0x06,0x03, +0x55,0x04,0x0A,0x13,0x0C,0x74,0x68,0x61,0x77,0x74,0x65,0x2C,0x20,0x49,0x6E,0x63, +0x2E,0x31,0x28,0x30,0x26,0x06,0x03,0x55,0x04,0x0B,0x13,0x1F,0x43,0x65,0x72,0x74, +0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x65,0x72,0x76,0x69,0x63, +0x65,0x73,0x20,0x44,0x69,0x76,0x69,0x73,0x69,0x6F,0x6E,0x31,0x38,0x30,0x36,0x06, +0x03,0x55,0x04,0x0B,0x13,0x2F,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x74, +0x68,0x61,0x77,0x74,0x65,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2D,0x20,0x46,0x6F, +0x72,0x20,0x61,0x75,0x74,0x68,0x6F,0x72,0x69,0x7A,0x65,0x64,0x20,0x75,0x73,0x65, +0x20,0x6F,0x6E,0x6C,0x79,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x13,0x16, +0x74,0x68,0x61,0x77,0x74,0x65,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x52, +0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86, +0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82, +0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xAC,0xA0,0xF0,0xFB,0x80,0x59,0xD4,0x9C,0xC7, +0xA4,0xCF,0x9D,0xA1,0x59,0x73,0x09,0x10,0x45,0x0C,0x0D,0x2C,0x6E,0x68,0xF1,0x6C, +0x5B,0x48,0x68,0x49,0x59,0x37,0xFC,0x0B,0x33,0x19,0xC2,0x77,0x7F,0xCC,0x10,0x2D, +0x95,0x34,0x1C,0xE6,0xEB,0x4D,0x09,0xA7,0x1C,0xD2,0xB8,0xC9,0x97,0x36,0x02,0xB7, +0x89,0xD4,0x24,0x5F,0x06,0xC0,0xCC,0x44,0x94,0x94,0x8D,0x02,0x62,0x6F,0xEB,0x5A, +0xDD,0x11,0x8D,0x28,0x9A,0x5C,0x84,0x90,0x10,0x7A,0x0D,0xBD,0x74,0x66,0x2F,0x6A, +0x38,0xA0,0xE2,0xD5,0x54,0x44,0xEB,0x1D,0x07,0x9F,0x07,0xBA,0x6F,0xEE,0xE9,0xFD, +0x4E,0x0B,0x29,0xF5,0x3E,0x84,0xA0,0x01,0xF1,0x9C,0xAB,0xF8,0x1C,0x7E,0x89,0xA4, +0xE8,0xA1,0xD8,0x71,0x65,0x0D,0xA3,0x51,0x7B,0xEE,0xBC,0xD2,0x22,0x60,0x0D,0xB9, +0x5B,0x9D,0xDF,0xBA,0xFC,0x51,0x5B,0x0B,0xAF,0x98,0xB2,0xE9,0x2E,0xE9,0x04,0xE8, +0x62,0x87,0xDE,0x2B,0xC8,0xD7,0x4E,0xC1,0x4C,0x64,0x1E,0xDD,0xCF,0x87,0x58,0xBA, +0x4A,0x4F,0xCA,0x68,0x07,0x1D,0x1C,0x9D,0x4A,0xC6,0xD5,0x2F,0x91,0xCC,0x7C,0x71, +0x72,0x1C,0xC5,0xC0,0x67,0xEB,0x32,0xFD,0xC9,0x92,0x5C,0x94,0xDA,0x85,0xC0,0x9B, +0xBF,0x53,0x7D,0x2B,0x09,0xF4,0x8C,0x9D,0x91,0x1F,0x97,0x6A,0x52,0xCB,0xDE,0x09, +0x36,0xA4,0x77,0xD8,0x7B,0x87,0x50,0x44,0xD5,0x3E,0x6E,0x29,0x69,0xFB,0x39,0x49, +0x26,0x1E,0x09,0xA5,0x80,0x7B,0x40,0x2D,0xEB,0xE8,0x27,0x85,0xC9,0xFE,0x61,0xFD, +0x7E,0xE6,0x7C,0x97,0x1D,0xD5,0x9D,0x02,0x03,0x01,0x00,0x01,0xA3,0x42,0x30,0x40, +0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01, +0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01, +0x06,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x7B,0x5B,0x45,0xCF, +0xAF,0xCE,0xCB,0x7A,0xFD,0x31,0x92,0x1A,0x6A,0xB6,0xF3,0x46,0xEB,0x57,0x48,0x50, +0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03, +0x82,0x01,0x01,0x00,0x79,0x11,0xC0,0x4B,0xB3,0x91,0xB6,0xFC,0xF0,0xE9,0x67,0xD4, +0x0D,0x6E,0x45,0xBE,0x55,0xE8,0x93,0xD2,0xCE,0x03,0x3F,0xED,0xDA,0x25,0xB0,0x1D, +0x57,0xCB,0x1E,0x3A,0x76,0xA0,0x4C,0xEC,0x50,0x76,0xE8,0x64,0x72,0x0C,0xA4,0xA9, +0xF1,0xB8,0x8B,0xD6,0xD6,0x87,0x84,0xBB,0x32,0xE5,0x41,0x11,0xC0,0x77,0xD9,0xB3, +0x60,0x9D,0xEB,0x1B,0xD5,0xD1,0x6E,0x44,0x44,0xA9,0xA6,0x01,0xEC,0x55,0x62,0x1D, +0x77,0xB8,0x5C,0x8E,0x48,0x49,0x7C,0x9C,0x3B,0x57,0x11,0xAC,0xAD,0x73,0x37,0x8E, +0x2F,0x78,0x5C,0x90,0x68,0x47,0xD9,0x60,0x60,0xE6,0xFC,0x07,0x3D,0x22,0x20,0x17, +0xC4,0xF7,0x16,0xE9,0xC4,0xD8,0x72,0xF9,0xC8,0x73,0x7C,0xDF,0x16,0x2F,0x15,0xA9, +0x3E,0xFD,0x6A,0x27,0xB6,0xA1,0xEB,0x5A,0xBA,0x98,0x1F,0xD5,0xE3,0x4D,0x64,0x0A, +0x9D,0x13,0xC8,0x61,0xBA,0xF5,0x39,0x1C,0x87,0xBA,0xB8,0xBD,0x7B,0x22,0x7F,0xF6, +0xFE,0xAC,0x40,0x79,0xE5,0xAC,0x10,0x6F,0x3D,0x8F,0x1B,0x79,0x76,0x8B,0xC4,0x37, +0xB3,0x21,0x18,0x84,0xE5,0x36,0x00,0xEB,0x63,0x20,0x99,0xB9,0xE9,0xFE,0x33,0x04, +0xBB,0x41,0xC8,0xC1,0x02,0xF9,0x44,0x63,0x20,0x9E,0x81,0xCE,0x42,0xD3,0xD6,0x3F, +0x2C,0x76,0xD3,0x63,0x9C,0x59,0xDD,0x8F,0xA6,0xE1,0x0E,0xA0,0x2E,0x41,0xF7,0x2E, +0x95,0x47,0xCF,0xBC,0xFD,0x33,0xF3,0xF6,0x0B,0x61,0x7E,0x7E,0x91,0x2B,0x81,0x47, +0xC2,0x27,0x30,0xEE,0xA7,0x10,0x5D,0x37,0x8F,0x5C,0x39,0x2B,0xE4,0x04,0xF0,0x7B, +0x8D,0x56,0x8C,0x68, +}; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { +/* subject:/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com */ +/* issuer :/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com */ +unsigned char XXX_certificate[747]={ +0x30,0x82,0x02,0xE7,0x30,0x82,0x02,0x50,0x02,0x01,0x01,0x30,0x0D,0x06,0x09,0x2A, +0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0xBB,0x31,0x24,0x30, +0x22,0x06,0x03,0x55,0x04,0x07,0x13,0x1B,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74, +0x20,0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x4E,0x65,0x74,0x77, +0x6F,0x72,0x6B,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x61, +0x6C,0x69,0x43,0x65,0x72,0x74,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x35,0x30,0x33, +0x06,0x03,0x55,0x04,0x0B,0x13,0x2C,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74,0x20, +0x43,0x6C,0x61,0x73,0x73,0x20,0x32,0x20,0x50,0x6F,0x6C,0x69,0x63,0x79,0x20,0x56, +0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72, +0x69,0x74,0x79,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x68,0x74, +0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x76,0x61,0x6C,0x69,0x63,0x65,0x72, +0x74,0x2E,0x63,0x6F,0x6D,0x2F,0x31,0x20,0x30,0x1E,0x06,0x09,0x2A,0x86,0x48,0x86, +0xF7,0x0D,0x01,0x09,0x01,0x16,0x11,0x69,0x6E,0x66,0x6F,0x40,0x76,0x61,0x6C,0x69, +0x63,0x65,0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x39,0x39,0x30,0x36, +0x32,0x36,0x30,0x30,0x31,0x39,0x35,0x34,0x5A,0x17,0x0D,0x31,0x39,0x30,0x36,0x32, +0x36,0x30,0x30,0x31,0x39,0x35,0x34,0x5A,0x30,0x81,0xBB,0x31,0x24,0x30,0x22,0x06, +0x03,0x55,0x04,0x07,0x13,0x1B,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74,0x20,0x56, +0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x4E,0x65,0x74,0x77,0x6F,0x72, +0x6B,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x61,0x6C,0x69, +0x43,0x65,0x72,0x74,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x35,0x30,0x33,0x06,0x03, +0x55,0x04,0x0B,0x13,0x2C,0x56,0x61,0x6C,0x69,0x43,0x65,0x72,0x74,0x20,0x43,0x6C, +0x61,0x73,0x73,0x20,0x32,0x20,0x50,0x6F,0x6C,0x69,0x63,0x79,0x20,0x56,0x61,0x6C, +0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74, +0x79,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x68,0x74,0x74,0x70, +0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x76,0x61,0x6C,0x69,0x63,0x65,0x72,0x74,0x2E, +0x63,0x6F,0x6D,0x2F,0x31,0x20,0x30,0x1E,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, +0x01,0x09,0x01,0x16,0x11,0x69,0x6E,0x66,0x6F,0x40,0x76,0x61,0x6C,0x69,0x63,0x65, +0x72,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, +0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02, +0x81,0x81,0x00,0xCE,0x3A,0x71,0xCA,0xE5,0xAB,0xC8,0x59,0x92,0x55,0xD7,0xAB,0xD8, +0x74,0x0E,0xF9,0xEE,0xD9,0xF6,0x55,0x47,0x59,0x65,0x47,0x0E,0x05,0x55,0xDC,0xEB, +0x98,0x36,0x3C,0x5C,0x53,0x5D,0xD3,0x30,0xCF,0x38,0xEC,0xBD,0x41,0x89,0xED,0x25, +0x42,0x09,0x24,0x6B,0x0A,0x5E,0xB3,0x7C,0xDD,0x52,0x2D,0x4C,0xE6,0xD4,0xD6,0x7D, +0x5A,0x59,0xA9,0x65,0xD4,0x49,0x13,0x2D,0x24,0x4D,0x1C,0x50,0x6F,0xB5,0xC1,0x85, +0x54,0x3B,0xFE,0x71,0xE4,0xD3,0x5C,0x42,0xF9,0x80,0xE0,0x91,0x1A,0x0A,0x5B,0x39, +0x36,0x67,0xF3,0x3F,0x55,0x7C,0x1B,0x3F,0xB4,0x5F,0x64,0x73,0x34,0xE3,0xB4,0x12, +0xBF,0x87,0x64,0xF8,0xDA,0x12,0xFF,0x37,0x27,0xC1,0xB3,0x43,0xBB,0xEF,0x7B,0x6E, +0x2E,0x69,0xF7,0x02,0x03,0x01,0x00,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, +0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x3B,0x7F,0x50,0x6F,0x6F, +0x50,0x94,0x99,0x49,0x62,0x38,0x38,0x1F,0x4B,0xF8,0xA5,0xC8,0x3E,0xA7,0x82,0x81, +0xF6,0x2B,0xC7,0xE8,0xC5,0xCE,0xE8,0x3A,0x10,0x82,0xCB,0x18,0x00,0x8E,0x4D,0xBD, +0xA8,0x58,0x7F,0xA1,0x79,0x00,0xB5,0xBB,0xE9,0x8D,0xAF,0x41,0xD9,0x0F,0x34,0xEE, +0x21,0x81,0x19,0xA0,0x32,0x49,0x28,0xF4,0xC4,0x8E,0x56,0xD5,0x52,0x33,0xFD,0x50, +0xD5,0x7E,0x99,0x6C,0x03,0xE4,0xC9,0x4C,0xFC,0xCB,0x6C,0xAB,0x66,0xB3,0x4A,0x21, +0x8C,0xE5,0xB5,0x0C,0x32,0x3E,0x10,0xB2,0xCC,0x6C,0xA1,0xDC,0x9A,0x98,0x4C,0x02, +0x5B,0xF3,0xCE,0xB9,0x9E,0xA5,0x72,0x0E,0x4A,0xB7,0x3F,0x3C,0xE6,0x16,0x68,0xF8, +0xBE,0xED,0x74,0x4C,0xBC,0x5B,0xD5,0x62,0x1F,0x43,0xDD, +}; + + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + return [NSArray arrayWithArray:trustedCertificates]; +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTAnalyticsMetadata.h b/Pods/Braintree/BraintreeCore/BTAnalyticsMetadata.h new file mode 100644 index 0000000..11de62e --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTAnalyticsMetadata.h @@ -0,0 +1,7 @@ +#import + +@interface BTAnalyticsMetadata : NSObject + ++ (NSDictionary *)metadata; + +@end diff --git a/Pods/Braintree/BraintreeCore/BTAnalyticsMetadata.m b/Pods/Braintree/BraintreeCore/BTAnalyticsMetadata.m new file mode 100644 index 0000000..b951aa4 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTAnalyticsMetadata.m @@ -0,0 +1,260 @@ +#import "BTAnalyticsMetadata.h" + +#import "Braintree-Version.h" +#import "BTKeychain.h" +@import CoreLocation; +#import +#import + +#import + +#ifdef __IPHONE_8_0 +#define kBTCLAuthorizationStatusAuthorized kCLAuthorizationStatusAuthorizedAlways +#else +#define kBTCLAuthorizationStatusAuthorized kCLAuthorizationStatusAuthorized +#endif + +@implementation BTAnalyticsMetadata + ++ (NSDictionary *)metadata { + BTAnalyticsMetadata *m = [[BTAnalyticsMetadata alloc] init]; + + NSMutableDictionary *data = [NSMutableDictionary dictionaryWithCapacity:16]; + + [self setObject:[m platform] forKey:@"platform" inDictionary:data]; + [self setObject:[m platformVersion] forKey:@"platformVersion" inDictionary:data]; + [self setObject:[m sdkVersion] forKey:@"sdkVersion" inDictionary:data]; + [self setObject:[m merchantAppId] forKey:@"merchantAppId" inDictionary:data]; + [self setObject:[m merchantAppName] forKey:@"merchantAppName" inDictionary:data]; + [self setObject:[m merchantAppVersion] forKey:@"merchantAppVersion" inDictionary:data]; +#ifndef __IPHONE_8_0 + [self setObject:@([m deviceRooted]) forKey:@"deviceRooted" inDictionary:data]; +#endif + [self setObject:[m deviceManufacturer] forKey:@"deviceManufacturer" inDictionary:data]; + [self setObject:[m deviceModel] forKey:@"deviceModel" inDictionary:data]; + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 8.0, watchOS 2.0, *)) { +#endif + if ([CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] == kBTCLAuthorizationStatusAuthorized) { + [self setObject:@([m deviceLocationLatitude]) forKey:@"deviceLocationLatitude" inDictionary:data]; + [self setObject:@([m deviceLocationLongitude]) forKey:@"deviceLocationLongitude" inDictionary:data]; + } +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + } +#endif + [self setObject:[m iosDeviceName] forKey:@"iosDeviceName" inDictionary:data]; + [self setObject:[m iosSystemName] forKey:@"iosSystemName" inDictionary:data]; + [self setObject:[m iosBaseSDK] forKey:@"iosBaseSDK" inDictionary:data]; + [self setObject:[m iosDeploymentTarget] forKey:@"iosDeploymentTarget" inDictionary:data]; + [self setObject:[m iosIdentifierForVendor] forKey:@"iosIdentifierForVendor" inDictionary:data]; + [self setObject:@([m iosIsCocoapods]) forKey:@"iosIsCocoapods" inDictionary:data]; + [self setObject:[m deviceAppGeneratedPersistentUuid] forKey:@"deviceAppGeneratedPersistentUuid" inDictionary:data]; + [self setObject:@([m isSimulator]) forKey:@"isSimulator" inDictionary:data]; + [self setObject:[m deviceScreenOrientation] forKey:@"deviceScreenOrientation" inDictionary:data]; + [self setObject:[m userInterfaceOrientation] forKey:@"userInterfaceOrientation" inDictionary:data]; + [self setObject:@([m isVenmoInstalled]) forKey:@"venmoInstalled" inDictionary:data]; + + return [NSDictionary dictionaryWithDictionary:data]; +} + ++ (void)setObject:(id)object forKey:(id)aKey inDictionary:(NSMutableDictionary *)dictionary { + if (object) { + [dictionary setObject:object forKey:aKey]; + } +} + +#pragma mark Metadata Factors + +- (NSString *)platform { + return @"iOS"; +} + +- (NSString *)platformVersion { + + return [[UIDevice currentDevice] systemVersion]; +} + +- (NSString *)sdkVersion { + return BRAINTREE_VERSION; +} + +- (NSString *)merchantAppId { + return [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey]; +} + +- (NSString *)merchantAppVersion { + return [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey]; +} + +- (NSString *)merchantAppName { + return [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleNameKey]; +} + +- (BOOL)deviceRooted { +#if TARGET_IPHONE_SIMULATOR || __IPHONE_8_0 + return NO; +#else + BOOL isJailbroken = system(NULL) == 1; + + return isJailbroken; +#endif +} + +- (NSString *)deviceManufacturer { + return @"Apple"; +} + +- (NSString *)deviceModel { + struct utsname systemInfo; + + uname(&systemInfo); + + NSString* code = [NSString stringWithCString:systemInfo.machine + encoding:NSUTF8StringEncoding]; + + + return code; +} + +- (CLLocationDegrees)deviceLocationLatitude { + return [[[[CLLocationManager alloc] init] location] coordinate].latitude; +} + +- (CLLocationDegrees)deviceLocationLongitude { + return [[[[CLLocationManager alloc] init] location] coordinate].longitude; +} + +- (NSString *)iosIdentifierForVendor { + return [[[UIDevice currentDevice] identifierForVendor] UUIDString]; +} + +- (NSString *)iosDeploymentTarget { + NSString *rawVersionString = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MinimumOSVersion"]; + NSArray *rawVersionArray = [rawVersionString componentsSeparatedByString:@"."]; + NSInteger majorVersionNumber = [[rawVersionArray objectAtIndex:0] integerValue] * 10000; + NSInteger minorVersionNumber = [[rawVersionArray objectAtIndex:1] integerValue] * 100; + + return [NSString stringWithFormat:@"%i", (int)majorVersionNumber + (int)minorVersionNumber]; +} + +- (NSString *)iosBaseSDK { + return [@(__IPHONE_OS_VERSION_MAX_ALLOWED) stringValue]; +} + +- (NSString *)iosDeviceName { + return [[UIDevice currentDevice] name]; +} + +- (NSString *)iosSystemName { + return [[UIDevice currentDevice] systemName]; +} + +- (BOOL)iosIsCocoapods { +#ifdef COCOAPODS + return YES; +#else + return NO; +#endif +} + +- (NSString *)deviceAppGeneratedPersistentUuid { + @try { + static NSString *deviceAppGeneratedPersistentUuidKeychainKey = @"deviceAppGeneratedPersistentUuid"; + NSString *savedIdentifier = [BTKeychain stringForKey:deviceAppGeneratedPersistentUuidKeychainKey]; + if (savedIdentifier.length == 0) { + savedIdentifier = [[NSUUID UUID] UUIDString]; + BOOL setDidSucceed = [BTKeychain setString:savedIdentifier + forKey:deviceAppGeneratedPersistentUuidKeychainKey]; + if (!setDidSucceed) { + return nil; + } + } + return savedIdentifier; + } @catch (NSException *exception) { + return nil; + } +} + +- (BOOL)isSimulator { + return TARGET_IPHONE_SIMULATOR; +} + +- (NSString *)userInterfaceOrientation { +// UIViewController interface orientation methods are deprecated as of iOS 8 +#ifndef __IPHONE_8_0 + if ([UIApplication class] == nil) { + return nil; + } + + if ([self.class isAppExtension]) { + return nil; + } + + UIApplication *sharedApplication = [UIApplication performSelector:@selector(sharedApplication)]; + UIInterfaceOrientation deviceOrientation = [[[sharedApplication keyWindow] rootViewController] interfaceOrientation]; + + switch (deviceOrientation) { + case UIInterfaceOrientationPortrait: + return @"Portrait"; + case UIInterfaceOrientationPortraitUpsideDown: + return @"PortraitUpsideDown"; + case UIInterfaceOrientationLandscapeLeft: + return @"LandscapeLeft"; + case UIInterfaceOrientationLandscapeRight: + return @"LandscapeRight"; + default: + return @"Unknown"; + } +#else + return nil; +#endif +} + +- (NSString *)deviceScreenOrientation { + if ([self.class isAppExtension]) { + return @"AppExtension"; + } + if ([UIDevice class] == nil) { + return nil; + } + + switch ([[UIDevice currentDevice] orientation]) { + case UIDeviceOrientationFaceUp: + return @"FaceUp"; + case UIDeviceOrientationFaceDown: + return @"FaceDown"; + case UIDeviceOrientationPortrait: + return @"Portrait"; + case UIDeviceOrientationPortraitUpsideDown: + return @"PortraitUpsideDown"; + case UIDeviceOrientationLandscapeLeft: + return @"LandscapeLeft"; + case UIDeviceOrientationLandscapeRight: + return @"LandscapeRight"; + default: + return @"Unknown"; + } +} + +- (BOOL)isVenmoInstalled { + if ([self.class isAppExtension]) { + return NO; + } + + UIApplication *sharedApplication = [UIApplication performSelector:@selector(sharedApplication)]; + static BOOL venmoInstalled; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSURL *venmoURL = [NSURL URLWithString:@"com.venmo.touch.v2://x-callback-url/vzero/auth"]; + venmoInstalled = [sharedApplication canOpenURL:venmoURL]; + }); + return venmoInstalled; +} + ++ (BOOL)isAppExtension { + NSDictionary *extensionDictionary = [[NSBundle mainBundle] infoDictionary][@"NSExtension"]; + return [extensionDictionary isKindOfClass:[NSDictionary class]]; +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTAnalyticsService.h b/Pods/Braintree/BraintreeCore/BTAnalyticsService.h new file mode 100644 index 0000000..39330f5 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTAnalyticsService.h @@ -0,0 +1,56 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +extern NSString * const BTAnalyticsServiceErrorDomain; + +typedef NS_ENUM(NSUInteger, BTAnalyticsServiceErrorType) { + BTAnalyticsServiceErrorTypeUnknown = 1, + BTAnalyticsServiceErrorTypeMissingAnalyticsURL, + BTAnalyticsServiceErrorTypeInvalidAPIClient, +}; + +@class BTAPIClient, BTHTTP; + +@interface BTAnalyticsService : NSObject + +- (instancetype)initWithAPIClient:(BTAPIClient *)apiClient; + +/** + @brief Defaults to 1, can be overridden +*/ +@property (nonatomic, assign) NSUInteger flushThreshold; + +@property (nonatomic, strong) BTAPIClient *apiClient; + +/** + @brief Tracks an event. + + @discussion Events are queued and sent in batches to the analytics service, based on the status of the app + and the number of queued events. After exiting this method, there is no guarantee that the event has been + sent. +*/ +- (void)sendAnalyticsEvent:(NSString *)eventKind; + +/** + @brief Tracks an event and sends it to the analytics service. It will also flush any queued events. + + @param completionBlock A callback that is invoked when the analytics service has completed. +*/ +- (void)sendAnalyticsEvent:(NSString *)eventKind completion:(nullable void(^)(NSError * _Nullable))completionBlock; + +/** + @brief Sends all queued events to the analytics service. + + @param completionBlock A callback that is invoked when the analytics service has completed. +*/ +- (void)flush:(nullable void (^)(NSError * _Nullable error))completionBlock; + +/** + @brief The HTTP client for communication with the analytics service endpoint. Exposed for testing. +*/ +@property (nonatomic, strong) BTHTTP *http; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCore/BTAnalyticsService.m b/Pods/Braintree/BraintreeCore/BTAnalyticsService.m new file mode 100644 index 0000000..f5dc8e3 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTAnalyticsService.m @@ -0,0 +1,290 @@ +#import "BTAnalyticsMetadata.h" +#import "BTAnalyticsService.h" +#import "BTAPIClient_Internal.h" +#import "BTClientMetadata.h" +#import "BTHTTP.h" +#import "BTLogger_Internal.h" +#import + +#pragma mark - BTAnalyticsEvent + +/// Encapsulates a single analytics event +@interface BTAnalyticsEvent : NSObject + +@property (nonatomic, copy) NSString *kind; + +@property (nonatomic, assign) long timestamp; + ++ (nonnull instancetype)event:(nonnull NSString *)eventKind withTimestamp:(long)timestamp; + +/// Event serialized to JSON +- (nonnull NSDictionary *)json; + +@end + +@implementation BTAnalyticsEvent + ++ (instancetype)event:(NSString *)eventKind withTimestamp:(long)timestamp { + BTAnalyticsEvent *event = [[BTAnalyticsEvent alloc] init]; + event.kind = eventKind; + event.timestamp = timestamp; + return event; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"%@ at %ld", self.kind, (long)self.timestamp]; +} + +- (NSDictionary *)json { + return @{ + @"kind": self.kind, + @"timestamp": @(self.timestamp) + }; +} + +@end + +#pragma mark - BTAnalyticsSession + +/// Encapsulates analytics events for a given session +@interface BTAnalyticsSession : NSObject + +@property (nonatomic, copy, nonnull) NSString *sessionID; + +@property (nonatomic, copy, nonnull) NSString *source; + +@property (nonatomic, copy, nonnull) NSString *integration; + +@property (nonatomic, strong, nonnull) NSMutableArray *events; + +/// Dictionary of analytics metadata from `BTAnalyticsMetadata` +@property (nonatomic, strong, nonnull) NSDictionary *metadataParameters; + ++ (nonnull instancetype)sessionWithID:(nonnull NSString *)sessionID + source:(nonnull NSString *)source + integration:(nonnull NSString *)integration; + +@end + +@implementation BTAnalyticsSession + +- (instancetype)init { + if (self = [super init]) { + _events = [NSMutableArray array]; + _metadataParameters = [BTAnalyticsMetadata metadata]; + } + return self; +} + ++ (instancetype)sessionWithID:(NSString *)sessionID + source:(NSString *)source + integration:(NSString *)integration +{ + if (!sessionID || !source || !integration) { + return nil; + } + + BTAnalyticsSession *session = [[BTAnalyticsSession alloc] init]; + session.sessionID = sessionID; + session.source = source; + session.integration = integration; + return session; +} + +@end + +#pragma mark - BTAnalyticsService + +@interface BTAnalyticsService () + +/// Dictionary of analytics sessions, keyed by session ID. The analytics service requires that batched events +/// are sent from only one session. In practice, BTAPIClient.metadata.sessionId should never change, so this +/// is defensive. +@property (nonatomic, strong) NSMutableDictionary *analyticsSessions; + +/// A serial dispatch queue that synchronizes access to `analyticsSessions` +@property (nonatomic, strong) dispatch_queue_t sessionsQueue; + +@end + +@implementation BTAnalyticsService + +NSString * const BTAnalyticsServiceErrorDomain = @"com.braintreepayments.BTAnalyticsServiceErrorDomain"; + +- (instancetype)initWithAPIClient:(BTAPIClient *)apiClient { + if (self = [super init]) { + _analyticsSessions = [NSMutableDictionary dictionary]; + _sessionsQueue = dispatch_queue_create("com.braintreepayments.BTAnalyticsService", DISPATCH_QUEUE_SERIAL); + _apiClient = apiClient; + _flushThreshold = 1; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResign:) name:UIApplicationWillResignActiveNotification object:nil]; + } + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +#pragma mark - Public methods + +- (void)sendAnalyticsEvent:(NSString *)eventKind { + dispatch_async(dispatch_get_main_queue(), ^{ + [self enqueueEvent:eventKind]; + [self checkFlushThreshold]; + }); +} + +- (void)sendAnalyticsEvent:(NSString *)eventKind completion:(__unused void(^)(NSError *error))completionBlock { + dispatch_async(dispatch_get_main_queue(), ^{ + [self enqueueEvent:eventKind]; + [self flush:completionBlock]; + }); +} + +- (void)flush:(void (^)(NSError *))completionBlock { + [self.apiClient fetchOrReturnRemoteConfiguration:^(BTConfiguration *configuration, NSError *error) { + if (error) { + [[BTLogger sharedLogger] warning:[NSString stringWithFormat:@"Failed to send analytics event. Remote configuration fetch failed. %@", error.localizedDescription]]; + if (completionBlock) completionBlock(error); + return; + } + + NSURL *analyticsURL = [configuration.json[@"analytics"][@"url"] asURL]; + if (!analyticsURL) { + [[BTLogger sharedLogger] debug:@"Skipping sending analytics event - analytics is disabled in remote configuration"]; + NSError *error = [NSError errorWithDomain:BTAnalyticsServiceErrorDomain code:BTAnalyticsServiceErrorTypeMissingAnalyticsURL userInfo:@{ NSLocalizedDescriptionKey : @"Analytics is disabled in remote configuration" }]; + if (completionBlock) completionBlock(error); + return; + } + + if (!self.http) { + if (self.apiClient.clientToken) { + self.http = [[BTHTTP alloc] initWithBaseURL:analyticsURL authorizationFingerprint:self.apiClient.clientToken.authorizationFingerprint]; + } else if (self.apiClient.tokenizationKey) { + self.http = [[BTHTTP alloc] initWithBaseURL:analyticsURL tokenizationKey:self.apiClient.tokenizationKey]; + } + if (!self.http) { + NSError *error = [NSError errorWithDomain:BTAnalyticsServiceErrorDomain code:BTAnalyticsServiceErrorTypeInvalidAPIClient userInfo:@{ NSLocalizedDescriptionKey : @"API client must have client token or tokenization key" }]; + [[BTLogger sharedLogger] warning:error.localizedDescription]; + if (completionBlock) completionBlock(error); + return; + } + } + // A special value passed in by unit tests to prevent BTHTTP from actually posting + if ([self.http.baseURL isEqual:[NSURL URLWithString:@"test://do-not-send.url"]]) { + if (completionBlock) completionBlock(nil); + return; + } + + dispatch_async(self.sessionsQueue, ^{ + if (self.analyticsSessions.count == 0) { + if (completionBlock) completionBlock(nil); + return; + } + + BOOL willPostAnalyticsEvent = NO; + + for (NSString *sessionID in self.analyticsSessions.allKeys) { + BTAnalyticsSession *session = self.analyticsSessions[sessionID]; + if (session.events.count == 0) { + continue; + } + + willPostAnalyticsEvent = YES; + + NSMutableDictionary *metadataParameters = [NSMutableDictionary dictionary]; + [metadataParameters addEntriesFromDictionary:session.metadataParameters]; + metadataParameters[@"sessionId"] = session.sessionID; + metadataParameters[@"integration"] = session.integration; + metadataParameters[@"source"] = session.source; + + NSMutableDictionary *postParameters = [NSMutableDictionary dictionary]; + if (session.events) { + // Map array of BTAnalyticsEvent to JSON + postParameters[@"analytics"] = [session.events valueForKey:@"json"]; + } + postParameters[@"_meta"] = metadataParameters; + if (self.apiClient.clientToken.authorizationFingerprint) { + postParameters[@"authorization_fingerprint"] = self.apiClient.clientToken.authorizationFingerprint; + } + if (self.apiClient.tokenizationKey) { + postParameters[@"tokenization_key"] = self.apiClient.tokenizationKey; + } + + [session.events removeAllObjects]; + + [self.http POST:@"/" parameters:postParameters completion:^(__unused BTJSON *body, __unused NSHTTPURLResponse *response, NSError *error) { + if (error != nil) { + [[BTLogger sharedLogger] warning:@"Failed to flush analytics events: %@", error.localizedDescription]; + } + if (completionBlock) completionBlock(error); + }]; + } + + if (!willPostAnalyticsEvent && completionBlock) { + completionBlock(nil); + } + }); + }]; +} + +#pragma mark - Private methods + +- (void)appWillResign:(NSNotification *)notification { + UIApplication *application = notification.object; + + __block UIBackgroundTaskIdentifier bgTask; + bgTask = [application beginBackgroundTaskWithName:@"BTAnalyticsService" expirationHandler:^{ + [[BTLogger sharedLogger] warning:@"Analytics service background task expired"]; + [application endBackgroundTask:bgTask]; + bgTask = UIBackgroundTaskInvalid; + }]; + + // Start the long-running task and return immediately. + dispatch_async(self.sessionsQueue, ^{ + [self flush:^(__unused NSError * _Nullable error) { + [application endBackgroundTask:bgTask]; + bgTask = UIBackgroundTaskInvalid; + }]; + }); +} + +#pragma mark - Helpers + +- (void)enqueueEvent:(NSString *)eventKind { + long timestampInSeconds = round([[NSDate date] timeIntervalSince1970]); + BTAnalyticsEvent *event = [BTAnalyticsEvent event:eventKind withTimestamp:timestampInSeconds]; + + BTAnalyticsSession *session = [BTAnalyticsSession sessionWithID:self.apiClient.metadata.sessionId + source:self.apiClient.metadata.sourceString + integration:self.apiClient.metadata.integrationString]; + if (!session) { + [[BTLogger sharedLogger] warning:@"Missing analytics session metadata - will not send event %@", event.kind]; + return; + } + + dispatch_async(self.sessionsQueue, ^{ + if (!self.analyticsSessions[session.sessionID]) { + self.analyticsSessions[session.sessionID] = session; + } + + [self.analyticsSessions[session.sessionID].events addObject:event]; + }); +} + +- (void)checkFlushThreshold { + __block NSUInteger eventCount = 0; + + dispatch_sync(self.sessionsQueue, ^{ + for (BTAnalyticsSession *analyticsSession in self.analyticsSessions.allValues) { + eventCount += analyticsSession.events.count; + } + }); + + if (eventCount >= self.flushThreshold) { + [self flush:nil]; + } +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTAppSwitch.m b/Pods/Braintree/BraintreeCore/BTAppSwitch.m new file mode 100644 index 0000000..bb90a94 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTAppSwitch.m @@ -0,0 +1,79 @@ +#import "BTAppSwitch.h" +#import + +NSString * const BTAppSwitchWillSwitchNotification = @"com.braintreepayments.BTAppSwitchWillSwitchNotification"; +NSString * const BTAppSwitchDidSwitchNotification = @"com.braintreepayments.BTAppSwitchDidSwitchNotification"; +NSString * const BTAppSwitchWillProcessPaymentInfoNotification = @"com.braintreepayments.BTAppSwitchWillProcessPaymentInfoNotification"; +NSString * const BTAppSwitchNotificationTargetKey = @"BTAppSwitchNotificationTargetKey"; + +@interface BTAppSwitch () + +@property (nonatomic, strong) NSMutableSet *appSwitchHandlers; + +@end + +@implementation BTAppSwitch + ++ (instancetype)sharedInstance { + static BTAppSwitch *instance; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + instance = [[BTAppSwitch alloc] init]; + }); + return instance; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _appSwitchHandlers = [NSMutableSet set]; + } + return self; +} + ++ (void)setReturnURLScheme:(NSString *)returnURLScheme { + [BTAppSwitch sharedInstance].returnURLScheme = returnURLScheme; +} + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 ++ (BOOL)handleOpenURL:(NSURL *)url options:(NSDictionary *)options { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 9.0, *)) { +#endif + return [[[self class] sharedInstance] handleOpenURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + } + // This code should technically never run due to the way the compiler macros are setup, but need to return a value here. + return [[[self class] sharedInstance] handleOpenURL:url sourceApplication:@""]; +#endif +} +#else ++ (BOOL)handleOpenURL:(NSURL *)url options:(__unused NSDictionary *)options { + return [[[self class] sharedInstance] handleOpenURL:url sourceApplication:nil]; +} +#endif + ++ (BOOL)handleOpenURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication { + return [[[self class] sharedInstance] handleOpenURL:url sourceApplication:sourceApplication]; +} + +- (BOOL)handleOpenURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication { + for (Class handlerClass in self.appSwitchHandlers) { + if ([handlerClass canHandleAppSwitchReturnURL:url sourceApplication:sourceApplication]) { + [handlerClass handleAppSwitchReturnURL:url]; + return YES; + } + } + return NO; +} + +-(void)registerAppSwitchHandler:(Class)handler { + if (!handler) return; + [self.appSwitchHandlers addObject:handler]; +} + +- (void)unregisterAppSwitchHandler:(Class)handler { + [self.appSwitchHandlers removeObject:handler]; +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTBinData.m b/Pods/Braintree/BraintreeCore/BTBinData.m new file mode 100644 index 0000000..9d3b46e --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTBinData.m @@ -0,0 +1,22 @@ +#import "BTBinData.h" + +@implementation BTBinData + +- (instancetype)initWithJSON:(BTJSON *)json { + if (self = [super init]) { + if (json != nil) { + _prepaid = [json[@"prepaid"] asString] ? [json[@"prepaid"] asString] : @"Unknown"; + _healthcare = [json[@"healthcare"] asString] ? [json[@"healthcare"] asString] : @"Unknown"; + _debit = [json[@"debit"] asString] ? [json[@"debit"] asString] : @"Unknown"; + _durbinRegulated = [json[@"durbinRegulated"] asString] ? [json[@"durbinRegulated"] asString] : @"Unknown"; + _commercial = [json[@"commercial"] asString] ? [json[@"commercial"] asString] : @"Unknown"; + _payroll = [json[@"payroll"] asString] ? [json[@"payroll"] asString] : @"Unknown"; + _issuingBank = [json[@"issuingBank"] asString] ? [json[@"issuingBank"] asString] : @""; + _countryOfIssuance = [json[@"countryOfIssuance"] asString] ? [json[@"countryOfIssuance"] asString] : @""; + _productId = [json[@"productId"] asString] ? [json[@"productId"] asString] : @""; + } + } + return self; +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTClientMetadata.m b/Pods/Braintree/BraintreeCore/BTClientMetadata.m new file mode 100644 index 0000000..acdeec6 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTClientMetadata.m @@ -0,0 +1,102 @@ +#import "BTClientMetadata.h" + +@interface BTClientMetadata () { + @protected + BTClientMetadataIntegrationType _integration; + BTClientMetadataSourceType _source; + NSString *_sessionId; +} +@end + +@implementation BTClientMetadata + +- (instancetype)init { + self = [super init]; + if (self) { + _integration = BTClientMetadataIntegrationCustom; + _source = BTClientMetadataSourceUnknown; + _sessionId = [[[NSUUID UUID] UUIDString] stringByReplacingOccurrencesOfString:@"-" withString:@""]; + } + return self; +} + +- (id)copyWithZone:(NSZone *)zone { + BTClientMetadata *copiedMetadata = [[BTClientMetadata allocWithZone:zone] init]; + copiedMetadata->_integration = _integration; + copiedMetadata->_source = _source; + copiedMetadata->_sessionId = [_sessionId copyWithZone:zone]; + return copiedMetadata; +} + +- (id)mutableCopyWithZone:(NSZone *)zone { + BTMutableClientMetadata *mutableMetadata = [[BTMutableClientMetadata allocWithZone:zone] init]; + mutableMetadata.integration = _integration; + mutableMetadata.source = _source; + mutableMetadata.sessionId = [_sessionId copyWithZone:zone]; + return mutableMetadata; +} + +- (NSString *)integrationString { + return [[self class] integrationToString:self.integration]; +} + +- (NSString *)sourceString { + return [[self class] sourceToString:self.source]; +} + +- (NSDictionary *)parameters { + return @{ + @"integration": self.integrationString, + @"source": self.sourceString, + @"sessionId": self.sessionId + }; +} + +#pragma mark Internal helpers + ++ (NSString *)integrationToString:(BTClientMetadataIntegrationType)integration { + switch (integration) { + case BTClientMetadataIntegrationCustom: + return @"custom"; + case BTClientMetadataIntegrationDropIn: + return @"dropin"; + case BTClientMetadataIntegrationDropIn2: + return @"dropin2"; + case BTClientMetadataIntegrationUnknown: + return @"unknown"; + } +} + ++ (NSString *)sourceToString:(BTClientMetadataSourceType)source { + switch (source) { + case BTClientMetadataSourcePayPalApp: + return @"paypal-app"; + case BTClientMetadataSourcePayPalBrowser: + return @"paypal-browser"; + case BTClientMetadataSourceVenmoApp: + return @"venmo-app"; + case BTClientMetadataSourceForm: + return @"form"; + case BTClientMetadataSourceUnknown: + return @"unknown"; + } +} + +@end + + +@implementation BTMutableClientMetadata + +- (void)setIntegration:(BTClientMetadataIntegrationType)integration { + _integration = integration; +} + +- (void)setSource:(BTClientMetadataSourceType)source { + _source = source; +} + +- (void)setSessionId:(NSString *)sessionId { + _sessionId = sessionId; +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTClientToken.m b/Pods/Braintree/BraintreeCore/BTClientToken.m new file mode 100644 index 0000000..974643c --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTClientToken.m @@ -0,0 +1,191 @@ +#import "BTClientToken.h" + +NSString *const BTClientTokenKeyVersion = @"version"; +NSString *const BTClientTokenKeyAuthorizationFingerprint = @"authorizationFingerprint"; +NSString *const BTClientTokenKeyConfigURL = @"configUrl"; +NSString * const BTClientTokenErrorDomain = @"com.braintreepayments.BTClientTokenErrorDomain"; + +@interface BTClientToken () + +@property (nonatomic, readwrite, copy) NSString *authorizationFingerprint; +@property (nonatomic, readwrite, strong) NSURL *configURL; +@property (nonatomic, copy) NSString *originalValue; +@property (nonatomic, readwrite, strong) BTJSON *json; + +@end + +@implementation BTClientToken + +- (instancetype)init { + return nil; +} + +- (instancetype)initWithClientToken:(NSString *)clientToken error:(NSError * __autoreleasing *)error { + if (self = [super init]) { + // Client token must be decoded first because the other values are retrieved from it + _json = [self decodeClientToken:clientToken error:error]; + _authorizationFingerprint = [_json[BTClientTokenKeyAuthorizationFingerprint] asString]; + _configURL = [_json[BTClientTokenKeyConfigURL] asURL]; + _originalValue = clientToken; + + if (![self validateClientToken:error]) { + return nil; + } + } + return self; +} + +- (BOOL)validateClientToken:(NSError *__autoreleasing*)error { + if (error != NULL && *error) { + return NO; + } + + if ([self.authorizationFingerprint length] == 0) { + if (error != NULL) { + *error = [NSError errorWithDomain:BTClientTokenErrorDomain + code:BTClientTokenErrorInvalid + userInfo:@{ + NSLocalizedDescriptionKey: @"Invalid client token. Please ensure your server is generating a valid Braintree ClientToken.", + NSLocalizedFailureReasonErrorKey: @"Authorization fingerprint was not present or invalid." }]; + } + return NO; + } + + if (![self.configURL isKindOfClass:[NSURL class]] || self.configURL.absoluteString.length == 0) { + if (error != NULL) { + *error = [NSError errorWithDomain:BTClientTokenErrorDomain + code:BTClientTokenErrorInvalid + userInfo:@{ + NSLocalizedDescriptionKey: @"Invalid client token: config url was missing or invalid. Please ensure your server is generating a valid Braintree ClientToken." + }]; + } + return NO; + } + + return YES; +} + +- (instancetype)copyWithZone:(NSZone *)zone { + BTClientToken *copiedClientToken = [[[self class] allocWithZone:zone] initWithClientToken:self.originalValue error:NULL]; + return copiedClientToken; +} + +#pragma mark JSON Parsing + +- (NSDictionary *)parseJSONString:(NSString *)rawJSONString error:(NSError * __autoreleasing *)error { + NSData *rawJSONData = [rawJSONString dataUsingEncoding:NSUTF8StringEncoding]; + + return [NSJSONSerialization JSONObjectWithData:rawJSONData options:0 error:error]; +} + +#pragma mark NSCoding + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeObject:self.originalValue forKey:@"originalValue"]; +} + +- (id)initWithCoder:(NSCoder *)decoder { + return [self initWithClientToken:[decoder decodeObjectForKey:@"originalValue"] error:NULL]; +} + +#pragma mark Client Token Parsing + +- (BTJSON *)decodeClientToken:(NSString *)rawClientTokenString error:(NSError * __autoreleasing *)error { + NSError *JSONError = nil; + NSData *base64DecodedClientToken = [[NSData alloc] initWithBase64EncodedString:rawClientTokenString + options:0]; + + NSDictionary *rawClientToken; + if (base64DecodedClientToken) { + rawClientToken = [NSJSONSerialization JSONObjectWithData:base64DecodedClientToken options:0 error:&JSONError]; + } else { + rawClientToken = [self parseJSONString:rawClientTokenString error:&JSONError]; + } + + if (!rawClientToken) { + if (error) { + NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] initWithDictionary:@{ + NSLocalizedDescriptionKey: @"Invalid client token. Please ensure your server is generating a valid Braintree ClientToken.", + NSLocalizedFailureReasonErrorKey: @"Invalid JSON" + }]; + if (JSONError) { + userInfo[NSUnderlyingErrorKey] = JSONError; + } + *error = [NSError errorWithDomain:BTClientTokenErrorDomain + code:BTClientTokenErrorInvalid + userInfo:userInfo]; + } + return nil; + } + + if (![rawClientToken isKindOfClass:[NSDictionary class]]) { + if (error) { + *error = [NSError errorWithDomain:BTClientTokenErrorDomain + code:BTClientTokenErrorInvalid + userInfo:@{ + NSLocalizedDescriptionKey: @"Invalid client token. Please ensure your server is generating a valid Braintree ClientToken.", + NSLocalizedFailureReasonErrorKey: @"Invalid JSON. Expected to find an object at JSON root." + }]; + } + return nil; + } + + NSError *clientTokenFormatError = [NSError errorWithDomain:BTClientTokenErrorDomain + code:BTClientTokenErrorInvalid + userInfo:@{ + NSLocalizedDescriptionKey: @"Invalid client token format. Please pass the client token string directly as it is generated by the server-side SDK.", + NSLocalizedFailureReasonErrorKey: @"Unsupported client token format." + }]; + + switch ([rawClientToken[BTClientTokenKeyVersion] integerValue]) { + case 1: + if (base64DecodedClientToken) { + if (error) { + *error = clientTokenFormatError; + } + return nil; + } + break; + case 2: + /* FALLTHROUGH */ + case 3: + if (!base64DecodedClientToken) { + if (error) { + *error = clientTokenFormatError; + } + return nil; + } + break; + default: + if (error) { + *error = [NSError errorWithDomain:BTClientTokenErrorDomain + code:BTClientTokenErrorUnsupportedVersion + userInfo:@{ + NSLocalizedDescriptionKey: @"Unsupported client token version. Please ensure your server is generating a valid Braintree ClientToken with a server-side SDK that is compatible with this version of Braintree iOS.", + NSLocalizedFailureReasonErrorKey: @"Unsupported client token version." + }]; + } + return nil; + } + + return [[BTJSON alloc] initWithValue:rawClientToken]; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"", self.authorizationFingerprint, self.configURL]; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + + if ([object isKindOfClass:[BTClientToken class]]) { + BTClientToken *otherToken = object; + return [self.json.asDictionary isEqualToDictionary:otherToken.json.asDictionary]; + } + + return NO; +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTConfiguration.m b/Pods/Braintree/BraintreeCore/BTConfiguration.m new file mode 100644 index 0000000..197a7e4 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTConfiguration.m @@ -0,0 +1,23 @@ +#import "BTConfiguration.h" + +@implementation BTConfiguration + +- (instancetype)init { + @throw [[NSException alloc] initWithName:@"Invalid initializer" reason:@"Use designated initializer" userInfo:nil]; +} + +- (instancetype)initWithJSON:(BTJSON *)json { + if (self = [super init]) { + _json = json; + } + return self; +} + ++ (BOOL)isBetaEnabledPaymentOption:(NSString*)__unused paymentOption { + return false; +} + ++ (void)setBetaPaymentOption:(NSString*) __unused paymentOption isEnabled:(BOOL) __unused isEnabled { /* NO OP */ } + + +@end diff --git a/Pods/Braintree/BraintreeCore/BTErrors.m b/Pods/Braintree/BraintreeCore/BTErrors.m new file mode 100644 index 0000000..fcbcffa --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTErrors.m @@ -0,0 +1,5 @@ +#import "BTErrors.h" + +#pragma mark Error userInfo Keys + +NSString *const BTCustomerInputBraintreeValidationErrorsKey = @"BTCustomerInputBraintreeValidationErrorsKey"; diff --git a/Pods/Braintree/BraintreeCore/BTHTTP.h b/Pods/Braintree/BraintreeCore/BTHTTP.h new file mode 100644 index 0000000..9158927 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTHTTP.h @@ -0,0 +1,87 @@ +#import +#import "BTHTTPErrors.h" +#import "BTJSON.h" + +NS_ASSUME_NONNULL_BEGIN + +@class BTHTTPResponse, BTClientToken; + +/** + @brief Performs HTTP methods on the Braintree Client API +*/ +@interface BTHTTP : NSObject + +/** + @brief An optional array of pinned certificates, each an NSData instance consisting of DER encoded x509 certificates +*/ +@property (nonatomic, nullable, strong) NSArray *pinnedCertificates; + +/** + @brief Initialize `BTHTTP` with the authorization fingerprint from a client token + + @param URL The base URL for the Braintree Client API + @param authorizationFingerprint The authorization fingerprint HMAC from a client token +*/ +- (instancetype)initWithBaseURL:(NSURL *)URL + authorizationFingerprint:(NSString *)authorizationFingerprint NS_DESIGNATED_INITIALIZER; + +/** + @brief Initialize `BTHTTP` with a tokenization key + + @param URL The base URL for the Braintree Client API + @param tokenizationKey A tokenization key +*/ +- (instancetype)initWithBaseURL:(NSURL *)URL tokenizationKey:(NSString *)tokenizationKey NS_DESIGNATED_INITIALIZER; + +/** + @brief A convenience initializer to initialize `BTHTTP` with a client token + + @param clientToken A client token +*/ +- (instancetype)initWithClientToken:(BTClientToken *)clientToken; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnullability" +- (nullable instancetype)init __attribute__((unavailable("Please use initWithBaseURL:authorizationFingerprint: instead."))); +#pragma clang diagnostic pop + +// For testing +@property (nonatomic, strong) NSURLSession *session; +@property (nonatomic, readonly, strong) NSURL *baseURL; + +/** + @brief Queue that callbacks are dispatched onto, main queue if not otherwise specified +*/ +@property (nonatomic, strong) dispatch_queue_t dispatchQueue; + +- (void)GET:(NSString *)endpoint + completion:(nullable void(^)(BTJSON * _Nullable body, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error))completionBlock; + +- (void)GET:(NSString *)endpoint + parameters:(nullable NSDictionary *)parameters + completion:(nullable void(^)(BTJSON * _Nullable body, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error))completionBlock; + +- (void)POST:(NSString *)endpoint + completion:(nullable void(^)(BTJSON * _Nullable body, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error))completionBlock; + +- (void)POST:(NSString *)endpoint + parameters:(nullable NSDictionary *)parameters + completion:(nullable void(^)(BTJSON * _Nullable body, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error))completionBlock; + +- (void)PUT:(NSString *)endpoint + completion:(nullable void(^)(BTJSON * _Nullable body, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error))completionBlock; + +- (void)PUT:(NSString *)endpoint + parameters:(nullable NSDictionary *)parameters + completion:(nullable void(^)(BTJSON * _Nullable body, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error))completionBlock; + +- (void)DELETE:(NSString *)endpoint + completion:(nullable void(^)(BTJSON * _Nullable body, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error))completionBlock; + +- (void)DELETE:(NSString *)endpoint + parameters:(nullable NSDictionary *)parameters + completion:(nullable void(^)(BTJSON * _Nullable body, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error))completionBlock; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCore/BTHTTP.m b/Pods/Braintree/BraintreeCore/BTHTTP.m new file mode 100644 index 0000000..fd3ad9a --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTHTTP.m @@ -0,0 +1,387 @@ +#import "BTHTTP.h" + +#include + +#import "Braintree-Version.h" +#import "BTClientToken.h" +#import "BTAPIPinnedCertificates.h" +#import "BTURLUtils.h" +#import "BTLogger_Internal.h" + +@interface BTHTTP () + +@property (nonatomic, strong) NSURL *baseURL; +@property (nonatomic, copy) NSString *authorizationFingerprint; +@property (nonatomic, copy) NSString *tokenizationKey; + +@end + +@implementation BTHTTP + +- (instancetype)init { + return nil; +} + +- (instancetype)initWithBaseURL:(NSURL *)URL authorizationFingerprint:(NSString *)authorizationFingerprint { + self = [super init]; + if (self) { + NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; + configuration.HTTPAdditionalHeaders = self.defaultHeaders; + self.baseURL = URL; + + NSOperationQueue *delegateQueue = [[NSOperationQueue alloc] init]; + delegateQueue.name = @"com.braintreepayments.BTHTTP"; + delegateQueue.maxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount; + + self.authorizationFingerprint = authorizationFingerprint; + self.session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:delegateQueue]; + self.pinnedCertificates = [BTAPIPinnedCertificates trustedCertificates]; + } + return self; +} + +- (instancetype)initWithBaseURL:(nonnull NSURL *)URL tokenizationKey:(nonnull NSString *)tokenizationKey { + if (self = [super init]) { + NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; + configuration.HTTPAdditionalHeaders = self.defaultHeaders; + self.baseURL = URL; + + NSOperationQueue *delegateQueue = [[NSOperationQueue alloc] init]; + delegateQueue.name = @"com.braintreepayments.BTHTTP"; + delegateQueue.maxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount; + + self.session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:delegateQueue]; + self.pinnedCertificates = [BTAPIPinnedCertificates trustedCertificates]; + self.tokenizationKey = tokenizationKey; + } + return self; +} + +- (instancetype)initWithClientToken:(BTClientToken *)clientToken { + return [self initWithBaseURL:[clientToken.json[@"clientApiUrl"] asURL] authorizationFingerprint:clientToken.authorizationFingerprint]; +} + +- (instancetype)copyWithZone:(NSZone *)zone { + BTHTTP *copiedHTTP; + if (self.authorizationFingerprint) { + copiedHTTP = [[[self class] allocWithZone:zone] initWithBaseURL:self.baseURL authorizationFingerprint:self.authorizationFingerprint]; + } else { + copiedHTTP = [[[self class] allocWithZone:zone] initWithBaseURL:self.baseURL tokenizationKey:self.tokenizationKey]; + } + + copiedHTTP.pinnedCertificates = [_pinnedCertificates copy]; + return copiedHTTP; +} + +#pragma mark - HTTP Methods + +- (void)GET:(NSString *)aPath completion:(void(^)(BTJSON *body, NSHTTPURLResponse *response, NSError *error))completionBlock { + [self GET:aPath parameters:nil completion:completionBlock]; +} + +- (void)GET:(NSString *)aPath parameters:(NSDictionary *)parameters completion:(void(^)(BTJSON *body, NSHTTPURLResponse *response, NSError *error))completionBlock { + [self httpRequest:@"GET" path:aPath parameters:parameters completion:completionBlock]; +} + +- (void)POST:(NSString *)aPath completion:(void(^)(BTJSON *body, NSHTTPURLResponse *response, NSError *error))completionBlock { + [self POST:aPath parameters:nil completion:completionBlock]; +} + +- (void)POST:(NSString *)aPath parameters:(NSDictionary *)parameters completion:(void(^)(BTJSON *body, NSHTTPURLResponse *response, NSError *error))completionBlock { + [self httpRequest:@"POST" path:aPath parameters:parameters completion:completionBlock]; +} + +- (void)PUT:(NSString *)aPath completion:(void(^)(BTJSON *body, NSHTTPURLResponse *response, NSError *error))completionBlock { + [self PUT:aPath parameters:nil completion:completionBlock]; +} + +- (void)PUT:(NSString *)aPath parameters:(NSDictionary *)parameters completion:(void(^)(BTJSON *body, NSHTTPURLResponse *response, NSError *error))completionBlock { + [self httpRequest:@"PUT" path:aPath parameters:parameters completion:completionBlock]; +} + +- (void)DELETE:(NSString *)aPath completion:(void(^)(BTJSON *body, NSHTTPURLResponse *response, NSError *error))completionBlock { + [self DELETE:aPath parameters:nil completion:completionBlock]; +} + +- (void)DELETE:(NSString *)aPath parameters:(NSDictionary *)parameters completion:(void(^)(BTJSON *body, NSHTTPURLResponse *response, NSError *error))completionBlock { + [self httpRequest:@"DELETE" path:aPath parameters:parameters completion:completionBlock]; +} + +#pragma mark - Underlying HTTP + +- (void)httpRequest:(NSString *)method path:(NSString *)aPath parameters:(NSDictionary *)parameters completion:(void(^)(BTJSON *body, NSHTTPURLResponse *response, NSError *error))completionBlock { + + BOOL hasHttpPrefix = aPath != nil && [aPath hasPrefix:@"http"]; + if (!hasHttpPrefix && (!self.baseURL || [self.baseURL.absoluteString isEqualToString:@""])) { + NSMutableDictionary *errorUserInfo = [NSMutableDictionary new]; + if (method) errorUserInfo[@"method"] = method; + if (aPath) errorUserInfo[@"path"] = aPath; + if (parameters) errorUserInfo[@"parameters"] = parameters; + completionBlock(nil, nil, [NSError errorWithDomain:BTHTTPErrorDomain code:BTHTTPErrorCodeMissingBaseURL userInfo:errorUserInfo]); + return; + } + + BOOL isNotDataURL = ![self.baseURL.scheme isEqualToString:@"data"]; + NSURL *fullPathURL; + if (aPath && isNotDataURL) { + if (hasHttpPrefix) { + fullPathURL = [NSURL URLWithString:aPath]; + } else { + fullPathURL = [self.baseURL URLByAppendingPathComponent:aPath]; + } + } else { + fullPathURL = self.baseURL; + } + + if (parameters == nil) { + parameters = [NSDictionary dictionary]; + } + NSMutableDictionary *mutableParameters = [NSMutableDictionary dictionaryWithDictionary:parameters]; + if (self.authorizationFingerprint) { + mutableParameters[@"authorization_fingerprint"] = self.authorizationFingerprint; + } + parameters = [mutableParameters copy]; + + if (!fullPathURL) { + // baseURL can be non-nil (e.g. an empty string) and still return nil for -URLByAppendingPathComponent: + // causing a crash when NSURLComponents.componentsWithString is called with nil. + NSMutableDictionary *errorUserInfo = [NSMutableDictionary new]; + if (method) errorUserInfo[@"method"] = method; + if (aPath) errorUserInfo[@"path"] = aPath; + if (parameters) errorUserInfo[@"parameters"] = parameters; + errorUserInfo[NSLocalizedFailureReasonErrorKey] = @"fullPathURL was nil"; + completionBlock(nil, nil, [NSError errorWithDomain:BTHTTPErrorDomain code:BTHTTPErrorCodeMissingBaseURL userInfo:errorUserInfo]); + return; + } + + NSURLComponents *components = [NSURLComponents componentsWithString:fullPathURL.absoluteString]; + + NSMutableDictionary *headers = [NSMutableDictionary dictionaryWithDictionary:self.defaultHeaders]; + + NSMutableURLRequest *request; + + if ([method isEqualToString:@"GET"] || [method isEqualToString:@"DELETE"]) { + if (isNotDataURL) { + NSString *encodedParametersString = [BTURLUtils queryStringWithDictionary:parameters]; + components.percentEncodedQuery = encodedParametersString; + } + request = [NSMutableURLRequest requestWithURL:components.URL]; + } else { + request = [NSMutableURLRequest requestWithURL:components.URL]; + + NSError *jsonSerializationError; + NSData *bodyData; + + if ([parameters isKindOfClass:[NSDictionary class]]) { + bodyData = [NSJSONSerialization dataWithJSONObject:parameters + options:0 + error:&jsonSerializationError]; + } + + if (jsonSerializationError != nil) { + completionBlock(nil, nil, jsonSerializationError); + return; + } + + [request setHTTPBody:bodyData]; + headers[@"Content-Type"] = @"application/json; charset=utf-8"; + } + if (self.tokenizationKey) { + headers[@"Client-Key"] = self.tokenizationKey; + } + [request setAllHTTPHeaderFields:headers]; + + [request setHTTPMethod:method]; + + // Perform the actual request + NSURLSessionTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + [self handleRequestCompletion:data response:response error:error completionBlock:completionBlock]; + }]; + [task resume]; +} + +- (void)handleRequestCompletion:(NSData *)data response:(NSURLResponse *)response error:(NSError *)error completionBlock:(void(^)(BTJSON *body, NSHTTPURLResponse *response, NSError *error))completionBlock { + // Handle errors for which the response is irrelevant + // e.g. SSL, unavailable network, etc. + if (error != nil) { + [self callCompletionBlock:completionBlock body:nil response:nil error:error]; + return; + } + + NSHTTPURLResponse *httpResponse; + if ([response isKindOfClass:[NSHTTPURLResponse class]]) { + httpResponse = (NSHTTPURLResponse *)response; + } else if ([response.URL.scheme isEqualToString:@"data"]) { + httpResponse = [[NSHTTPURLResponse alloc] initWithURL:response.URL statusCode:200 HTTPVersion:nil headerFields:nil]; + } + + NSString *responseContentType = [response MIMEType]; + + NSMutableDictionary *errorUserInfo = [NSMutableDictionary new]; + errorUserInfo[BTHTTPURLResponseKey] = httpResponse; + + if (httpResponse.statusCode >= 400) { + errorUserInfo[NSLocalizedFailureReasonErrorKey] = [NSHTTPURLResponse localizedStringForStatusCode:httpResponse.statusCode]; + + BTJSON *json; + if ([responseContentType isEqualToString:@"application/json"]) { + json = (data.length == 0) ? [BTJSON new] : [[BTJSON alloc] initWithData:data]; + if (!json.isError) { + errorUserInfo[BTHTTPJSONResponseBodyKey] = json; + NSString *errorResponseMessage = [json[@"error"][@"message"] asString]; + if (errorResponseMessage) { + errorUserInfo[NSLocalizedDescriptionKey] = errorResponseMessage; + } + } + } + + BTHTTPErrorCode errorCode = httpResponse.statusCode >= 500 ? BTHTTPErrorCodeServerError : BTHTTPErrorCodeClientError; + if (httpResponse.statusCode == 429) { + errorCode = BTHTTPErrorCodeRateLimitError; + errorUserInfo[NSLocalizedDescriptionKey] = @"You are being rate-limited."; + errorUserInfo[NSLocalizedRecoverySuggestionErrorKey] = @"Please try again in a few minutes."; + } else if (httpResponse.statusCode >= 500) { + errorUserInfo[NSLocalizedRecoverySuggestionErrorKey] = @"Please try again later."; + } + + NSError *error = [NSError errorWithDomain:BTHTTPErrorDomain + code:errorCode + userInfo:[errorUserInfo copy]]; + [self callCompletionBlock:completionBlock body:json response:httpResponse error:error]; + return; + } + + // Empty response is valid + BTJSON *json = (data.length == 0) ? [BTJSON new] : [[BTJSON alloc] initWithData:data]; + if (json.isError) { + if (![responseContentType isEqualToString:@"application/json"]) { + // Return error for unsupported response type + errorUserInfo[NSLocalizedFailureReasonErrorKey] = [NSString stringWithFormat:@"BTHTTP only supports application/json responses, received Content-Type: %@", responseContentType]; + NSError *returnedError = [NSError errorWithDomain:BTHTTPErrorDomain + code:BTHTTPErrorCodeResponseContentTypeNotAcceptable + userInfo:[errorUserInfo copy]]; + [self callCompletionBlock:completionBlock body:nil response:nil error:returnedError]; + } else { + [self callCompletionBlock:completionBlock body:nil response:nil error:json.asError]; + } + return; + } + + [self callCompletionBlock:completionBlock body:json response:httpResponse error:nil]; +} + +- (void)callCompletionBlock:(void(^)(BTJSON *body, NSHTTPURLResponse *response, NSError *error))completionBlock + body:(BTJSON *)jsonBody + response:(NSHTTPURLResponse *)response + error:(NSError *)error { + if (completionBlock) { + dispatch_async(self.dispatchQueue, ^{ + completionBlock(jsonBody, response, error); + }); + } +} + +- (dispatch_queue_t)dispatchQueue { + return _dispatchQueue ?: dispatch_get_main_queue(); +} + +#pragma mark - Default Headers + +- (NSDictionary *)defaultHeaders { + return @{ @"User-Agent": [self userAgentString], + @"Accept": [self acceptString], + @"Accept-Language": [self acceptLanguageString] }; +} + +- (NSString *)userAgentString { + return [NSString stringWithFormat:@"Braintree/iOS/%@", BRAINTREE_VERSION]; +} + +- (NSString *)platformString { + size_t size = 128; + char *hwModel = alloca(size); + + if (sysctlbyname("hw.model", hwModel, &size, NULL, 0) != 0) { + return nil; + } + + NSString *hwModelString = [NSString stringWithCString:hwModel encoding:NSUTF8StringEncoding]; +#if TARGET_IPHONE_SIMULATOR + hwModelString = [hwModelString stringByAppendingString:@"(simulator)"]; +#endif + return hwModelString; +} + +- (NSString *)architectureString { + size_t size = 128; + char *hwMachine = alloca(size); + + if (sysctlbyname("hw.machine", hwMachine, &size, NULL, 0) != 0) { + return nil; + } + + return [NSString stringWithCString:hwMachine encoding:NSUTF8StringEncoding]; +} + +- (NSString *)acceptString { + return @"application/json"; +} + +- (NSString *)acceptLanguageString { + NSLocale *locale = [NSLocale currentLocale]; + return [NSString stringWithFormat:@"%@-%@", + [locale objectForKey:NSLocaleLanguageCode], + [locale objectForKey:NSLocaleCountryCode]]; +} + +#pragma mark - Helpers + +- (NSArray *)pinnedCertificateData { + NSMutableArray *pinnedCertificates = [NSMutableArray array]; + for (NSData *certificateData in self.pinnedCertificates) { + [pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)]; + } + return pinnedCertificates; +} + +- (void)URLSession:(__unused NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler { + if ([[[challenge protectionSpace] authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) { + NSString *domain = challenge.protectionSpace.host; + SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust]; + + NSArray *policies = @[(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)]; + SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies); + SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)self.pinnedCertificateData); + SecTrustResultType result; + + OSStatus errorCode = SecTrustEvaluate(serverTrust, &result); + + BOOL evaluatesAsTrusted = (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed); + if (errorCode == errSecSuccess && evaluatesAsTrusted) { + NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust]; + completionHandler(NSURLSessionAuthChallengeUseCredential, credential); + } else { + completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, NULL); + } + } else { + completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, NULL); + } +} + +- (BOOL)isEqualToHTTP:(BTHTTP *)http { + return [self.baseURL isEqual:http.baseURL] && [self.authorizationFingerprint isEqualToString:http.authorizationFingerprint]; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + + if ([object isKindOfClass:[BTHTTP class]]) { + return [self isEqualToHTTP:object]; + } + + return NO; +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTHTTPErrors.m b/Pods/Braintree/BraintreeCore/BTHTTPErrors.m new file mode 100644 index 0000000..917a5ab --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTHTTPErrors.m @@ -0,0 +1,7 @@ +#import "BTHTTPErrors.h" + +NSString * const BTHTTPErrorDomain = @"com.braintreepayments.BTHTTPErrorDomain"; + +NSString * const BTHTTPURLResponseKey = @"com.braintreepayments.BTHTTPURLResponseKey"; + +NSString * const BTHTTPJSONResponseBodyKey = @"com.braintreepayments.BTHTTPJSONResponseBodyKey"; diff --git a/Pods/Braintree/BraintreeCore/BTJSON.m b/Pods/Braintree/BraintreeCore/BTJSON.m new file mode 100644 index 0000000..b56d406 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTJSON.m @@ -0,0 +1,257 @@ +#import "BTJSON.h" + +NSString * const BTJSONErrorDomain = @"com.briantreepayments.BTJSONErrorDomain"; + +@interface BTJSON () + +@property (nonatomic, strong) NSArray *subscripts; +@property (nonatomic, strong) id value; + +@end + +@implementation BTJSON + +@synthesize value = _value; + +- (instancetype)init { + self = [super init]; + if (self) { + self.subscripts = [NSMutableArray array]; + self.value = @{}; + } + return self; +} + +- (instancetype)initWithData:(NSData *)data { + NSError *error; + id value = [NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingAllowFragments + error:&error]; + if (error != nil) { + return self = [self initWithValue:error]; + } + + return self = [self initWithValue:value]; +} + +- (instancetype)initWithValue:(id)value { + self = [self init]; + if (self) { + self.value = value; + } + return self; +} + + +#pragma mark Subscripting + +- (id)objectForKeyedSubscript:(NSString *)key { + BTJSON *json = [[BTJSON alloc] initWithValue:_value]; + json.subscripts = [self.subscripts arrayByAddingObject:key]; + + return json; +} + +- (id)objectAtIndexedSubscript:(NSUInteger)idx { + BTJSON *json = [[BTJSON alloc] initWithValue:_value]; + json.subscripts = [self.subscripts arrayByAddingObject:@(idx)]; + + return json; +} + +- (id)value { + id value = _value; + for (id key in self.subscripts) { + if ([value isKindOfClass:[NSArray class]]) { + if (![key isKindOfClass:[NSNumber class]]) { + value = [self chainedErrorOrErrorWithCode:BTJSONErrorAccessInvalid userInfo:nil]; + break; + } + + NSUInteger idx = [(NSNumber *)key unsignedIntegerValue]; + if (idx >= [(NSArray *)value count]) { + value = nil; + break; + } + + value = [value objectAtIndexedSubscript:idx]; + } else if ([value isKindOfClass:[NSDictionary class]]) { + if (![key isKindOfClass:[NSString class]]) { + value = [self chainedErrorOrErrorWithCode:BTJSONErrorAccessInvalid userInfo:nil]; + break; + } + + value = [value objectForKeyedSubscript:key]; + } else { + value = [self chainedErrorOrErrorWithCode:BTJSONErrorValueInvalid userInfo:@{ NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"Attempted to index into a value that is neither an object nor an array using key (%@).", key] }]; + break; + } + } + return value; +} + +#pragma mark Validity Checks + +- (BOOL)isError { + return [self.value isKindOfClass:[NSError class]]; +} + +- (NSError *)asError { + if (![self.value isKindOfClass:[NSError class]]) { + return nil; + } + + return self.value; +} + +#pragma mark Generating JSON + +- (NSData *)asJSONAndReturnError:(NSError **)error { + return [NSJSONSerialization dataWithJSONObject:self.value + options:0 + error:error]; +} + +- (NSString *)asPrettyJSONAndReturnError:(NSError **)error { + return [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:self.value + options:NSJSONWritingPrettyPrinted + error:error] + encoding:NSUTF8StringEncoding]; +} + + +#pragma mark JSON Type Casts + +- (NSString *)asString { + if (![self.value isKindOfClass:[NSString class]]) { + return nil; + } + + return self.value; +} + +- (NSArray *)asArray { + if (![self.value isKindOfClass:[NSArray class]]) { + return nil; + } + + return self.value; +} + +- (NSDecimalNumber *)asNumber { + if (![self.value isKindOfClass:[NSNumber class]]) { + return nil; + } + + return [NSDecimalNumber decimalNumberWithDecimal:[self.value decimalValue]]; +} + +#pragma mark JSON Extension Type Casts + +- (NSURL *)asURL { + NSString *urlString = self.asString; + + if (urlString == nil) { + return nil; + } + + return [NSURL URLWithString:urlString]; +} + +- (NSArray *)asStringArray { + NSArray *array = (NSArray *)self.asArray; + + for (id obj in array) { + if (![obj isKindOfClass:[NSString class]]) { + return nil; + } + } + + return array; +} + +- (NSDictionary *)asDictionary { + NSDictionary *dictionary = self.value; + + if (![dictionary isKindOfClass:[NSDictionary class]]) { + return nil; + } + + return dictionary; +} + +- (NSInteger)asIntegerOrZero { + NSNumber *number = self.value; + + if (![number isKindOfClass:[NSNumber class]]) { + return 0; + } + + return number.integerValue; +} + +- (NSInteger)asEnum:(nonnull NSDictionary *)mapping orDefault:(NSInteger)defaultValue { + id key = self.value; + NSNumber *value = mapping[key]; + + if (value == nil || ![value isKindOfClass:[NSNumber class]]) { + return defaultValue; + } + + return value.integerValue; +} + +// @name JSON Type Checks + +- (BOOL)isString { + return [self.value isKindOfClass:[NSString class]]; +} + +- (BOOL)isNumber { + return [self.value isKindOfClass:[NSNumber class]]; +} + +- (BOOL)isArray { + return [self.value isKindOfClass:[NSArray class]]; +} + +- (BOOL)isObject { + return [self.value isKindOfClass:[NSDictionary class]]; +} + +- (BOOL)isTrue { + return [self.value isEqual:@YES]; +} + +- (BOOL)isFalse { + return [self.value isEqual:@NO]; +} + +- (BOOL)isNull { + return [self.value isKindOfClass:[NSNull class]]; +} + +#pragma mark Error Handling + +- (NSError *)chainedErrorOrErrorWithCode:(NSInteger)code + userInfo:(NSDictionary *)userInfo { + if ([_value isKindOfClass:[NSError class]]) { + return _value; + } + + return [NSError errorWithDomain:BTJSONErrorDomain + code:code + userInfo:userInfo]; +} + +#pragma mark - + +- (NSString *)description { + return [self debugDescription]; +} + +- (NSString *)debugDescription { + return [NSString stringWithFormat:@"", self, self.value]; +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTKeychain.h b/Pods/Braintree/BraintreeCore/BTKeychain.h new file mode 100644 index 0000000..99b7e12 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTKeychain.h @@ -0,0 +1,12 @@ +#import + +@interface BTKeychain : NSObject + ++ (BOOL)setString:(NSString *)string forKey:(NSString *)key; ++ (NSString *)stringForKey:(NSString *)key; + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key; ++ (NSData *)dataForKey:(NSString *)key; + + +@end diff --git a/Pods/Braintree/BraintreeCore/BTKeychain.m b/Pods/Braintree/BraintreeCore/BTKeychain.m new file mode 100644 index 0000000..fb631af --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTKeychain.m @@ -0,0 +1,98 @@ +#import "BTKeychain.h" +@import Security; + +@implementation BTKeychain + ++ (BOOL)setString:(NSString *)string forKey:(NSString *)key { + NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; + return [self setData:data forKey:key]; +} + ++ (NSString *)stringForKey:(NSString *)key { + NSData *data = [self dataForKey:key]; + return data == nil ? nil : [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; +} + ++ (NSString *)keychainKeyForKey:(NSString *)key { + return [NSString stringWithFormat:@"com.braintreepayments.Braintree-API.%@", key]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key { + if(!key) { + return NO; + } + + BOOL success = YES; + + key = [self keychainKeyForKey:key]; + + // First check if it already exists, by creating a search dictionary and requesting that + // nothing be returned, and performing the search anyway. + NSMutableDictionary *existsQueryDictionary = [NSMutableDictionary dictionary]; + + [existsQueryDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; + + // Add the keys to the search dict + [existsQueryDictionary setObject:@"Service" forKey:(__bridge id)kSecAttrService]; + [existsQueryDictionary setObject:key forKey:(__bridge id)kSecAttrAccount]; + + OSStatus res = SecItemCopyMatching((__bridge CFDictionaryRef)existsQueryDictionary, NULL); + if(res == errSecItemNotFound) { + if(data) { + NSMutableDictionary *addDict = existsQueryDictionary; + [addDict setObject:data forKey:(__bridge id)kSecValueData]; + [addDict setObject:(__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly forKey:(__bridge id)kSecAttrAccessible]; + + res = SecItemAdd((__bridge CFDictionaryRef)addDict, NULL); + if (res != errSecSuccess) { + success = NO; + } + } + } + else if(res == errSecSuccess) { + if(data) { + // Modify an existing one + // Actually pull it now of the keychain at this point. + NSDictionary *attributeDict = [NSDictionary dictionaryWithObject:data forKey:(__bridge id)kSecValueData]; + + res = SecItemUpdate((__bridge CFDictionaryRef)existsQueryDictionary, (__bridge CFDictionaryRef)attributeDict); + if (res != errSecSuccess) { + success = NO; + } + } else { + SecItemDelete((__bridge CFDictionaryRef)existsQueryDictionary); + } + } + else { + success = NO; + } + + return success; +} + ++ (NSData *)dataForKey:(NSString *)key { + + key = [self keychainKeyForKey:key]; + + NSMutableDictionary *existsQueryDictionary = [NSMutableDictionary dictionary]; + + [existsQueryDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; + + // Add the keys to the search dict + [existsQueryDictionary setObject:@"Service" forKey:(__bridge id)kSecAttrService]; + [existsQueryDictionary setObject:key forKey:(__bridge id)kSecAttrAccount]; + + // We want the data back! + [existsQueryDictionary setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData]; + + CFTypeRef cfData = NULL; + OSStatus res = SecItemCopyMatching((__bridge CFDictionaryRef)existsQueryDictionary, &cfData); + NSData *data = (id)CFBridgingRelease(cfData); + if(res == errSecSuccess) { + return data; + } + + return nil; +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTLogger.m b/Pods/Braintree/BraintreeCore/BTLogger.m new file mode 100644 index 0000000..83bbda1 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTLogger.m @@ -0,0 +1,85 @@ +#import + +#import "BTLogger_Internal.h" + +#define variadicLogLevel(level, format) \ + va_list args; \ + va_start(args, format); \ + [self logLevel:level format:format arguments:args]; \ + va_end(args); + + +@implementation BTLogger + ++ (instancetype)sharedLogger { + static BTLogger *instance; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + instance = [self new]; + }); + + return instance; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _level = BTLogLevelInfo; + } + return self; +} + +- (void)log:(NSString *)format, ... { + variadicLogLevel(BTLogLevelInfo, format) +} + +- (void)critical:(NSString *)format, ... { + variadicLogLevel(BTLogLevelCritical, format) +} + +- (void)error:(NSString *)format, ... { + variadicLogLevel(BTLogLevelError, format) +} + +- (void)warning:(NSString *)format, ... { + variadicLogLevel(BTLogLevelWarning, format) +} + +- (void)info:(NSString *)format, ... { + variadicLogLevel(BTLogLevelInfo, format) +} + +- (void)debug:(NSString *)format, ... { + variadicLogLevel(BTLogLevelDebug, format) +} + +- (void)logLevel:(BTLogLevel)level format:(NSString *)format arguments:(va_list)arguments { + if (level <= self.level) { + NSString *message = [[NSString alloc] initWithFormat:format arguments:arguments]; + if (self.logBlock) { + self.logBlock(level, message); + } else { + NSString *levelString = [[self class] levelString:level]; + NSLog(@"[BraintreeSDK] %@ %@", [levelString uppercaseString], message); + } + } +} + ++ (NSString *)levelString:(BTLogLevel)level { + switch (level) { + case BTLogLevelCritical: + return @"Critical"; + case BTLogLevelError: + return @"Error"; + case BTLogLevelWarning: + return @"Warning"; + case BTLogLevelInfo: + return @"Info"; + case BTLogLevelDebug: + return @"Debug"; + default: + return nil; + } +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTLogger_Internal.h b/Pods/Braintree/BraintreeCore/BTLogger_Internal.h new file mode 100644 index 0000000..932f05e --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTLogger_Internal.h @@ -0,0 +1,19 @@ +#import + +#import "BTLogger.h" + +@interface BTLogger () + +- (void)log:(NSString *)format, ...; +- (void)critical:(NSString *)format, ...; +- (void)error:(NSString *)format, ...; +- (void)warning:(NSString *)format, ...; +- (void)info:(NSString *)format, ...; +- (void)debug:(NSString *)format, ...; + +/** + @brief Custom block for handling log messages +*/ +@property (nonatomic, copy) void (^logBlock)(BTLogLevel level, NSString *message); + +@end diff --git a/Pods/Braintree/BraintreeCore/BTPaymentMethodNonce.m b/Pods/Braintree/BraintreeCore/BTPaymentMethodNonce.m new file mode 100644 index 0000000..8d5d4fb --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTPaymentMethodNonce.m @@ -0,0 +1,34 @@ +#import "BTPaymentMethodNonce.h" + +@interface BTPaymentMethodNonce () +@property (nonatomic, copy, readwrite) NSString *nonce; +@property (nonatomic, copy, readwrite) NSString *localizedDescription; +@property (nonatomic, copy, readwrite) NSString *type; +@property (nonatomic, readwrite, assign) BOOL isDefault; +@end + +@implementation BTPaymentMethodNonce + +- (instancetype)initWithNonce:(NSString *)nonce localizedDescription:(NSString *)description type:(NSString *)type { + if (!nonce) return nil; + + if (self = [super init]) { + self.nonce = nonce; + self.localizedDescription = description; + self.type = type; + } + return self; +} + +- (nullable instancetype)initWithNonce:(NSString *)nonce localizedDescription:(nullable NSString *)description { + return [self initWithNonce:nonce localizedDescription:description type:@"Unknown"]; +} + +- (nullable instancetype)initWithNonce:(NSString *)nonce localizedDescription:(NSString *)description type:(nonnull NSString *)type isDefault:(BOOL)isDefault { + if (self = [self initWithNonce:nonce localizedDescription:description type:type]) { + _isDefault = isDefault; + } + return self; +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTPaymentMethodNonceParser.m b/Pods/Braintree/BraintreeCore/BTPaymentMethodNonceParser.m new file mode 100644 index 0000000..64f5c7e --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTPaymentMethodNonceParser.m @@ -0,0 +1,61 @@ +#import "BTPaymentMethodNonce.h" +#import "BTPaymentMethodNonceParser.h" + +@interface BTPaymentMethodNonceParser () + +/// Dictionary of JSON parsing blocks keyed by types as strings. The blocks have the following type: +/// +/// `BTPaymentMethodNonce *(^)(NSDictionary *json)` +@property (nonatomic, strong) NSMutableDictionary *JSONParsingBlocks; + +@end + +@implementation BTPaymentMethodNonceParser + ++ (instancetype)sharedParser { + static BTPaymentMethodNonceParser *sharedParser; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedParser = [[BTPaymentMethodNonceParser alloc] init]; + }); + return sharedParser; +} + +- (NSMutableDictionary *)JSONParsingBlocks { + if (!_JSONParsingBlocks) { + _JSONParsingBlocks = [NSMutableDictionary dictionary]; + } + return _JSONParsingBlocks; +} + +- (BOOL)isTypeAvailable:(NSString *)type { + return self.JSONParsingBlocks[type] != nil; +} + +- (NSArray *)allTypes { + return self.JSONParsingBlocks.allKeys; +} + +- (void)registerType:(NSString *)type withParsingBlock:(BTPaymentMethodNonce *(^)(BTJSON *))jsonParsingBlock { + if (jsonParsingBlock) { + self.JSONParsingBlocks[type] = [jsonParsingBlock copy]; + } +} + +- (BTPaymentMethodNonce *)parseJSON:(BTJSON *)json withParsingBlockForType:(NSString *)type { + BTPaymentMethodNonce *(^block)(BTJSON *) = self.JSONParsingBlocks[type]; + if (!json) { + return nil; + } + if (block) { + return block(json); + } + // Unregistered types should fall back to parsing basic nonce and description from JSON + if (![json[@"nonce"] isString]) return nil; + return [[BTPaymentMethodNonce alloc] initWithNonce:[json[@"nonce"] asString] + localizedDescription:[json[@"description"] asString] + type:@"Unknown" + isDefault:[json[@"default"] isTrue]]; +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTPostalAddress.m b/Pods/Braintree/BraintreeCore/BTPostalAddress.m new file mode 100644 index 0000000..25a3121 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTPostalAddress.m @@ -0,0 +1,24 @@ +#import "BTPostalAddress.h" + +@implementation BTPostalAddress + +// Property names follow the `Braintree_Address` convention as documented at: +// https://developers.braintreepayments.com/ios+php/reference/response/address + +- (id)copyWithZone:(__unused NSZone *)zone { + BTPostalAddress *address = [[BTPostalAddress alloc] init]; + address.recipientName = self.recipientName; + address.streetAddress = self.streetAddress; + address.extendedAddress = self.extendedAddress; + address.locality = self.locality; + address.countryCodeAlpha2 = self.countryCodeAlpha2; + address.postalCode = self.postalCode; + address.region = self.region; + return address; +} + +- (NSString *)debugDescription { + return [NSString stringWithFormat:@"<%@:%p \"%@\" %@, %@, %@, %@, %@ %@ %@>", NSStringFromClass([self class]), self, [self description], self.recipientName, self.streetAddress, self.extendedAddress, self.locality, self.region, self.postalCode, self.countryCodeAlpha2]; +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTTokenizationService.m b/Pods/Braintree/BraintreeCore/BTTokenizationService.m new file mode 100644 index 0000000..d1f5a19 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTTokenizationService.m @@ -0,0 +1,74 @@ +#import "BTTokenizationService.h" + +NSString * const BTTokenizationServiceErrorDomain = @"com.braintreepayments.BTTokenizationServiceErrorDomain"; +NSString * const BTTokenizationServiceViewPresentingDelegateOption = @"viewControllerPresentingDelegate"; +NSString * const BTTokenizationServiceAppSwitchDelegateOption = @"BTTokenizationServiceAppSwitchDelegateOption"; +NSString * const BTTokenizationServicePayPalScopesOption = @"BTPaymentRequest.additionalPayPalScopes"; +NSString * const BTTokenizationServiceAmountOption = @"BTTokenizationServiceAmountOption"; +NSString * const BTTokenizationServiceNonceOption = @"BTTokenizationServiceNonceOption"; + +@interface BTTokenizationService () +/// Dictionary of tokenization blocks keyed by types as strings. The blocks have the following type: +/// +/// `void (^)(BTAPIClient * _Nonnull, NSDictionary * _Nullable, void (^ _Nonnull)(BTPaymentMethodNonce * _Nullable, NSError * _Nullable))` +@property (nonatomic, strong) NSMutableDictionary *tokenizationBlocks; +@end + +@implementation BTTokenizationService + ++ (instancetype)sharedService { + static BTTokenizationService *sharedService; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedService = [[BTTokenizationService alloc] init]; + }); + return sharedService; +} + +- (NSMutableDictionary *)tokenizationBlocks { + if (!_tokenizationBlocks) { + _tokenizationBlocks = [NSMutableDictionary dictionary]; + } + return _tokenizationBlocks; +} + +- (void)registerType:(NSString *)type withTokenizationBlock:(void (^)(BTAPIClient * _Nonnull, NSDictionary * _Nullable, void (^ _Nonnull)(BTPaymentMethodNonce * _Nullable, NSError * _Nullable)))tokenizationBlock +{ + self.tokenizationBlocks[type] = [tokenizationBlock copy]; +} + +- (BOOL)isTypeAvailable:(NSString *)type { + return self.tokenizationBlocks[type] != nil; +} + +- (NSArray *)allTypes { + return [self.tokenizationBlocks allKeys]; +} + +- (void)tokenizeType:(NSString *)type + withAPIClient:(BTAPIClient *)apiClient + completion:(void (^)(BTPaymentMethodNonce * _Nullable, NSError * _Nullable))completion +{ + [self tokenizeType:type options:nil withAPIClient:apiClient completion:completion]; +} + +- (void)tokenizeType:(NSString *)type + options:(NSDictionary *)options + withAPIClient:(BTAPIClient *)apiClient + completion:(void (^)(BTPaymentMethodNonce * _Nullable, NSError * _Nullable))completion +{ + void(^block)(BTAPIClient *, NSDictionary *, void(^)(BTPaymentMethodNonce *, NSError *)) = self.tokenizationBlocks[type]; + if (block) { + block(apiClient, options ?: @{}, completion); + } else { + NSError *error = [NSError errorWithDomain:BTTokenizationServiceErrorDomain + code:BTTokenizationServiceErrorTypeNotRegistered + userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"%@ processing not available", type], + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"Type '%@' is not registered with BTTokenizationService", type], + NSLocalizedRecoverySuggestionErrorKey: [NSString stringWithFormat:@"Please link Braintree%@.framework to your app", type] + }]; + completion(nil, error); + } +} + +@end diff --git a/Pods/Braintree/BraintreeCore/BTURLUtils.h b/Pods/Braintree/BraintreeCore/BTURLUtils.h new file mode 100644 index 0000000..4930ff3 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTURLUtils.h @@ -0,0 +1,9 @@ +#import + +@interface BTURLUtils : NSObject + ++ (NSURL *)URLfromURL:(NSURL *)URL withAppendedQueryDictionary:(NSDictionary *)dictionary; ++ (NSString *)queryStringWithDictionary:(NSDictionary *)dict; ++ (NSDictionary *)dictionaryForQueryString:(NSString *)queryString; + +@end diff --git a/Pods/Braintree/BraintreeCore/BTURLUtils.m b/Pods/Braintree/BraintreeCore/BTURLUtils.m new file mode 100644 index 0000000..2d28fdd --- /dev/null +++ b/Pods/Braintree/BraintreeCore/BTURLUtils.m @@ -0,0 +1,87 @@ +#import "BTURLUtils.h" + +@implementation BTURLUtils + ++ (NSURL *)URLfromURL:(NSURL *)URL withAppendedQueryDictionary:(NSDictionary *)dictionary { + if (!URL) { + return nil; + } + + NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:URL resolvingAgainstBaseURL:NO]; + urlComponents.percentEncodedQuery = [self queryStringWithDictionary:dictionary]; + return urlComponents.URL; +} + ++ (NSString *)queryStringWithDictionary:(NSDictionary *)dict { + NSMutableString *queryString = [NSMutableString string]; + for (id key in dict) { + NSString *encodedKey = [self stringByURLEncodingAllCharactersInString:[key description]]; + id value = [dict objectForKey:key]; + if([value isKindOfClass:[NSArray class]]) { + for(id obj in value) { + [queryString appendFormat:@"%@%%5B%%5D=%@&", + encodedKey, + [self stringByURLEncodingAllCharactersInString:[obj description]] + ]; + } + } else if([value isKindOfClass:[NSDictionary class]]) { + for(id subkey in value) { + [queryString appendFormat:@"%@%%5B%@%%5D=%@&", + encodedKey, + [self stringByURLEncodingAllCharactersInString:[subkey description]], + [self stringByURLEncodingAllCharactersInString:[[value objectForKey:subkey] description]] + ]; + } + } else if([value isKindOfClass:[NSNull class]]) { + [queryString appendFormat:@"%@=&", encodedKey]; + } else { + [queryString appendFormat:@"%@=%@&", + encodedKey, + [self stringByURLEncodingAllCharactersInString:[value description]] + ]; + } + } + if([queryString length] > 0) { + [queryString deleteCharactersInRange:NSMakeRange([queryString length] - 1, 1)]; // remove trailing & + } + return queryString; +} + ++ (NSString *)stringByURLEncodingAllCharactersInString:(NSString *)aString { + // See Section 2.2. http://www.ietf.org/rfc/rfc2396.txt + NSString *reservedCharacters = @";/?:@&=+$,"; + + NSMutableCharacterSet *URLQueryPartAllowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy]; + [URLQueryPartAllowedCharacterSet removeCharactersInString:reservedCharacters]; + + return [aString stringByAddingPercentEncodingWithAllowedCharacters:URLQueryPartAllowedCharacterSet]; +} + ++ (NSDictionary *)dictionaryForQueryString:(NSString *)queryString { + NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; + NSArray *components = [queryString componentsSeparatedByString:@"&"]; + for (NSString *keyValueString in components) { + if ([keyValueString length] == 0) { + continue; + } + + NSArray *keyValueArray = [keyValueString componentsSeparatedByString:@"="]; + NSString *key = [self percentDecodedStringForString:keyValueArray[0]]; + if (!key) { + continue; + } + if (keyValueArray.count == 2) { + NSString *value = [self percentDecodedStringForString:keyValueArray[1]]; + parameters[key] = value; + } else { + parameters[key] = [NSNull null]; + } + } + return [NSDictionary dictionaryWithDictionary:parameters]; +} + ++ (NSString *)percentDecodedStringForString:(NSString *)string { + return [[string stringByReplacingOccurrencesOfString:@"+" withString:@" "] stringByRemovingPercentEncoding]; +} + +@end diff --git a/Pods/Braintree/BraintreeCore/Braintree-Version.h b/Pods/Braintree/BraintreeCore/Braintree-Version.h new file mode 100644 index 0000000..a889f5c --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Braintree-Version.h @@ -0,0 +1 @@ +#define BRAINTREE_VERSION (@"4.9.6") diff --git a/Pods/Braintree/BraintreeCore/Public/BTAPIClient.h b/Pods/Braintree/BraintreeCore/Public/BTAPIClient.h new file mode 100644 index 0000000..b5087c4 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTAPIClient.h @@ -0,0 +1,112 @@ +#import +#import "BTClientMetadata.h" +#import "BTConfiguration.h" +#import "BTJSON.h" + +@class BTPaymentMethodNonce; + +NS_ASSUME_NONNULL_BEGIN + +extern NSString *const BTAPIClientErrorDomain; + +typedef NS_ENUM(NSInteger, BTAPIClientErrorType) { + BTAPIClientErrorTypeUnknown = 0, + + /// Configuration fetch failed + BTAPIClientErrorTypeConfigurationUnavailable, + + /// The authorization provided to the API client is insufficient + BTAPIClientErrorTypeNotAuthorized, +}; + +/** + @class BTAPIClient + @brief This class acts as the entry point for accessing the Braintree APIs via common HTTP methods performed on API endpoints. + @discussion It also manages authentication via tokenization key and provides access to a merchant's gateway configuration. +*/ +@interface BTAPIClient : NSObject + +/** + @brief Initialize a new API client. + + @param authorization Your tokenization key or client token. Passing an invalid value may return `nil`. + @return A Braintree API client, or `nil` if initialization failed. +*/ +- (nullable instancetype)initWithAuthorization:(NSString *)authorization; + +/** + @brief Create a copy of an existing API client, but specify a new source and integration type. + @discussion This provides a way to override an API client's source and integration metadata, which + is captured and sent to Braintree as part of the analytics we track. +*/ +- (instancetype)copyWithSource:(BTClientMetadataSourceType)source + integration:(BTClientMetadataIntegrationType)integration; + +/** + @brief Provides configuration data as a `BTJSON` object. + + @discussion The configuration data can be used by supported payment options to configure themselves + dynamically through the Control Panel. It also contains configuration options for the + Braintree SDK Core components. + + @note This method is asynchronous because it requires a network call to fetch the + configuration for a merchant account from Braintree servers. This configuration is + cached on subsequent calls for better performance. +*/ +- (void)fetchOrReturnRemoteConfiguration:(void (^)(BTConfiguration * _Nullable configuration, NSError * _Nullable error))completionBlock; + +/** + @brief Fetches a customer's vaulted payment method nonces. + + @discussion Must be using client token with a customer ID specified. + + @param completion Callback that returns an array of payment method nonces. + On success, `paymentMethodNonces` contains the nonces and `error` is `nil`. The default payment method nonce, if one exists, will be first. + On failure, `error` contains the error that occured and `paymentMethodNonces` is `nil`. +*/ +- (void)fetchPaymentMethodNonces:(void(^)(NSArray * _Nullable paymentMethodNonces, NSError * _Nullable error))completion; + +/** + @brief Fetches a customer's vaulted payment method nonces. + + @discussion Must be using client token with a customer ID specified. + + @param defaultFirst Specifies whether to sorts the fetched payment method nonces with the default payment method or the most recently used payment method first + @param completion Callback that returns an array of payment method nonces +*/ +- (void)fetchPaymentMethodNonces:(BOOL)defaultFirst + completion:(void(^)(NSArray * _Nullable paymentMethodNonces, NSError * _Nullable error))completion; + +/** + @brief Perfom an HTTP GET on a URL composed of the configured from environment and the given path. + + @param path The endpoint URI path. + @param parameters Optional set of query parameters to be encoded with the request. + @param completionBlock A block object to be executed when the request finishes. + On success, `body` and `response` will contain the JSON body response and the + HTTP response and `error` will be `nil`; on failure, `body` and `response` will be + `nil` and `error` will contain the error that occurred. +*/ +- (void)GET:(NSString *)path + parameters:(nullable NSDictionary *)parameters + completion:(nullable void(^)(BTJSON * _Nullable body, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error))completionBlock; + +/** + @brief Perfom an HTTP POST on a URL composed of the configured from environment and the given path. + + @param path The endpoint URI path. + @param parameters Optional set of parameters to be JSON encoded and sent in the body of the request. + @param completionBlock A block object to be executed when the request finishes. + On success, `body` and `response` will contain the JSON body response and the + HTTP response and `error` will be `nil`; on failure, `body` and `response` will be + `nil` and `error` will contain the error that occurred. +*/ +- (void)POST:(NSString *)path + parameters:(nullable NSDictionary *)parameters + completion:(nullable void(^)(BTJSON * _Nullable body, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error))completionBlock; + +- (instancetype)init __attribute__((unavailable("Use initWithAuthorization: instead."))); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCore/Public/BTAppSwitch.h b/Pods/Braintree/BraintreeCore/Public/BTAppSwitch.h new file mode 100644 index 0000000..10f8c95 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTAppSwitch.h @@ -0,0 +1,171 @@ +#import + +@protocol BTAppSwitchHandler; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - BTAppSwitch + +/** + @class BTAppSwitch + @brief Handles return URLs when returning from app switch and routes the return URL to the correct app switch handler class. + @discussion `returnURLScheme` must contain your app's registered URL Type that starts with the app's bundle + ID. When your app returns from app switch, the app delegate should call `handleOpenURL:sourceApplication:` +*/ +@interface BTAppSwitch : NSObject + +/** + @brief The URL scheme to return to this app after switching to another app. + + @discussion This URL scheme must be registered as a URL Type in the app's info.plist, and it must start with the app's bundle ID. +*/ +@property (nonatomic, copy) NSString *returnURLScheme; + +/** + @brief The singleton instance +*/ ++ (instancetype)sharedInstance; + +/** + @brief Sets the return URL scheme for your app. + + @discussion This must be configured if your app integrates a payment option that may switch to either + Mobile Safari or to another app to finish the payment authorization workflow. + + @param returnURLScheme The return URL scheme +*/ ++ (void)setReturnURLScheme:(NSString *)returnURLScheme; + +/** + @brief Handles a return from app switch + + @param url The URL that was opened to return to your app + @param sourceApplication The source app that requested the launch of your app + @return `YES` if the app switch successfully handled the URL, or `NO` if the attempt to handle the URL failed. +*/ ++ (BOOL)handleOpenURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication; + +/** + @brief Handles a return from app switch + + @param url The URL that was opened to return to your app + @param options The options dictionary provided by `application:openURL:options:` + @return `YES` if the app switch successfully handled the URL, or `NO` if the attempt to handle the URL failed. +*/ ++ (BOOL)handleOpenURL:(NSURL *)url options:(NSDictionary *)options; + +/** + @brief Registers a class that knows how to handle a return from app switch +*/ +- (void)registerAppSwitchHandler:(Class)handler; + +/** + @brief Unregisters a class that knows how to handle a return from app switch +*/ +- (void)unregisterAppSwitchHandler:(Class)handler; + +- (BOOL)handleOpenURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication; + +@end + +#pragma mark - BTAppSwitchDelegate + +extern NSString * const BTAppSwitchWillSwitchNotification; +extern NSString * const BTAppSwitchDidSwitchNotification; +extern NSString * const BTAppSwitchWillProcessPaymentInfoNotification; +extern NSString * const BTAppSwitchNotificationTargetKey; + +/** + @brief Specifies the destination of an app switch +*/ +typedef NS_ENUM(NSInteger, BTAppSwitchTarget) { + BTAppSwitchTargetUnknown = 0, + /// Native app + BTAppSwitchTargetNativeApp, + /// Browser (i.e. Mobile Safari) + BTAppSwitchTargetWebBrowser, +}; + +/** + @brief Protocol for receiving payment lifecycle messages from a payment option that may initiate an app or browser switch event to authorize payments. +*/ +@protocol BTAppSwitchDelegate + +/** + @brief The app switcher will perform an app switch in order to obtain user payment authorization. + + @discussion Your implementation of this method may set your app to the state + it should be in if the user manually app-switches back to your app. + For example, re-enable any controls that are disabled. + + @param appSwitcher The app switcher +*/ +- (void)appSwitcherWillPerformAppSwitch:(id)appSwitcher; + +/** + @brief Delegates receive this message when the app switcher has successfully performed an app switch. + + @discussion You may use this hook to prepare your UI for app switch return. Keep in mind that + users may manually switch back to your app via the iOS task manager. + + @note You may also hook into the app switch lifecycle via UIApplicationWillResignActiveNotification. + + @param appSwitcher The app switcher instance performing user authentication + @param target The destination that was actually used for this app switch +*/ +- (void)appSwitcher:(id)appSwitcher didPerformSwitchToTarget:(BTAppSwitchTarget)target; + +/** + @brief The app switcher has obtained user payment details and/or user authorization and will process the results. + + @discussion This typically indicates asynchronous network activity. + When you receive this message, your UI should indicate activity. + + In the case of an app switch, this message indicates that the user has returned to this app; + this is usually after handleAppSwitchReturnURL: is called in your UIApplicationDelegate. + + @note You may also hook into the app switch lifecycle via UIApplicationWillResignActiveNotification. + + @param appSwitcher The app switcher +*/ +- (void)appSwitcherWillProcessPaymentInfo:(id)appSwitcher; + +@end + +#pragma mark - BTAppSwitchHandler protocol + +/** + @protocol BTAppSwitchHandler + @brief A protocol for handling the return from switching out of an app to gather payment information. + @note The app may switch out to Mobile Safari or to a native app. +*/ +@protocol BTAppSwitchHandler + +@required + +/** + @brief Determine whether the app switch return URL can be handled. + + @param url the URL you receive in `application:openURL:sourceApplication:annotation` when returning to your app + @param sourceApplication The source application you receive in `application:openURL:sourceApplication:annotation` + @return `YES` when the object can handle returning from the application with a URL +*/ ++ (BOOL)canHandleAppSwitchReturnURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication; + +/** + @brief Pass control back to `BTPayPalDriver` after returning from app or browser switch. + + @param url The URL you receive in `application:openURL:sourceApplication:annotation` +*/ ++ (void)handleAppSwitchReturnURL:(NSURL *)url; + +@optional + +/** + @brief Indicates whether an iOS app is installed and available for app switch. +*/ +- (BOOL)isiOSAppAvailableForAppSwitch; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCore/Public/BTBinData.h b/Pods/Braintree/BraintreeCore/Public/BTBinData.h new file mode 100644 index 0000000..9771883 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTBinData.h @@ -0,0 +1,60 @@ +#import +#import "BTJSON.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface BTBinData : NSObject + +/** + @brief Create a `BTBinData` object from JSON. + */ +- (instancetype)initWithJSON:(BTJSON *)json; + +/** + @brief Whether the card is a prepaid card. Possible values: Yes/No/Unknown + */ +@property (nonatomic, nullable, readonly, copy) NSString *prepaid; + +/** + @brief Whether the card is a healthcare card. Possible values: Yes/No/Unknown + */ +@property (nonatomic, nullable, readonly, copy) NSString *healthcare; + +/** + @brief Whether the card is a debit card. Possible values: Yes/No/Unknown + */ +@property (nonatomic, nullable, readonly, copy) NSString *debit; + +/** + @brief A value indicating whether the issuing bank's card range is regulated by the Durbin Amendment due to the bank's assets. Possible values: Yes/No/Unknown + */ +@property (nonatomic, nullable, readonly, copy) NSString *durbinRegulated; + +/** + @brief Whether the card type is a commercial card and is capable of processing Level 2 transactions. Possible values: Yes/No/Unknown + */ +@property (nonatomic, nullable, readonly, copy) NSString *commercial; + +/** + @brief Whether the card is a payroll card. Possible values: Yes/No/Unknown + */ +@property (nonatomic, nullable, readonly, copy) NSString *payroll; + +/** + @brief The bank that issued the credit card, if available. + */ +@property (nonatomic, nullable, readonly, copy) NSString *issuingBank; + +/** + @brief The country that issued the credit card, if available. + */ +@property (nonatomic, nullable, readonly, copy) NSString *countryOfIssuance; + +/** + @brief The code for the product type of the card (e.g. `D` (Visa Signature Preferred), `G` (Visa Business)), if available. + */ +@property (nonatomic, nullable, readonly, copy) NSString *productId; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCore/Public/BTClientMetadata.h b/Pods/Braintree/BraintreeCore/Public/BTClientMetadata.h new file mode 100644 index 0000000..66ff103 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTClientMetadata.h @@ -0,0 +1,60 @@ +#import + +typedef NS_ENUM(NSInteger, BTClientMetadataSourceType) { + BTClientMetadataSourceUnknown = 0, + BTClientMetadataSourcePayPalApp, + BTClientMetadataSourcePayPalBrowser, + BTClientMetadataSourceVenmoApp, + BTClientMetadataSourceForm, +}; + +typedef NS_ENUM(NSInteger, BTClientMetadataIntegrationType) { + BTClientMetadataIntegrationCustom, + BTClientMetadataIntegrationDropIn, + BTClientMetadataIntegrationDropIn2, + BTClientMetadataIntegrationUnknown +}; + +NS_ASSUME_NONNULL_BEGIN + +/** + @class BTClientMetadata + @brief Represents the metadata associated with a session for posting along with payment data during tokenization + + @discussion When a payment method is tokenized, the client api accepts parameters under + _meta which are used to determine where payment data originated. + + In general, this data may evolve and be used in different ways by different + integrations in a single app. For example, if both Apple Pay and drop in are + used. In this case, the source and integration may change over time, while + the sessionId should remain constant. To achieve this, users of this class + should use `mutableCopy` to create a new copy based on the existing session + and then update the object as needed. +*/ +@interface BTClientMetadata : NSObject + +@property (nonatomic, assign, readonly) BTClientMetadataIntegrationType integration; +@property (nonatomic, assign, readonly) BTClientMetadataSourceType source; + +/** + @brief Auto-generated UUID +*/ +@property (nonatomic, copy, readonly) NSString *sessionId; + +#pragma mark Derived Properties + +@property (nonatomic, copy, readonly) NSString *integrationString; +@property (nonatomic, copy, readonly) NSString *sourceString; +@property (nonatomic, strong, readonly) NSDictionary *parameters; + +@end + +@interface BTMutableClientMetadata : BTClientMetadata + +- (void)setIntegration:(BTClientMetadataIntegrationType)integration; +- (void)setSource:(BTClientMetadataSourceType)source; +- (void)setSessionId:(NSString *)sessionId; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCore/Public/BTClientToken.h b/Pods/Braintree/BraintreeCore/Public/BTClientToken.h new file mode 100644 index 0000000..ccb1c87 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTClientToken.h @@ -0,0 +1,50 @@ +#import +#import "BTJSON.h" + +NS_ASSUME_NONNULL_BEGIN + +extern NSString * const BTClientTokenKeyVersion; +extern NSString * const BTClientTokenErrorDomain; +extern NSString * const BTClientTokenKeyAuthorizationFingerprint; +extern NSString * const BTClientTokenKeyConfigURL; + +typedef NS_ENUM(NSInteger, BTClientTokenError) { + BTClientTokenErrorUnknown = 0, + BTClientTokenErrorInvalid, + BTClientTokenErrorUnsupportedVersion, +}; + +@interface BTClientToken : NSObject + +/** + @brief The client token as a BTJSON object +*/ +@property (nonatomic, readonly, strong) BTJSON *json; + +/** + @brief The extracted authorization fingerprint +*/ +@property (nonatomic, readonly, copy) NSString *authorizationFingerprint; + +/** + @brief The extracted configURL +*/ +@property (nonatomic, readonly, strong) NSURL *configURL; + +/** + @brief The original string used to initialize this instance +*/ +@property (nonatomic, readonly, copy) NSString *originalValue; + +#pragma mark - Initializers + +/** + @brief Initialize a client token with a client token string generated by a Braintree Server Library. +*/ +- (nullable instancetype)initWithClientToken:(NSString *)clientToken error:(NSError **)error NS_DESIGNATED_INITIALIZER; + +- (instancetype)init __attribute__((unavailable("Please use initWithClientToken:error: instead."))); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCore/Public/BTConfiguration.h b/Pods/Braintree/BraintreeCore/Public/BTConfiguration.h new file mode 100644 index 0000000..c629126 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTConfiguration.h @@ -0,0 +1,31 @@ +#import +#import "BTJSON.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface BTConfiguration : NSObject + +- (instancetype)initWithJSON:(BTJSON *)json NS_DESIGNATED_INITIALIZER; + +/** + @brief The merchant account's configuration as a `BTJSON` object +*/ +@property (nonatomic, readonly, strong) BTJSON *json; + +#pragma mark - Undesignated initializers (do not use) + +- (instancetype)init __attribute__((unavailable("Please use initWithJSON: instead."))); + +/** + @brief Returns true if the corresponding beta flag is set, otherwise returns false +*/ ++ (BOOL)isBetaEnabledPaymentOption:(NSString*)paymentOption DEPRECATED_MSG_ATTRIBUTE("Pay with Venmo is no longer in beta"); + +/** + @brief Set a corresponding beta flag +*/ ++ (void)setBetaPaymentOption:(NSString*)paymentOption isEnabled:(BOOL)isEnabled DEPRECATED_MSG_ATTRIBUTE("Pay with Venmo is no longer in beta"); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCore/Public/BTEnums.h b/Pods/Braintree/BraintreeCore/Public/BTEnums.h new file mode 100644 index 0000000..de66d6b --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTEnums.h @@ -0,0 +1,18 @@ +/** + @brief Card type + */ +typedef NS_ENUM(NSInteger, BTCardNetwork) { + BTCardNetworkUnknown = 0, + BTCardNetworkAMEX, + BTCardNetworkDinersClub, + BTCardNetworkDiscover, + BTCardNetworkMasterCard, + BTCardNetworkVisa, + BTCardNetworkJCB, + BTCardNetworkLaser, + BTCardNetworkMaestro, + BTCardNetworkUnionPay, + BTCardNetworkSolo, + BTCardNetworkSwitch, + BTCardNetworkUKMaestro, +}; diff --git a/Pods/Braintree/BraintreeCore/Public/BTErrors.h b/Pods/Braintree/BraintreeCore/Public/BTErrors.h new file mode 100644 index 0000000..2b7eb11 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTErrors.h @@ -0,0 +1,8 @@ +#import + +#pragma mark NSError userInfo Keys + +/** + @brief NSError userInfo key for validation errors. +*/ +extern NSString * _Nonnull const BTCustomerInputBraintreeValidationErrorsKey; diff --git a/Pods/Braintree/BraintreeCore/Public/BTHTTPErrors.h b/Pods/Braintree/BraintreeCore/Public/BTHTTPErrors.h new file mode 100644 index 0000000..7bb6e40 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTHTTPErrors.h @@ -0,0 +1,34 @@ +#import + +/** + @brief The error domain for BTHTTP errors +*/ +extern NSString * const BTHTTPErrorDomain; + +/** + @brief Key for userInfo dictionary that contains the NSHTTPURLResponse from server when it returns an HTTP error +*/ +extern NSString * const BTHTTPURLResponseKey; + +/** + @brief Key for userInfo dictionary that contains the BTJSON body of the HTTP error response +*/ +extern NSString * const BTHTTPJSONResponseBodyKey; + +/** + @brief BTHTTP error codes +*/ +typedef NS_ENUM(NSInteger, BTHTTPErrorCode) { + /// Unknown error (reserved) + BTHTTPErrorCodeUnknown = 0, + /// The response had a Content-Type header that is not supported + BTHTTPErrorCodeResponseContentTypeNotAcceptable, + /// The response was a 4xx error, e.g. 422, indicating a problem with the client's request + BTHTTPErrorCodeClientError, + /// The response was a 403 server error + BTHTTPErrorCodeServerError, + /// The BTHTTP instance was missing a base URL + BTHTTPErrorCodeMissingBaseURL, + /// The response was a 429, indicating a rate limiting error + BTHTTPErrorCodeRateLimitError +}; diff --git a/Pods/Braintree/BraintreeCore/Public/BTJSON.h b/Pods/Braintree/BraintreeCore/Public/BTJSON.h new file mode 100644 index 0000000..5b22dd3 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTJSON.h @@ -0,0 +1,127 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +extern NSString * const BTJSONErrorDomain; + +typedef NS_ENUM(NSInteger, BTJSONErrorCode) { + BTJSONErrorValueUnknown = 0, + BTJSONErrorValueInvalid = 1, + BTJSONErrorAccessInvalid = 2, +}; + +/** + @brief A type-safe wrapper around JSON + + @see http://www.json.org/ + + @discussion The primary goal of this class is to two-fold: (1) prevent bugs by staying true to JSON (json.org) + rather than interpreting it in mysterious ways; (2) prevent bugs by making JSON interpretation + as un-surprising as possible. + + Most notably, type casting occurs via the as* nullable methods; errors are deferred and can be checked explicitly using isError and asError. + + @code + ## Example Data: + { + "foo": "bar", + "baz": [1, 2, 3] + } + + ## Example Usage: + + let json : BTJSON = BTJSON(data:data); + json.isError // false + json.isObject // true + json.isNumber // false + json.asObject // self + json["foo"] // JSON(@"bar") + json["foo"].isString // true + json["foo"].asString // @"bar" + json["baz"].asString // null + json["baz"]["quux"].isError // true + json["baz"]["quux"].asError // NSError(domain: BTJSONErrorDomain, code: BTJSONErrorCodeTypeInvalid) + json["baz"][0].asError // null + json["baz"][0].asInteger // + json["random"]["nested"]["things"][3].isError // true + + let json : BTJSON = BTJSON() // json.asJson => {} + json["foo"][0] = "bar" // json.asJSON => { "foo": ["bar"] } + json["baz"] = [ 1, 2, 3 ] // json.asJSON => { "foo": ["bar"], "baz": [1,2,3] } + json["quux"] = NSSet() // json.isError => true, json.asJSON => throws NSError(domain: BTJSONErrorDomain, code: BTJSONErrorInvalidData) + @endcode +*/ +@interface BTJSON : NSObject + +- (instancetype)init NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithValue:(id)value; + +- (instancetype)initWithData:(NSData *)data; + +/// @name Subscripting + +/** + @brief Indexes into the JSON as if the current value is an object + + @discussion Notably, this method will always return successfully; however, if the value is not an object, the JSON will wrap an error. +*/ +- (id)objectForKeyedSubscript:(NSString *)key; + +/** + @brief Indexes into the JSON as if the current value is an array + + @discussion Notably, this method will always return successfully; however, if the value is not an array, the JSON will wrap an error. +*/ +- (BTJSON *)objectAtIndexedSubscript:(NSUInteger)idx; + +/// @name Validity Checks + +@property (nonatomic, assign, readonly) BOOL isError; + +- (nullable NSError *)asError; + +/// @name Generating JSON + +- (nullable NSData *)asJSONAndReturnError:(NSError **)error; +- (nullable NSString *)asPrettyJSONAndReturnError:(NSError **)error; + +/// @name JSON Type Casts + +- (nullable NSString *)asString; + +- (nullable NSArray *)asArray; + +- (nullable NSDecimalNumber *)asNumber; + +/// @name JSON Extension Type Casts + +- (nullable NSURL *)asURL; + +- (nullable NSArray *)asStringArray; + +- (nullable NSDictionary *)asDictionary; + +- (NSInteger)asIntegerOrZero; + +- (NSInteger)asEnum:(NSDictionary *)mapping orDefault:(NSInteger)defaultValue; + +/// @name JSON Type Checks + +@property (nonatomic, assign, readonly) BOOL isString; + +@property (nonatomic, assign, readonly) BOOL isNumber; + +@property (nonatomic, assign, readonly) BOOL isArray; + +@property (nonatomic, assign, readonly) BOOL isObject; + +@property (nonatomic, assign, readonly) BOOL isTrue; + +@property (nonatomic, assign, readonly) BOOL isFalse; + +@property (nonatomic, assign, readonly) BOOL isNull; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCore/Public/BTLogger.h b/Pods/Braintree/BraintreeCore/Public/BTLogger.h new file mode 100644 index 0000000..2ca2568 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTLogger.h @@ -0,0 +1,42 @@ +#import + +/** + @brief Braintree SDK Logging Levels +*/ +typedef NS_ENUM(NSUInteger, BTLogLevel) { + + /// Suppress all log output + BTLogLevelNone = 0, + + /// Only log critical issues (e.g. irrecoverable errors) + BTLogLevelCritical = 1, + + /// Log errors (e.g. expected or recoverable errors) + BTLogLevelError = 2, + + /// Log warnings (e.g. use of pre-release features) + BTLogLevelWarning = 3, + + /// Log basic information (e.g. state changes, network activity) + BTLogLevelInfo = 4, + + /// Log debugging statements (anything and everything) + BTLogLevelDebug = 5 +}; + +/** + @brief Braintree leveled logger + */ +@interface BTLogger : NSObject + +/** + @brief The logger singleton used by the Braintree SDK +*/ ++ (instancetype)sharedLogger; + +/** + @brief The current log level, with default value BTLogLevelInfo +*/ +@property (nonatomic, assign) BTLogLevel level; + +@end diff --git a/Pods/Braintree/BraintreeCore/Public/BTPaymentMethodNonce.h b/Pods/Braintree/BraintreeCore/Public/BTPaymentMethodNonce.h new file mode 100644 index 0000000..38d8b3f --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTPaymentMethodNonce.h @@ -0,0 +1,71 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + @class BTPaymentMethodNonce + @brief BTPaymentMethodNonce is for generic tokenized payment information. + + @discussion For example, if a customer's vaulted payment methods contains a type that's not recognized or supported by the + Braintree SDK or the client-side integration (e.g. the vault contains a PayPal account but the client-side + integration does not include the PayPal component), this type can act as a fallback. + + The payment method nonce is a public token that acts as a placeholder for sensitive payments data that + has been uploaded to Braintree for subsequent processing. The nonce is safe to access on the client and can be + used on your server to reference the data in Braintree operations, such as Transaction.sale. +*/ +@interface BTPaymentMethodNonce : NSObject + +/** + @brief Initialize a new Payment Method Nonce. + + @param nonce A transactable payment method nonce. + @param description A human-readable description. + @param type A string identifying the type of the payment method. + @return A Payment Method Nonce, or `nil` if nonce is nil. +*/ +- (nullable instancetype)initWithNonce:(NSString *)nonce localizedDescription:(nullable NSString *)description type:(NSString *)type; + +/** + @brief Initialize a new Payment Method Nonce. + + @param nonce A transactable payment method nonce. + @param description A human-readable description. + @return A Payment Method Nonce, or `nil` if nonce is nil. +*/ +- (nullable instancetype)initWithNonce:(NSString *)nonce localizedDescription:(nullable NSString *)description; + +/** + @brief Initialize a new Payment Method Nonce. + + @param nonce A transactable payment method nonce. + @param description A human-readable description. + @param type A string identifying the type of the payment method. + @param isDefault A boolean indicating whether this is a default payment method. + @return A Payment Method Nonce, or `nil` if nonce is nil. +*/ +- (nullable instancetype)initWithNonce:(NSString *)nonce localizedDescription:(NSString *)description type:(nonnull NSString *)type isDefault:(BOOL)isDefault; + +/** + @brief The one-time use payment method nonce +*/ +@property (nonatomic, readonly, copy) NSString *nonce; + +/** + @brief A localized description of the payment info +*/ +@property (nonatomic, readonly, copy) NSString *localizedDescription; + +/** + @brief The type of the tokenized data, e.g. PayPal, Venmo, MasterCard, Visa, Amex +*/ +@property (nonatomic, readonly, copy) NSString *type; + +/** + @brief True if this nonce is the customer's default payment method, otherwise false. +*/ +@property (nonatomic, readonly, assign) BOOL isDefault; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCore/Public/BTPaymentMethodNonceParser.h b/Pods/Braintree/BraintreeCore/Public/BTPaymentMethodNonceParser.h new file mode 100644 index 0000000..bd34d9d --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTPaymentMethodNonceParser.h @@ -0,0 +1,59 @@ +#import "BTJSON.h" +#import "BTPaymentMethodNonce.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + @class BTPaymentMethodNonceParser + @brief A JSON parser that parses `BTJSON` into concrete `BTPaymentMethodNonce` objects. It supports registration of parsers at runtime. + + @discussion `BTPaymentMethodNonceParser` provides access to JSON parsing for different payment options + without introducing compile-time dependencies on payment option frameworks and their symbols. +*/ +@interface BTPaymentMethodNonceParser : NSObject + +/** + @brief The singleton instance +*/ ++ (instancetype)sharedParser; + +/** + @brief An array of the tokenization types currently registered +*/ +@property (nonatomic, readonly, strong) NSArray *allTypes; + +/** + @brief Indicates whether a tokenization type is currently registered + + @param type The tokenization type string +*/ +- (BOOL)isTypeAvailable:(NSString *)type; + +/** + @brief Registers a parsing block for a tokenization type. + + @param type The tokenization type string + @param jsonParsingBlock The block to execute when `parseJSON:type:` is called for the tokenization type. + This block should return a `BTPaymentMethodNonce` object, or `nil` if the JSON cannot be parsed. +*/ +- (void)registerType:(NSString *)type withParsingBlock:(BTPaymentMethodNonce * _Nullable (^)(BTJSON *json))jsonParsingBlock; + +/** + @brief Parses tokenized payment information that has been serialized to JSON, and returns a `BTPaymentMethodNonce` object. + + @discussion The `BTPaymentMethodNonce` object is created by the JSON parsing block that has been registered for the tokenization + type. + + If the `type` has not been registered, this method will attempt to read the nonce from the JSON and return + a basic object; if it fails, it will return `nil`. + + @param json The tokenized payment info, serialized to JSON + @param type The registered type of the parsing block to use + @return A `BTPaymentMethodNonce` object, or `nil` if the tokenized payment info JSON does not contain a nonce +*/ +- (nullable BTPaymentMethodNonce *)parseJSON:(BTJSON *)json withParsingBlockForType:(NSString *)type; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCore/Public/BTPostalAddress.h b/Pods/Braintree/BraintreeCore/Public/BTPostalAddress.h new file mode 100644 index 0000000..ebbbc79 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTPostalAddress.h @@ -0,0 +1,44 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface BTPostalAddress : NSObject + +/** + @brief Optional. Recipient name for shipping address. +*/ +@property (nonatomic, nullable, copy) NSString *recipientName; + +/** + @brief Line 1 of the Address (eg. number, street, etc). +*/ +@property (nonatomic, copy) NSString *streetAddress; + +/** + @brief Optional line 2 of the Address (eg. suite, apt #, etc.). +*/ +@property (nonatomic, nullable, copy) NSString *extendedAddress; + +/** + @brief City name +*/ +@property (nonatomic, copy) NSString *locality; + +/** + @brief 2 letter country code. +*/ +@property (nonatomic, copy) NSString *countryCodeAlpha2; + +/** + @brief Zip code or equivalent is usually required for countries that have them. For list of countries that do not have postal codes please refer to http://en.wikipedia.org/wiki/Postal_code. +*/ +@property (nonatomic, nullable, copy) NSString *postalCode; + +/** + @brief 2 letter code for US states, and the equivalent for other countries. +*/ +@property (nonatomic, nullable, copy) NSString *region; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCore/Public/BTTokenizationService.h b/Pods/Braintree/BraintreeCore/Public/BTTokenizationService.h new file mode 100644 index 0000000..1af2155 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTTokenizationService.h @@ -0,0 +1,76 @@ +#import +#import "BTAPIClient.h" +#import "BTPaymentMethodNonce.h" + +NS_ASSUME_NONNULL_BEGIN + +extern NSString * const BTTokenizationServiceErrorDomain; +extern NSString * const BTTokenizationServiceAppSwitchDelegateOption; +extern NSString * const BTTokenizationServiceViewPresentingDelegateOption; +extern NSString * const BTTokenizationServicePayPalScopesOption; +extern NSString * const BTTokenizationServiceAmountOption; +extern NSString * const BTTokenizationServiceNonceOption; + +typedef NS_ENUM(NSInteger, BTTokenizationServiceError) { + BTTokenizationServiceErrorUnknown = 0, + BTTokenizationServiceErrorTypeNotRegistered, +}; + +/** + @class BTTokenizationService + @brief A tokenization service that supports registration of tokenizers at runtime. + + @discussion `BTTokenizationService` provides access to tokenization services from payment options + (e.g. `BTPayPalDriver`) without introducing compile-time dependencies on the frameworks. +*/ +@interface BTTokenizationService : NSObject + +/** + @brief The singleton instance of the tokenization service +*/ ++ (instancetype)sharedService; + +/** + @brief Registers a block to execute for a given type when `tokenizeType:withAPIClient:completion:` or`tokenizeType:options:withAPIClient:completion:` are invoked. + + @param type A type string to identify the tokenization block. Providing a type that has already + been registered will overwrite the previously registered tokenization block. + @param tokenizationBlock The tokenization block to register for a type. +*/ +- (void)registerType:(NSString *)type withTokenizationBlock:(void(^)(BTAPIClient *apiClient, NSDictionary * _Nullable options, void(^)(BTPaymentMethodNonce * _Nullable paymentMethodNonce, NSError * _Nullable error)))tokenizationBlock; + +/** + @brief Indicates whether a type has been registered with a valid tokenization block. +*/ +- (BOOL)isTypeAvailable:(NSString *)type; + +/** + @brief Perform tokenization for the given type. This will execute the tokenization block that has been registered for the type. + + @param type The tokenization type to perform + @param apiClient The API client to use when performing tokenization. + @param completion The completion block to invoke when tokenization has completed. +*/ +- (void)tokenizeType:(NSString *)type + withAPIClient:(BTAPIClient *)apiClient + completion:(void(^)(BTPaymentMethodNonce * _Nullable paymentMethodNonce, NSError * _Nullable error))completion; + +/** + @brief Perform tokenization for the given type. This will execute the tokenization block that has been registered for the type. + + @param type The tokenization type to perform + @param options A dictionary of data to use when invoking the tokenization block. This can be + used to pass data into a tokenization client/driver, e.g. credit card raw details. + @param apiClient The API client to use when performing tokenization. + @param completion The completion block to invoke when tokenization has completed. +*/ +- (void)tokenizeType:(NSString *)type + options:(nullable NSDictionary *)options + withAPIClient:(BTAPIClient *)apiClient + completion:(void(^)(BTPaymentMethodNonce * _Nullable paymentMethodNonce, NSError * _Nullable error))completion; + +@property (nonatomic, readonly, strong) NSArray *allTypes; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCore/Public/BTViewControllerPresentingDelegate.h b/Pods/Braintree/BraintreeCore/Public/BTViewControllerPresentingDelegate.h new file mode 100644 index 0000000..8a7b370 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BTViewControllerPresentingDelegate.h @@ -0,0 +1,34 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + @brief Protocol for receiving payment lifecycle messages from a payment driver that requires presentation of a view controller to authorize a payment. +*/ +@protocol BTViewControllerPresentingDelegate + +/** + @brief The payment driver requires presentation of a view controller in order to proceed. + + @discussion Your implementation should present the viewController modally, e.g. via + `presentViewController:animated:completion:` + + @param driver The payment driver + @param viewController The view controller to present +*/ +- (void)paymentDriver:(id)driver requestsPresentationOfViewController:(UIViewController *)viewController; + +/** + @brief The payment driver requires dismissal of a view controller. + + @discussion Your implementation should dismiss the viewController, e.g. via + `dismissViewControllerAnimated:completion:` + + @param driver The payment driver + @param viewController The view controller to be dismissed +*/ +- (void)paymentDriver:(id)driver requestsDismissalOfViewController:(UIViewController *)viewController; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeCore/Public/BraintreeCore.h b/Pods/Braintree/BraintreeCore/Public/BraintreeCore.h new file mode 100644 index 0000000..b02ed28 --- /dev/null +++ b/Pods/Braintree/BraintreeCore/Public/BraintreeCore.h @@ -0,0 +1,29 @@ +#import + +//! Project version number for BraintreeCore. +FOUNDATION_EXPORT double BraintreeCoreVersionNumber; + +//! Project version string for BraintreeCore. +FOUNDATION_EXPORT const unsigned char BraintreeCoreVersionString[]; + +#import "BTAPIClient.h" +#import "BTAppSwitch.h" +#import "BTBinData.h" +#import "BTClientMetadata.h" +#import "BTClientToken.h" +#import "BTConfiguration.h" +#import "BTEnums.h" +#import "BTErrors.h" +#import "BTHTTPErrors.h" +#import "BTJSON.h" +#import "BTLogger.h" +#import "BTPostalAddress.h" +#import "BTPaymentMethodNonce.h" +#import "BTPaymentMethodNonceParser.h" +#import "BTTokenizationService.h" +#import "BTPaymentMethodNonce.h" +#import "BTViewControllerPresentingDelegate.h" + +#ifndef __BT_AVAILABLE +#define __BT_AVAILABLE(class) NSClassFromString(class) != nil +#endif /*__BT_AVAILABLE*/ diff --git a/Pods/Braintree/BraintreePayPal/BTConfiguration+PayPal.m b/Pods/Braintree/BraintreePayPal/BTConfiguration+PayPal.m new file mode 100644 index 0000000..d332c9b --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/BTConfiguration+PayPal.m @@ -0,0 +1,13 @@ +#import "BTConfiguration+PayPal.h" + +@implementation BTConfiguration (PayPal) + +- (BOOL)isPayPalEnabled { + return [self.json[@"paypalEnabled"] isTrue]; +} + +- (BOOL)isBillingAgreementsEnabled { + return [self.json[@"paypal"][@"billingAgreementsEnabled"] isTrue]; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/BTPayPalAccountNonce.m b/Pods/Braintree/BraintreePayPal/BTPayPalAccountNonce.m new file mode 100644 index 0000000..2a350dd --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/BTPayPalAccountNonce.m @@ -0,0 +1,44 @@ +#import "BTPayPalAccountNonce_Internal.h" + +@interface BTPayPalAccountNonce () +@property (nonatomic, readwrite, copy) NSString *email; +@property (nonatomic, readwrite, copy) NSString *firstName; +@property (nonatomic, readwrite, copy) NSString *lastName; +@property (nonatomic, readwrite, copy) NSString *phone; +@property (nonatomic, readwrite, strong) BTPostalAddress *billingAddress; +@property (nonatomic, readwrite, strong) BTPostalAddress *shippingAddress; +@property (nonatomic, readwrite, copy) NSString *clientMetadataId; +@property (nonatomic, readwrite, copy) NSString *payerId; +@property (nonatomic, readwrite, strong) BTPayPalCreditFinancing *creditFinancing; +@end + +@implementation BTPayPalAccountNonce + +- (instancetype)initWithNonce:(NSString *)nonce + description:(NSString *)description + email:(NSString *)email + firstName:(NSString *)firstName + lastName:(NSString *)lastName + phone:(NSString *)phone + billingAddress:(BTPostalAddress *)billingAddress + shippingAddress:(BTPostalAddress *)shippingAddress + clientMetadataId:(NSString *)clientMetadataId + payerId:(NSString *)payerId + isDefault:(BOOL)isDefault + creditFinancing:(BTPayPalCreditFinancing *)creditFinancing +{ + if (self = [super initWithNonce:nonce localizedDescription:description type:@"PayPal" isDefault:isDefault]) { + _email = email; + _firstName = firstName; + _lastName = lastName; + _phone = phone; + _billingAddress = [billingAddress copy]; + _shippingAddress = [shippingAddress copy]; + _clientMetadataId = clientMetadataId; + _payerId = payerId; + _creditFinancing = creditFinancing; + } + return self; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/BTPayPalAccountNonce_Internal.h b/Pods/Braintree/BraintreePayPal/BTPayPalAccountNonce_Internal.h new file mode 100644 index 0000000..50ad737 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/BTPayPalAccountNonce_Internal.h @@ -0,0 +1,40 @@ +#import "BTPayPalAccountNonce.h" +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif + +@interface BTPayPalCreditFinancingAmount () + +- (instancetype)initWithCurrency:(NSString *)currency value:(NSString *)value; + +@end + +@interface BTPayPalCreditFinancing () + +- (instancetype)initWithCardAmountImmutable:(BOOL)cardAmountImmutable + monthlyPayment:(BTPayPalCreditFinancingAmount *)monthlyPayment + payerAcceptance:(BOOL)payerAcceptance + term:(NSInteger)term + totalCost:(BTPayPalCreditFinancingAmount *)totalCost + totalInterest:(BTPayPalCreditFinancingAmount *)totalInterest; + +@end + +@interface BTPayPalAccountNonce () + +- (instancetype)initWithNonce:(NSString *)nonce + description:(NSString *)description + email:(NSString *)email + firstName:(NSString *)firstName + lastName:(NSString *)lastName + phone:(NSString *)phone + billingAddress:(BTPostalAddress *)billingAddress + shippingAddress:(BTPostalAddress *)shippingAddress + clientMetadataId:(NSString *)clientMetadataId + payerId:(NSString *)payerId + isDefault:(BOOL)isDefault + creditFinancing:(BTPayPalCreditFinancing *)creditFinancing; + +@end diff --git a/Pods/Braintree/BraintreePayPal/BTPayPalCreditFinancing.m b/Pods/Braintree/BraintreePayPal/BTPayPalCreditFinancing.m new file mode 100644 index 0000000..8047d48 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/BTPayPalCreditFinancing.m @@ -0,0 +1,34 @@ +#import "BTPayPalAccountNonce_Internal.h" + +@interface BTPayPalCreditFinancing () + +@property (nonatomic, readwrite) BOOL cardAmountImmutable; +@property (nonatomic, readwrite, strong) BTPayPalCreditFinancingAmount *monthlyPayment; +@property (nonatomic, readwrite) BOOL payerAcceptance; +@property (nonatomic, readwrite) NSInteger term; +@property (nonatomic, readwrite, strong) BTPayPalCreditFinancingAmount *totalCost; +@property (nonatomic, readwrite, strong) BTPayPalCreditFinancingAmount *totalInterest; + +@end + +@implementation BTPayPalCreditFinancing + +- (instancetype)initWithCardAmountImmutable:(BOOL)cardAmountImmutable + monthlyPayment:(BTPayPalCreditFinancingAmount *)monthlyPayment + payerAcceptance:(BOOL)payerAcceptance + term:(NSInteger)term + totalCost:(BTPayPalCreditFinancingAmount *)totalCost + totalInterest:(BTPayPalCreditFinancingAmount *)totalInterest +{ + if (self = [super init]) { + _cardAmountImmutable = cardAmountImmutable; + _monthlyPayment = monthlyPayment; + _payerAcceptance = payerAcceptance; + _term = term; + _totalCost = totalCost; + _totalInterest = totalInterest; + } + return self; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/BTPayPalCreditFinancingAmount.m b/Pods/Braintree/BraintreePayPal/BTPayPalCreditFinancingAmount.m new file mode 100644 index 0000000..74d39eb --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/BTPayPalCreditFinancingAmount.m @@ -0,0 +1,20 @@ +#import "BTPayPalAccountNonce_Internal.h" + +@interface BTPayPalCreditFinancingAmount () + +@property (nonatomic, readwrite, copy) NSString *currency; +@property (nonatomic, readwrite, copy) NSString *value; + +@end + +@implementation BTPayPalCreditFinancingAmount + +- (instancetype)initWithCurrency:(NSString *)currency value:(NSString *)value { + if (self = [super init]) { + _currency = currency; + _value = value; + } + return self; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/BTPayPalDriver.m b/Pods/Braintree/BraintreePayPal/BTPayPalDriver.m new file mode 100644 index 0000000..3d00e8d --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/BTPayPalDriver.m @@ -0,0 +1,1093 @@ +#import "BTPayPalDriver_Internal.h" + +#import "PPOTRequest.h" +#import "PPOTCore.h" + +#if __has_include("BraintreeCore.h") +#import "BTAPIClient_Internal.h" +#import "BTPayPalAccountNonce_Internal.h" +#import "BTPostalAddress.h" +#import "BTLogger_Internal.h" +#else +#import +#import +#import +#import +#import +#endif +#import +#import "BTConfiguration+PayPal.h" + +NSString *const BTPayPalDriverErrorDomain = @"com.braintreepayments.BTPayPalDriverErrorDomain"; +NSString *const BTSFAuthenticationSessionDisabled = @"sfAuthenticationSessionDisabled"; + +static void (^appSwitchReturnBlock)(NSURL *url); + +typedef NS_ENUM(NSUInteger, BTPayPalPaymentType) { + BTPayPalPaymentTypeUnknown = 0, + BTPayPalPaymentTypeFuturePayments, + BTPayPalPaymentTypeCheckout, + BTPayPalPaymentTypeBillingAgreement, +}; + +@interface BTPayPalDriver () +@property (nonatomic, assign) BOOL becameActiveAfterSFAuthenticationSessionModal; +@end + +@implementation BTPayPalDriver + ++ (void)load { + if (self == [BTPayPalDriver class]) { + PayPalClass = [PPOTCore class]; + + [[BTAppSwitch sharedInstance] registerAppSwitchHandler:self]; + + [[BTTokenizationService sharedService] registerType:@"PayPal" withTokenizationBlock:^(BTAPIClient *apiClient, __unused NSDictionary *options, void (^completionBlock)(BTPaymentMethodNonce *paymentMethodNonce, NSError *error)) { + BTPayPalDriver *driver = [[BTPayPalDriver alloc] initWithAPIClient:apiClient]; + driver.viewControllerPresentingDelegate = options[BTTokenizationServiceViewPresentingDelegateOption]; + driver.appSwitchDelegate = options[BTTokenizationServiceAppSwitchDelegateOption]; + [driver authorizeAccountWithAdditionalScopes:options[BTTokenizationServicePayPalScopesOption] completion:completionBlock]; + }]; + + [[BTPaymentMethodNonceParser sharedParser] registerType:@"PayPalAccount" withParsingBlock:^BTPaymentMethodNonce * _Nullable(BTJSON * _Nonnull payPalAccount) { + return [self payPalAccountFromJSON:payPalAccount]; + }]; + } +} + +- (instancetype)initWithAPIClient:(BTAPIClient *)apiClient { + if (self = [super init]) { + BTClientMetadataSourceType source = [self isiOSAppAvailableForAppSwitch] ? BTClientMetadataSourcePayPalApp : BTClientMetadataSourcePayPalBrowser; + _apiClient = [apiClient copyWithSource:source integration:apiClient.metadata.integration]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil]; + } + return self; +} + +- (instancetype)init { + return nil; +} + +- (void)applicationDidBecomeActive:(__unused NSNotification *)notification +{ + if (self.isSFAuthenticationSessionStarted) { + self.becameActiveAfterSFAuthenticationSessionModal = YES; + } +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +#pragma mark - Authorization (Future Payments) + +- (void)authorizeAccountWithCompletion:(void (^)(BTPayPalAccountNonce *paymentMethod, NSError *error))completionBlock { + [self authorizeAccountWithAdditionalScopes:[NSSet set] completion:completionBlock]; +} + +- (void)authorizeAccountWithAdditionalScopes:(NSSet *)additionalScopes completion:(void (^)(BTPayPalAccountNonce *, NSError *))completionBlock { + [self authorizeAccountWithAdditionalScopes:additionalScopes forceFuturePaymentFlow:false completion:completionBlock]; +} + +- (void)authorizeAccountWithAdditionalScopes:(NSSet *)additionalScopes forceFuturePaymentFlow:(BOOL)forceFuturePaymentFlow completion:(void (^)(BTPayPalAccountNonce *, NSError *))completionBlock { + if (!self.apiClient) { + NSError *error = [NSError errorWithDomain:BTPayPalDriverErrorDomain + code:BTPayPalDriverErrorTypeIntegration + userInfo:@{NSLocalizedDescriptionKey: @"BTPayPalDriver failed because BTAPIClient is nil."}]; + completionBlock(nil, error); + return; + } + + [self setAuthorizationAppSwitchReturnBlock:completionBlock]; + + [self.apiClient fetchOrReturnRemoteConfiguration:^(BTConfiguration *configuration, NSError *error) { + if (error) { + if (completionBlock) completionBlock(nil, error); + return; + } + + self.disableSFAuthenticationSession = [configuration.json[BTSFAuthenticationSessionDisabled] isTrue] || self.disableSFAuthenticationSession; + + if (configuration.isBillingAgreementsEnabled && !forceFuturePaymentFlow) { + // Switch to Billing Agreements flow + BTPayPalRequest *payPalRequest = [[BTPayPalRequest alloc] init]; // Drop-in only supports Vault flow, which does not use currency code or amount + [self requestBillingAgreement:payPalRequest completion:completionBlock]; + return; + } + + if (![self verifyAppSwitchWithRemoteConfiguration:configuration.json error:&error]) { + if (completionBlock) completionBlock(nil, error); + return; + } + + PPOTAuthorizationRequest *request = + [self.requestFactory requestWithScopeValues:[self.defaultOAuth2Scopes setByAddingObjectsFromSet:(additionalScopes ? additionalScopes : [NSSet set])] + privacyURL:[configuration.json[@"paypal"][@"privacyUrl"] asURL] + agreementURL:[configuration.json[@"paypal"][@"userAgreementUrl"] asURL] + clientID:[self paypalClientIdWithRemoteConfiguration:configuration.json] + environment:[self payPalEnvironmentForRemoteConfiguration:configuration.json] + callbackURLScheme:self.returnURLScheme]; + + if (self.apiClient.clientToken) { + request.additionalPayloadAttributes = @{ @"client_token": self.apiClient.clientToken.originalValue }; + } else if (self.apiClient.tokenizationKey) { + request.additionalPayloadAttributes = @{ @"client_key": self.apiClient.tokenizationKey }; + } + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 9.0, *)) { + // will use in-app browser + } else { + [self informDelegateWillPerformAppSwitch]; + } +#else + if (![SFSafariViewController class]) { + [self informDelegateWillPerformAppSwitch]; + } +#endif + + [request performWithAdapterBlock:^(BOOL success, NSURL *url, PPOTRequestTarget target, NSString *clientMetadataId, NSError *error) { + self.clientMetadataId = clientMetadataId; + + [self sendAnalyticsEventForInitiatingOneTouchForPaymentType:BTPayPalPaymentTypeFuturePayments withSuccess:success target:target]; + + [self handlePayPalRequestWithSuccess:success error:error requestURL:url target:target paymentType:BTPayPalPaymentTypeFuturePayments completion:completionBlock]; + }]; + }]; +} + +- (void)setAuthorizationAppSwitchReturnBlock:(void (^)(BTPayPalAccountNonce *account, NSError *error))completionBlock { + [self setAppSwitchReturnBlock:completionBlock forPaymentType:BTPayPalPaymentTypeFuturePayments]; +} + +#pragma mark - Billing Agreement + +- (void)requestBillingAgreement:(BTPayPalRequest *)request completion:(void (^)(BTPayPalAccountNonce *tokenizedCheckout, NSError *error))completionBlock { + [self requestExpressCheckout:request isBillingAgreement:YES handler:nil completion:completionBlock]; +} + +- (void)requestBillingAgreement:(BTPayPalRequest *)request handler:(id)handler completion:(void (^)(BTPayPalAccountNonce * _Nullable, NSError * _Nullable))completionBlock { + [self requestExpressCheckout:request isBillingAgreement:YES handler:handler completion:completionBlock]; +} + +- (void)setBillingAgreementAppSwitchReturnBlock:(void (^)(BTPayPalAccountNonce *tokenizedAccount, NSError *error))completionBlock { + [self setAppSwitchReturnBlock:completionBlock forPaymentType:BTPayPalPaymentTypeBillingAgreement]; +} + +#pragma mark - Express Checkout (One-Time Payments) + +- (void)requestOneTimePayment:(BTPayPalRequest *)request completion:(void (^)(BTPayPalAccountNonce *tokenizedCheckout, NSError *error))completionBlock { + [self requestExpressCheckout:request isBillingAgreement:NO handler:nil completion:completionBlock]; +} + +- (void)requestOneTimePayment:(BTPayPalRequest *)request handler:(id)handler completion:(void (^)(BTPayPalAccountNonce *tokenizedCheckout, NSError *error))completionBlock { + [self requestExpressCheckout:request isBillingAgreement:NO handler:handler completion:completionBlock]; +} + +- (void)setOneTimePaymentAppSwitchReturnBlock:(void (^)(BTPayPalAccountNonce *tokenizedAccount, NSError *error))completionBlock { + [self setAppSwitchReturnBlock:completionBlock forPaymentType:BTPayPalPaymentTypeCheckout]; +} + +#pragma mark - Helpers + +/// A "Hermes checkout" is used by both Billing Agreements and Express Checkout +- (void)requestExpressCheckout:(BTPayPalRequest *)request + isBillingAgreement:(BOOL)isBillingAgreement + handler:(id)handler + completion:(void (^)(BTPayPalAccountNonce *tokenizedCheckout, NSError *error))completionBlock { + if (!self.apiClient) { + NSError *error = [NSError errorWithDomain:BTPayPalDriverErrorDomain + code:BTPayPalDriverErrorTypeIntegration + userInfo:@{NSLocalizedDescriptionKey: @"BTPayPalDriver failed because BTAPIClient is nil."}]; + completionBlock(nil, error); + return; + } + + if (!request || (!isBillingAgreement && !request.amount)) { + completionBlock(nil, [NSError errorWithDomain:BTPayPalDriverErrorDomain code:BTPayPalDriverErrorTypeInvalidRequest userInfo:nil]); + return; + } + + [self.apiClient fetchOrReturnRemoteConfiguration:^(BTConfiguration *configuration, NSError *error) { + if (error) { + if (completionBlock) completionBlock(nil, error); + return; + } + + if (![self verifyAppSwitchWithRemoteConfiguration:configuration.json error:&error]) { + if (completionBlock) completionBlock(nil, error); + return; + } + + self.disableSFAuthenticationSession = [configuration.json[BTSFAuthenticationSessionDisabled] isTrue] || self.disableSFAuthenticationSession; + NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; + NSMutableDictionary *experienceProfile = [NSMutableDictionary dictionary]; + + if (!isBillingAgreement) { + parameters[@"intent"] = [self.class intentTypeToString:request.intent]; + if (request.amount != nil) { + parameters[@"amount"] = request.amount; + } + } else { + if (request.billingAgreementDescription.length > 0) { + parameters[@"description"] = request.billingAgreementDescription; + } + } + + parameters[@"offer_paypal_credit"] = @(request.offerCredit); + + experienceProfile[@"no_shipping"] = @(!request.isShippingAddressRequired); + + experienceProfile[@"brand_name"] = request.displayName ?: [configuration.json[@"paypal"][@"displayName"] asString]; + + NSString *landingPageTypeValue = [self.class landingPageTypeToString:request.landingPageType]; + if (landingPageTypeValue != nil) { + experienceProfile[@"landing_page_type"] = landingPageTypeValue; + } + + if (request.localeCode != nil) { + experienceProfile[@"locale_code"] = request.localeCode; + } + + // Currency code should only be used for Hermes Checkout (one-time payment). + // For BA, currency should not be used. + NSString *currencyCode = request.currencyCode ?: [configuration.json[@"paypal"][@"currencyIsoCode"] asString]; + if (!isBillingAgreement && currencyCode) { + parameters[@"currency_iso_code"] = currencyCode; + } + + if (request.shippingAddressOverride != nil) { + experienceProfile[@"address_override"] = @YES; + BTPostalAddress *shippingAddress = request.shippingAddressOverride; + parameters[@"line1"] = shippingAddress.streetAddress; + parameters[@"line2"] = shippingAddress.extendedAddress; + parameters[@"city"] = shippingAddress.locality; + parameters[@"state"] = shippingAddress.region; + parameters[@"postal_code"] = shippingAddress.postalCode; + parameters[@"country_code"] = shippingAddress.countryCodeAlpha2; + parameters[@"recipient_name"] = shippingAddress.recipientName; + } else { + experienceProfile[@"address_override"] = @NO; + } + + NSString *returnURI; + NSString *cancelURI; + + [[self.class payPalClass] redirectURLsForCallbackURLScheme:self.returnURLScheme + withReturnURL:&returnURI + withCancelURL:&cancelURI]; + if (!returnURI || !cancelURI) { + completionBlock(nil, [NSError errorWithDomain:BTPayPalDriverErrorDomain + code:BTPayPalDriverErrorTypeIntegrationReturnURLScheme + userInfo:@{NSLocalizedFailureReasonErrorKey: @"Application may not support One Touch callback URL scheme.", + NSLocalizedRecoverySuggestionErrorKey: @"Check the return URL scheme" }]); + return; + } + + if (returnURI) { + parameters[@"return_url"] = returnURI; + } + if (cancelURI) { + parameters[@"cancel_url"] = cancelURI; + } + + parameters[@"experience_profile"] = experienceProfile; + + self.payPalRequest = request; + + NSString *url = isBillingAgreement ? @"setup_billing_agreement" : @"create_payment_resource"; + + [self.apiClient POST:[NSString stringWithFormat:@"v1/paypal_hermes/%@",url] + parameters:parameters + completion:^(BTJSON *body, __unused NSHTTPURLResponse *response, NSError *error) { + + if (error) { + NSString *errorDetailsIssue = ((BTJSON *)error.userInfo[BTHTTPJSONResponseBodyKey][@"paymentResource"][@"errorDetails"][0][@"issue"]).asString; + if (error.userInfo[NSLocalizedDescriptionKey] == nil && errorDetailsIssue != nil) { + NSMutableDictionary *dictionary = [error.userInfo mutableCopy]; + dictionary[NSLocalizedDescriptionKey] = errorDetailsIssue; + error = [NSError errorWithDomain:error.domain code:error.code userInfo:dictionary]; + } + + if (completionBlock) completionBlock(nil, error); + return; + } + + if (isBillingAgreement) { + [self setBillingAgreementAppSwitchReturnBlock:completionBlock]; + } else { + [self setOneTimePaymentAppSwitchReturnBlock:completionBlock]; + } + + NSString *payPalClientID = [configuration.json[@"paypal"][@"clientId"] asString]; + + if (!payPalClientID && [self payPalEnvironmentForRemoteConfiguration:configuration.json] == PayPalEnvironmentMock) { + payPalClientID = @"FAKE-PAYPAL-CLIENT-ID"; + } + + NSURL *approvalUrl = [body[@"paymentResource"][@"redirectUrl"] asURL]; + if (approvalUrl == nil) { + approvalUrl = [body[@"agreementSetup"][@"approvalUrl"] asURL]; + } + + approvalUrl = [self decorateApprovalURL:approvalUrl forRequest:request]; + + PPOTCheckoutRequest *request = nil; + if (isBillingAgreement) { + request = [self.requestFactory billingAgreementRequestWithApprovalURL:approvalUrl + clientID:payPalClientID + environment:[self payPalEnvironmentForRemoteConfiguration:configuration.json] + callbackURLScheme:self.returnURLScheme]; + } else { + request = [self.requestFactory checkoutRequestWithApprovalURL:approvalUrl + clientID:payPalClientID + environment:[self payPalEnvironmentForRemoteConfiguration:configuration.json] + callbackURLScheme:self.returnURLScheme]; + } + + // Call custom handler and return before beginning the default approval process + if (handler != nil) { + [handler handleApproval:request paypalApprovalDelegate:self]; + return; + } + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 9.0, *)) { + // will use in-app browser + } else { + [self informDelegateWillPerformAppSwitch]; + } +#else + if (![SFSafariViewController class]) { + [self informDelegateWillPerformAppSwitch]; + } +#endif + + [request performWithAdapterBlock:^(BOOL success, NSURL *url, PPOTRequestTarget target, NSString *clientMetadataId, NSError *error) { + self.clientMetadataId = clientMetadataId; + + if (isBillingAgreement) { + [self sendAnalyticsEventForInitiatingOneTouchForPaymentType:BTPayPalPaymentTypeBillingAgreement withSuccess:success target:target]; + } else { + [self sendAnalyticsEventForInitiatingOneTouchForPaymentType:BTPayPalPaymentTypeCheckout withSuccess:success target:target]; + } + + [self handlePayPalRequestWithSuccess:success + error:error + requestURL:url + target:target + paymentType:isBillingAgreement ? BTPayPalPaymentTypeBillingAgreement : BTPayPalPaymentTypeCheckout + completion:completionBlock]; + }]; + }]; + }]; +} + +- (void)setAppSwitchReturnBlock:(void (^)(BTPayPalAccountNonce *tokenizedAccount, NSError *error))completionBlock + forPaymentType:(BTPayPalPaymentType)paymentType { + appSwitchReturnBlock = ^(NSURL *url) { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 11.0, *)) { + if (self.safariAuthenticationSession) { + // do nothing + } else if (self.safariViewController) { + [self informDelegatePresentingViewControllerNeedsDismissal]; + } else { + [self informDelegateWillProcessAppSwitchReturn]; + } + } else +#endif + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 9.0, *)) { +#else + if (self.safariViewController) { +#endif + [self informDelegatePresentingViewControllerNeedsDismissal]; + } else { + [self informDelegateWillProcessAppSwitchReturn]; + } + + // Before parsing the return URL, check whether the user cancelled by breaking + // out of the PayPal app switch flow (e.g. "Done" button in SFSafariViewController) + if ([url.absoluteString isEqualToString:SFSafariViewControllerFinishedURL]) { + if (completionBlock) completionBlock(nil, nil); + appSwitchReturnBlock = nil; + return; + } + + [[self.class payPalClass] parseResponseURL:url completionBlock:^(PPOTResult *result) { + + [self sendAnalyticsEventForHandlingOneTouchResult:result forPaymentType:paymentType]; + + switch (result.type) { + case PPOTResultTypeError: + if (completionBlock) completionBlock(nil, result.error); + break; + case PPOTResultTypeCancel: + if (result.error) { + [[BTLogger sharedLogger] error:@"PayPal error: %@", result.error]; + } + if (completionBlock) completionBlock(nil, nil); + break; + case PPOTResultTypeSuccess: { + + NSMutableDictionary *parameters = [NSMutableDictionary dictionary]; + parameters[@"paypal_account"] = [result.response mutableCopy]; + + if (paymentType == BTPayPalPaymentTypeCheckout) { + parameters[@"paypal_account"][@"options"] = @{ @"validate": @NO }; + if (self.payPalRequest) { + parameters[@"paypal_account"][@"intent"] = [self.class intentTypeToString:self.payPalRequest.intent]; + } + } + if (self.clientMetadataId) { + parameters[@"paypal_account"][@"correlation_id"] = self.clientMetadataId; + } + + BTClientMetadata *metadata = [self clientMetadata]; + parameters[@"_meta"] = @{ + @"source" : metadata.sourceString, + @"integration" : metadata.integrationString, + @"sessionId" : metadata.sessionId, + }; + + [self.apiClient POST:@"/v1/payment_methods/paypal_accounts" + parameters:parameters + completion:^(BTJSON *body, __unused NSHTTPURLResponse *response, NSError *error) + { + if (error) { + [self sendAnalyticsEventForTokenizationFailureForPaymentType:paymentType]; + if (completionBlock) completionBlock(nil, error); + return; + } + + [self sendAnalyticsEventForTokenizationSuccessForPaymentType:paymentType]; + + BTJSON *payPalAccount = body[@"paypalAccounts"][0]; + BTPayPalAccountNonce *tokenizedAccount = [self.class payPalAccountFromJSON:payPalAccount]; + + [self sendAnalyticsEventIfCreditFinancingInNonce:tokenizedAccount forPaymentType:paymentType]; + + if (completionBlock) completionBlock(tokenizedAccount, nil); + }]; + + break; + } + } + appSwitchReturnBlock = nil; + }]; + }; +} + +- (void)handlePayPalRequestWithSuccess:(BOOL)success + error:(NSError *)error + requestURL:(NSURL *)url + target:(PPOTRequestTarget)target + paymentType:(BTPayPalPaymentType)paymentType + completion:(void (^)(BTPayPalAccountNonce *, NSError *))completionBlock +{ + if (success) { + // Defensive programming in case PayPal One Touch returns a non-HTTP URL so that SFSafariViewController doesn't crash +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 9.0, *)) { +#else + if ([SFSafariViewController class]) { +#endif + if (![url.scheme.lowercaseString hasPrefix:@"http"]) { + NSError *urlError = [NSError errorWithDomain:BTPayPalDriverErrorDomain + code:BTPayPalDriverErrorTypeUnknown + userInfo:@{ NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Attempted to open an invalid URL in SFSafariViewController: %@://", url.scheme], + NSLocalizedRecoverySuggestionErrorKey: @"Try again or contact Braintree Support." }]; + if (completionBlock) completionBlock(nil, urlError); + + NSString *eventName = [NSString stringWithFormat:@"ios.%@.%@.error.safariviewcontrollerbadscheme.%@", [self.class eventStringForPaymentType:paymentType], [self.class eventStringForRequestTarget:target], url.scheme]; + [self.apiClient sendAnalyticsEvent:eventName]; + + return; + } + } + [self performSwitchRequest:url]; + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 9.0, *)) { + // use in-app browser + } else { + [self informDelegateDidPerformAppSwitchToTarget:target]; + } +#else + if (![SFSafariViewController class]) { + [self informDelegateDidPerformAppSwitchToTarget:target]; + } +#endif + } else { + if (completionBlock) completionBlock(nil, error); + } +} + +- (void)performSwitchRequest:(NSURL *)appSwitchURL { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 11.0, *)) { + NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:appSwitchURL resolvingAgainstBaseURL:NO]; + + if (self.disableSFAuthenticationSession) { + // Append "force-one-touch" query param when One Touch functions correctly + NSString *queryForAuthSession = [urlComponents.query stringByAppendingString:@"&bt_int_type=1"]; + urlComponents.query = queryForAuthSession; + [self informDelegatePresentingViewControllerRequestPresent:urlComponents.URL]; + } else { + NSString *queryForAuthSession = [urlComponents.query stringByAppendingString:@"&bt_int_type=2"]; + urlComponents.query = queryForAuthSession; + self.safariAuthenticationSession = [[SFAuthenticationSession alloc] initWithURL:urlComponents.URL callbackURLScheme:self.returnURLScheme completionHandler:^(NSURL * _Nullable callbackURL, NSError * _Nullable error) { + if (error) { + if (error.domain == SFAuthenticationErrorDomain && error.code == SFAuthenticationErrorCanceledLogin) { + if (self.becameActiveAfterSFAuthenticationSessionModal) { + [self.apiClient sendAnalyticsEvent:@"ios.sfauthsession.cancel.web"]; + } else { + [self.apiClient sendAnalyticsEvent:@"ios.sfauthsession.cancel.modal"]; + } + } + + [self.class handleAppSwitchReturnURL:[NSURL URLWithString:SFSafariViewControllerFinishedURL]]; + return; + } + [BTAppSwitch handleOpenURL:callbackURL sourceApplication:@"com.apple.safariviewservice"]; + self.safariAuthenticationSession = nil; + }]; + if (self.safariAuthenticationSession != nil) { + self.becameActiveAfterSFAuthenticationSessionModal = NO; + self.isSFAuthenticationSessionStarted = [self.safariAuthenticationSession start]; + if (self.isSFAuthenticationSessionStarted) { + [self.apiClient sendAnalyticsEvent:@"ios.sfauthsession.start.succeeded"]; + } else { + [self.apiClient sendAnalyticsEvent:@"ios.sfauthsession.start.failed"]; + } + } + } + } else if (@available(iOS 9.0, *)) { + NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:appSwitchURL resolvingAgainstBaseURL:NO]; + NSString *queryForAuthSession = [urlComponents.query stringByAppendingString:@"&bt_int_type=1"]; + urlComponents.query = queryForAuthSession; + [self informDelegatePresentingViewControllerRequestPresent:urlComponents.URL]; +#else + if ([SFSafariViewController class]) { + NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:appSwitchURL resolvingAgainstBaseURL:NO]; + NSString *queryForAuthSession = [urlComponents.query stringByAppendingString:@"&bt_int_type=1"]; + urlComponents.query = queryForAuthSession; + [self informDelegatePresentingViewControllerRequestPresent:urlComponents.URL]; +#endif + } else { + UIApplication *application = [UIApplication sharedApplication]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 10.0, *)) { +#else + if ([application respondsToSelector:@selector(openURL:options:completionHandler:)]) { +#endif + [application openURL:appSwitchURL options:[NSDictionary dictionary] completionHandler:nil]; + } else { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [application openURL:appSwitchURL]; +#pragma clang diagnostic pop + } +#else +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [application openURL:appSwitchURL]; +#pragma clang diagnostic pop +#endif + } +} + +- (NSString *)payPalEnvironmentForRemoteConfiguration:(BTJSON *)configuration { + NSString *btPayPalEnvironmentName = [configuration[@"paypal"][@"environment"] asString]; + if ([btPayPalEnvironmentName isEqualToString:@"offline"]) { + return PayPalEnvironmentMock; + } else if ([btPayPalEnvironmentName isEqualToString:@"live"]) { + return PayPalEnvironmentProduction; + } else { + // Fall back to mock when configuration has an unsupported value for environment, e.g. "custom" + // Instead of returning btPayPalEnvironmentName + return PayPalEnvironmentMock; + } +} + +- (NSString *)paypalClientIdWithRemoteConfiguration:(BTJSON *)configuration { + if ([[configuration[@"paypal"][@"environment"] asString] isEqualToString:@"offline"] && ![configuration[@"paypal"][@"clientId"] isString]) { + return @"mock-paypal-client-id"; + } else { + return [configuration[@"paypal"][@"clientId"] asString]; + } +} + +- (BTClientMetadata *)clientMetadata { + BTMutableClientMetadata *metadata = [self.apiClient.metadata mutableCopy]; + + if ([self isiOSAppAvailableForAppSwitch]) { + metadata.source = BTClientMetadataSourcePayPalApp; + } else { + metadata.source = BTClientMetadataSourcePayPalBrowser; + } + + return [metadata copy]; +} + +- (NSSet *)defaultOAuth2Scopes { + return [NSSet setWithObjects:@"https://uri.paypal.com/services/payments/futurepayments", @"email", nil]; +} + ++ (BTPostalAddress *)accountAddressFromJSON:(BTJSON *)addressJSON { + if (!addressJSON.isObject) { + return nil; + } + + BTPostalAddress *address = [[BTPostalAddress alloc] init]; + address.recipientName = [addressJSON[@"recipientName"] asString]; // Likely to be nil + address.streetAddress = [addressJSON[@"street1"] asString]; + address.extendedAddress = [addressJSON[@"street2"] asString]; + address.locality = [addressJSON[@"city"] asString]; + address.region = [addressJSON[@"state"] asString]; + address.postalCode = [addressJSON[@"postalCode"] asString]; + address.countryCodeAlpha2 = [addressJSON[@"country"] asString]; + + return address; +} + ++ (BTPostalAddress *)shippingOrBillingAddressFromJSON:(BTJSON *)addressJSON { + if (!addressJSON.isObject) { + return nil; + } + + BTPostalAddress *address = [[BTPostalAddress alloc] init]; + address.recipientName = [addressJSON[@"recipientName"] asString]; // Likely to be nil + address.streetAddress = [addressJSON[@"line1"] asString]; + address.extendedAddress = [addressJSON[@"line2"] asString]; + address.locality = [addressJSON[@"city"] asString]; + address.region = [addressJSON[@"state"] asString]; + address.postalCode = [addressJSON[@"postalCode"] asString]; + address.countryCodeAlpha2 = [addressJSON[@"countryCode"] asString]; + + return address; +} + ++ (BTPayPalCreditFinancingAmount *)creditFinancingAmountFromJSON:(BTJSON *)amountJSON { + if (!amountJSON.isObject) { + return nil; + } + + NSString *currency = [amountJSON[@"currency"] asString]; + NSString *value = [amountJSON[@"value"] asString]; + + return [[BTPayPalCreditFinancingAmount alloc] initWithCurrency:currency value:value]; +} + ++ (BTPayPalCreditFinancing *)creditFinancingFromJSON:(BTJSON *)creditFinancingOfferedJSON { + if (!creditFinancingOfferedJSON.isObject) { + return nil; + } + + BOOL isCardAmountImmutable = [creditFinancingOfferedJSON[@"cardAmountImmutable"] isTrue]; + + BTPayPalCreditFinancingAmount *monthlyPayment = [self.class creditFinancingAmountFromJSON:creditFinancingOfferedJSON[@"monthlyPayment"]]; + + BOOL payerAcceptance = [creditFinancingOfferedJSON[@"payerAcceptance"] isTrue]; + NSInteger term = [creditFinancingOfferedJSON[@"term"] asIntegerOrZero]; + BTPayPalCreditFinancingAmount *totalCost = [self.class creditFinancingAmountFromJSON:creditFinancingOfferedJSON[@"totalCost"]]; + BTPayPalCreditFinancingAmount *totalInterest = [self.class creditFinancingAmountFromJSON:creditFinancingOfferedJSON[@"totalInterest"]]; + + return [[BTPayPalCreditFinancing alloc] initWithCardAmountImmutable:isCardAmountImmutable + monthlyPayment:monthlyPayment + payerAcceptance:payerAcceptance + term:term + totalCost:totalCost + totalInterest:totalInterest]; +} + ++ (BTPayPalAccountNonce *)payPalAccountFromJSON:(BTJSON *)payPalAccount { + NSString *nonce = [payPalAccount[@"nonce"] asString]; + NSString *description = [payPalAccount[@"description"] asString]; + + BTJSON *details = payPalAccount[@"details"]; + + NSString *email = [details[@"email"] asString]; + NSString *clientMetadataId = [details[@"correlationId"] asString]; + // Allow email to be under payerInfo + if ([details[@"payerInfo"][@"email"] isString]) { + email = [details[@"payerInfo"][@"email"] asString]; + } + + NSString *firstName = [details[@"payerInfo"][@"firstName"] asString]; + NSString *lastName = [details[@"payerInfo"][@"lastName"] asString]; + NSString *phone = [details[@"payerInfo"][@"phone"] asString]; + NSString *payerId = [details[@"payerInfo"][@"payerId"] asString]; + BOOL isDefault = [payPalAccount[@"default"] isTrue]; + + BTPostalAddress *shippingAddress = [self.class shippingOrBillingAddressFromJSON:details[@"payerInfo"][@"shippingAddress"]]; + BTPostalAddress *billingAddress = [self.class shippingOrBillingAddressFromJSON:details[@"payerInfo"][@"billingAddress"]]; + if (!shippingAddress) { + shippingAddress = [self.class accountAddressFromJSON:details[@"payerInfo"][@"accountAddress"]]; + } + + // Braintree gateway has some inconsistent behavior depending on + // the type of nonce, and sometimes returns "PayPal" for description, + // and sometimes returns a real identifying string. The former is not + // desirable for display. The latter is. + // As a workaround, we ignore descriptions that look like "PayPal". + if ([description caseInsensitiveCompare:@"PayPal"] == NSOrderedSame) { + description = email; + } + + BTPayPalCreditFinancing *creditFinancing = [self.class creditFinancingFromJSON:details[@"creditFinancingOffered"]]; + + BTPayPalAccountNonce *tokenizedPayPalAccount = [[BTPayPalAccountNonce alloc] initWithNonce:nonce + description:description + email:email + firstName:firstName + lastName:lastName + phone:phone + billingAddress:billingAddress + shippingAddress:shippingAddress + clientMetadataId:clientMetadataId + payerId:payerId + isDefault:isDefault + creditFinancing:creditFinancing]; + + return tokenizedPayPalAccount; +} + ++ (NSString *)intentTypeToString:(BTPayPalRequestIntent)intentType { + NSString *result = nil; + + switch(intentType) { + case BTPayPalRequestIntentAuthorize: + result = @"authorize"; + break; + case BTPayPalRequestIntentSale: + result = @"sale"; + break; + case BTPayPalRequestIntentOrder: + result = @"order"; + break; + default: + result = @"authorize"; + break; + } + + return result; +} + ++ (NSString *)landingPageTypeToString:(BTPayPalRequestLandingPageType)landingPageType { + switch(landingPageType) { + case BTPayPalRequestLandingPageTypeLogin: + return @"login"; + case BTPayPalRequestLandingPageTypeBilling: + return @"billing"; + default: + return nil; + } +} + +#pragma mark - Delegate Informers + +- (void)informDelegateWillPerformAppSwitch { + NSNotification *notification = [[NSNotification alloc] initWithName:BTAppSwitchWillSwitchNotification object:self userInfo:nil]; + [[NSNotificationCenter defaultCenter] postNotification:notification]; + + if ([self.appSwitchDelegate respondsToSelector:@selector(appSwitcherWillPerformAppSwitch:)]) { + [self.appSwitchDelegate appSwitcherWillPerformAppSwitch:self]; + } +} + +- (void)informDelegateDidPerformAppSwitchToTarget:(PPOTRequestTarget)target { + BTAppSwitchTarget appSwitchTarget; + switch (target) { + case PPOTRequestTargetBrowser: + appSwitchTarget = BTAppSwitchTargetWebBrowser; + break; + case PPOTRequestTargetOnDeviceApplication: + appSwitchTarget = BTAppSwitchTargetNativeApp; + break; + case PPOTRequestTargetNone: + case PPOTRequestTargetUnknown: + appSwitchTarget = BTAppSwitchTargetUnknown; + // Should never happen + break; + } + + NSNotification *notification = [[NSNotification alloc] initWithName:BTAppSwitchDidSwitchNotification object:self userInfo:@{ BTAppSwitchNotificationTargetKey : @(appSwitchTarget) } ]; + [[NSNotificationCenter defaultCenter] postNotification:notification]; + + if ([self.appSwitchDelegate respondsToSelector:@selector(appSwitcher:didPerformSwitchToTarget:)]) { + [self.appSwitchDelegate appSwitcher:self didPerformSwitchToTarget:appSwitchTarget]; + } +} + +- (void)informDelegateWillProcessAppSwitchReturn { + NSNotification *notification = [[NSNotification alloc] initWithName:BTAppSwitchWillProcessPaymentInfoNotification object:self userInfo:nil]; + [[NSNotificationCenter defaultCenter] postNotification:notification]; + + if ([self.appSwitchDelegate respondsToSelector:@selector(appSwitcherWillProcessPaymentInfo:)]) { + [self.appSwitchDelegate appSwitcherWillProcessPaymentInfo:self]; + } +} + +- (void)informDelegatePresentingViewControllerRequestPresent:(NSURL*) appSwitchURL { + if (self.viewControllerPresentingDelegate != nil && [self.viewControllerPresentingDelegate respondsToSelector:@selector(paymentDriver:requestsPresentationOfViewController:)]) { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 9.0, *)) { +#endif + self.safariViewController = [[SFSafariViewController alloc] initWithURL:appSwitchURL]; + self.safariViewController.delegate = self; + [self.viewControllerPresentingDelegate paymentDriver:self requestsPresentationOfViewController:self.safariViewController]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + } +#endif + } else { + [[BTLogger sharedLogger] critical:@"Unable to display View Controller to continue PayPal flow. BTPayPalDriver needs a viewControllerPresentingDelegate to be set."]; + } +} + +- (void)informDelegatePresentingViewControllerNeedsDismissal { + if (self.viewControllerPresentingDelegate != nil && [self.viewControllerPresentingDelegate respondsToSelector:@selector(paymentDriver:requestsDismissalOfViewController:)]) { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 9.0, *)) { +#endif + [self.viewControllerPresentingDelegate paymentDriver:self requestsDismissalOfViewController:self.safariViewController]; + self.safariViewController = nil; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + } +#endif + } else { + [[BTLogger sharedLogger] critical:@"Unable to dismiss View Controller to end PayPal flow. BTPayPalDriver needs a viewControllerPresentingDelegate to be set."]; + } +} + +#pragma mark - SFSafariViewControllerDelegate + +static NSString * const SFSafariViewControllerFinishedURL = @"sfsafariviewcontroller://finished"; + +- (void)safariViewControllerDidFinish:(__unused SFSafariViewController *)controller API_AVAILABLE(ios(9.0)) { + [self.class handleAppSwitchReturnURL:[NSURL URLWithString:SFSafariViewControllerFinishedURL]]; +} + +#pragma mark - Preflight check + +- (BOOL)verifyAppSwitchWithRemoteConfiguration:(BTJSON *)configuration error:(NSError * __autoreleasing *)error { + if (![configuration[@"paypalEnabled"] isTrue]) { + [self.apiClient sendAnalyticsEvent:@"ios.paypal-otc.preflight.disabled"]; + if (error != NULL) { + *error = [NSError errorWithDomain:BTPayPalDriverErrorDomain + code:BTPayPalDriverErrorTypeDisabled + userInfo:@{ NSLocalizedDescriptionKey: @"PayPal is not enabled for this merchant", + NSLocalizedRecoverySuggestionErrorKey: @"Enable PayPal for this merchant in the Braintree Control Panel" }]; + } + return NO; + } + + if (self.returnURLScheme == nil || [self.returnURLScheme isEqualToString:@""]) { + NSString *recoverySuggestion = @"PayPal requires a return URL scheme to be configured via [BTAppSwitch setReturnURLScheme:]. This custom URL scheme must also be registered with your app."; + [[BTLogger sharedLogger] critical:recoverySuggestion]; + + [self.apiClient sendAnalyticsEvent:@"ios.paypal-otc.preflight.nil-return-url-scheme"]; + if (error != NULL) { + *error = [NSError errorWithDomain:BTPayPalDriverErrorDomain + code:BTPayPalDriverErrorTypeIntegrationReturnURLScheme + userInfo:@{ NSLocalizedDescriptionKey: @"PayPal app switch is missing a returnURLScheme", + NSLocalizedRecoverySuggestionErrorKey: recoverySuggestion }]; + } + return NO; + } + + if (![[self.class payPalClass] doesApplicationSupportOneTouchCallbackURLScheme:self.returnURLScheme]) { + NSString *recoverySuggestion = [NSString stringWithFormat:@"PayPal requires [BTAppSwitch setReturnURLScheme:] to be configured to begin with your app's bundle ID (%@). Currently, it is set to (%@).", [NSBundle mainBundle].bundleIdentifier, self.returnURLScheme]; + [[BTLogger sharedLogger] critical:recoverySuggestion]; + + [self.apiClient sendAnalyticsEvent:@"ios.paypal-otc.preflight.invalid-return-url-scheme"]; + if (error != NULL) { + *error = [NSError errorWithDomain:BTPayPalDriverErrorDomain + code:BTPayPalDriverErrorTypeIntegrationReturnURLScheme + userInfo:@{NSLocalizedFailureReasonErrorKey: @"Application does not support One Touch callback URL scheme", + NSLocalizedRecoverySuggestionErrorKey: recoverySuggestion }]; + } + return NO; + } + + return YES; +} + +#pragma mark - Analytics Helpers + ++ (NSString *)eventStringForPaymentType:(BTPayPalPaymentType)paymentType { + switch (paymentType) { + case BTPayPalPaymentTypeBillingAgreement: + return @"paypal-ba"; + case BTPayPalPaymentTypeFuturePayments: + return @"paypal-future-payments"; + case BTPayPalPaymentTypeCheckout: + return @"paypal-single-payment"; + case BTPayPalPaymentTypeUnknown: + return nil; + } +} + ++ (NSString *)eventStringForRequestTarget:(PPOTRequestTarget)requestTarget { + switch (requestTarget) { + case PPOTRequestTargetNone: + return @"none"; + case PPOTRequestTargetUnknown: + return @"unknown"; + case PPOTRequestTargetOnDeviceApplication: + return @"appswitch"; + case PPOTRequestTargetBrowser: + return @"webswitch"; + } +} + +- (void)sendAnalyticsEventForInitiatingOneTouchForPaymentType:(BTPayPalPaymentType)paymentType + withSuccess:(BOOL)success + target:(PPOTRequestTarget)target +{ + if (paymentType == BTPayPalPaymentTypeUnknown) return; + + NSString *eventName = [NSString stringWithFormat:@"ios.%@.%@.initiate.%@", [self.class eventStringForPaymentType:paymentType], [self.class eventStringForRequestTarget:target], success ? @"started" : @"failed"]; + [self.apiClient sendAnalyticsEvent:eventName]; + + if ((paymentType == BTPayPalPaymentTypeCheckout || paymentType == BTPayPalPaymentTypeBillingAgreement) && self.payPalRequest.offerCredit) { + NSString *eventName = [NSString stringWithFormat:@"ios.%@.%@.credit.offered.%@", [self.class eventStringForPaymentType:paymentType], [self.class eventStringForRequestTarget:target], success ? @"started" : @"failed"]; + + [self.apiClient sendAnalyticsEvent:eventName]; + } +} + +- (void)sendAnalyticsEventForHandlingOneTouchResult:(PPOTResult *)result forPaymentType:(BTPayPalPaymentType)paymentType { + if (paymentType == BTPayPalPaymentTypeUnknown) return; + + NSString *eventName = [NSString stringWithFormat:@"ios.%@.%@", [self.class eventStringForPaymentType:paymentType], [self.class eventStringForRequestTarget:result.target]]; + + switch (result.type) { + case PPOTResultTypeError: + if (result.error.code == PPOTErrorCodePersistedDataFetchFailed) { + return [self.apiClient sendAnalyticsEvent:[NSString stringWithFormat:@"%@.failed-keychain", eventName]]; + } + return [self.apiClient sendAnalyticsEvent:[NSString stringWithFormat:@"%@.failed", eventName]]; + case PPOTResultTypeCancel: + if (result.error) { + return [self.apiClient sendAnalyticsEvent:[NSString stringWithFormat:@"%@.canceled-with-error", eventName]]; + } else { + return [self.apiClient sendAnalyticsEvent:[NSString stringWithFormat:@"%@.canceled", eventName]]; + } + case PPOTResultTypeSuccess: + return [self.apiClient sendAnalyticsEvent:[NSString stringWithFormat:@"%@.succeeded", eventName]]; + } +} + +- (void)sendAnalyticsEventIfCreditFinancingInNonce:(BTPayPalAccountNonce *)payPalAccountNonce forPaymentType:(BTPayPalPaymentType)paymentType { + if ([payPalAccountNonce creditFinancing]) { + NSString *eventName = [NSString stringWithFormat:@"ios.%@.credit.accepted", [self.class eventStringForPaymentType:paymentType]]; + + [self.apiClient sendAnalyticsEvent:eventName]; + } +} + +- (void)sendAnalyticsEventForTokenizationSuccessForPaymentType:(BTPayPalPaymentType)paymentType { + if (paymentType == BTPayPalPaymentTypeUnknown) return; + + NSString *eventName = [NSString stringWithFormat:@"ios.%@.tokenize.succeeded", [self.class eventStringForPaymentType:paymentType]]; + [self.apiClient sendAnalyticsEvent:eventName]; +} + +- (void)sendAnalyticsEventForTokenizationFailureForPaymentType:(BTPayPalPaymentType)paymentType { + if (paymentType == BTPayPalPaymentTypeUnknown) return; + + NSString *eventName = [NSString stringWithFormat:@"ios.%@.tokenize.failed", [self.class eventStringForPaymentType:paymentType]]; + [self.apiClient sendAnalyticsEvent:eventName]; +} + +#pragma mark - App Switch handling + +- (BOOL)isiOSAppAvailableForAppSwitch { + return [[self.class payPalClass] isWalletAppInstalled]; +} + ++ (BOOL)canHandleAppSwitchReturnURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication { + return appSwitchReturnBlock != nil && [PPOTCore canParseURL:url sourceApplication:sourceApplication]; +} + ++ (void)handleAppSwitchReturnURL:(NSURL *)url { + if (appSwitchReturnBlock) { + appSwitchReturnBlock(url); + } +} + +- (NSString *)returnURLScheme { + if (!_returnURLScheme) { + _returnURLScheme = [[BTAppSwitch sharedInstance] returnURLScheme]; + } + return _returnURLScheme; +} + +#pragma mark - BTPayPalApprovalHandler delegate methods + +- (void)onApprovalComplete:(NSURL *)url { + [self.class handleAppSwitchReturnURL:url]; +} + +- (void)onApprovalCancel { + [self.class handleAppSwitchReturnURL:[NSURL URLWithString:SFSafariViewControllerFinishedURL]]; +} + +#pragma mark - Internal + +- (NSURL *)decorateApprovalURL:(NSURL*)approvalURL forRequest:(BTPayPalRequest *)paypalRequest { + if (approvalURL != nil && paypalRequest.userAction != BTPayPalRequestUserActionDefault) { + NSURLComponents* approvalURLComponents = [[NSURLComponents alloc] initWithURL:approvalURL resolvingAgainstBaseURL:NO]; + if (approvalURLComponents != nil) { + NSString *userActionValue = [BTPayPalDriver userActionTypeToString:paypalRequest.userAction]; + if ([userActionValue length] > 0) { + NSString *query = [approvalURLComponents query]; + NSString *delimiter = [query length] == 0 ? @"" : @"&"; + query = [NSString stringWithFormat:@"%@%@useraction=%@", query, delimiter, userActionValue]; + approvalURLComponents.query = query; + } + return [approvalURLComponents URL]; + } + } + return approvalURL; +} + ++ (NSString *)userActionTypeToString:(BTPayPalRequestUserAction)userActionType { + NSString *result = nil; + + switch(userActionType) { + case BTPayPalRequestUserActionCommit: + result = @"commit"; + break; + default: + result = @""; + break; + } + + return result; +} + +- (BTPayPalRequestFactory *)requestFactory { + if (!_requestFactory) { + _requestFactory = [[BTPayPalRequestFactory alloc] init]; + } + return _requestFactory; +} + +static Class PayPalClass; + ++ (void)setPayPalClass:(Class)payPalClass { + if ([payPalClass isSubclassOfClass:[PPOTCore class]]) { + PayPalClass = payPalClass; + } +} + ++ (Class)payPalClass { + return PayPalClass; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/BTPayPalDriver_Internal.h b/Pods/Braintree/BraintreePayPal/BTPayPalDriver_Internal.h new file mode 100644 index 0000000..84590c6 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/BTPayPalDriver_Internal.h @@ -0,0 +1,100 @@ +#import "BTPayPalDriver.h" +#import "BTPayPalRequestFactory.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface BTPayPalDriver () + +/** + @brief Set up the callback to be invoked on return from browser or app switch for PayPal Express Checkout (Checkout Flow) + + @discussion Exposed internally to test BTPayPalDriver app switch return behavior by simulating an app switch return +*/ +- (void)setOneTimePaymentAppSwitchReturnBlock:(void (^)(BTPayPalAccountNonce * _Nullable tokenizedCheckout, NSError * _Nullable error))completionBlock; + +/** + @brief Set up the callback to be invoked on return from browser or app switch for PayPal Billing Agreement (Vault Flow) + + @discussion Exposed internally to test BTPayPalDriver app switch return behavior by simulating an app switch return +*/ +- (void)setBillingAgreementAppSwitchReturnBlock:(void (^)(BTPayPalAccountNonce * _Nullable tokenizedAccount, NSError * _Nullable error))completionBlock; + +/** + @brief Set up the callback to be invoked on return from browser or app switch for PayPal Future Payments (Vault Flow) + + @discussion Exposed internally to test BTPayPalDriver app switch return behavior by simulating an app switch return +*/ +- (void)setAuthorizationAppSwitchReturnBlock:(void (^)(BTPayPalAccountNonce * _Nullable tokenizedAccount, NSError * _Nullable error))completionBlock; + +- (void)informDelegatePresentingViewControllerRequestPresent:(NSURL*) appSwitchURL; + +- (void)informDelegatePresentingViewControllerNeedsDismissal; + +/** + @brief Exposed for testing to create stubbed versions of `PayPalOneTouchAuthorizationRequest` and `PayPalOneTouchCheckoutRequest` +*/ +@property (nonatomic, strong) BTPayPalRequestFactory *requestFactory; + +/** + @brief Exposed for testing to provide subclasses of PayPalOneTouchCore to stub class methods +*/ ++ (Class)payPalClass; ++ (void)setPayPalClass:(Class)payPalClass; + +/** + @brief Exposed for testing to provide a convenient way to inject custom return URL schemes +*/ +@property (nonatomic, copy) NSString *returnURLScheme; + +/** + @brief Exposed for testing to get the instance of BTAPIClient after it has been copied by `copyWithSource:integration:` +*/ +@property (nonatomic, strong, nullable) BTAPIClient *apiClient; + +/** + @brief Exposed for testing the clientMetadataId associated with this request +*/ +@property (nonatomic, strong) NSString *clientMetadataId; + +/** + @brief Exposed for testing the intent associated with this request +*/ +@property (nonatomic, strong) BTPayPalRequest *payPalRequest; + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 +/** + @brief Exposed for testing, the safariViewController instance used for the PayPal flow on iOS 9 and 10 +*/ +@property (nonatomic, strong, nullable) SFSafariViewController *safariViewController NS_AVAILABLE_IOS(9_0); +#endif + + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 +/** + @brief Exposed for testing, the safariAuthenticationSession instance used for the PayPal flow on iOS >=11 + */ +@property (nonatomic, strong, nullable) SFAuthenticationSession *safariAuthenticationSession NS_AVAILABLE_IOS(11_0); +#endif + +/** + @brief Exposed for testing, for determining if SFAuthenticationSession was started + */ +@property (nonatomic, assign) BOOL isSFAuthenticationSessionStarted; + +/** + @brief Exposed for testing, for disabling SFAuthenticationSession and use SFSafariViewController or Safari + */ +@property (nonatomic, assign) BOOL disableSFAuthenticationSession; + +/** + @brief Used to test the Future Payments flow by force +*/ +- (void)authorizeAccountWithAdditionalScopes:(NSSet *)additionalScopes forceFuturePaymentFlow:(BOOL)forceFuturePaymentFlow completion:(void (^)(BTPayPalAccountNonce *, NSError *))completionBlock; + ++ (nullable BTPayPalCreditFinancingAmount *)creditFinancingAmountFromJSON:(BTJSON *)amountJSON; + ++ (nullable BTPayPalCreditFinancing *)creditFinancingFromJSON:(BTJSON *)creditFinancingOfferedJSON; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreePayPal/BTPayPalRequest.m b/Pods/Braintree/BraintreePayPal/BTPayPalRequest.m new file mode 100644 index 0000000..6e4b970 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/BTPayPalRequest.m @@ -0,0 +1,29 @@ +#import "BTPayPalRequest.h" + +@implementation BTPayPalRequest + +- (instancetype)init +{ + self = [super init]; + if (self) { + _shippingAddressRequired = NO; + _offerCredit = NO; + _intent = BTPayPalRequestIntentAuthorize; + _userAction = BTPayPalRequestUserActionDefault; + _landingPageType = BTPayPalRequestLandingPageTypeDefault; + } + return self; +} + +- (instancetype)initWithAmount:(NSString *)amount { + if (amount == nil) { + return nil; + } + + if (self = [self init]) { + _amount = amount; + } + return self; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/BTPayPalRequestFactory.h b/Pods/Braintree/BraintreePayPal/BTPayPalRequestFactory.h new file mode 100644 index 0000000..12b33ab --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/BTPayPalRequestFactory.h @@ -0,0 +1,33 @@ +#import +#import "PPOTRequest.h" +#import "PPOTCore.h" + +@interface BTPayPalRequestFactory : NSObject + +/** + @brief Creates PayPal Express Checkout requests +*/ +- (PPOTCheckoutRequest *)checkoutRequestWithApprovalURL:(NSURL *)approvalURL + clientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme; + +/** + @brief Creates PayPal Billing Agreement requests +*/ +- (PPOTBillingAgreementRequest *)billingAgreementRequestWithApprovalURL:(NSURL *)approvalURL + clientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme; + +/** + @brief Creates PayPal Future Payment requests +*/ +- (PPOTAuthorizationRequest *)requestWithScopeValues:(NSSet *)scopeValues + privacyURL:(NSURL *)privacyURL + agreementURL:(NSURL *)agreementURL + clientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme; + +@end diff --git a/Pods/Braintree/BraintreePayPal/BTPayPalRequestFactory.m b/Pods/Braintree/BraintreePayPal/BTPayPalRequestFactory.m new file mode 100644 index 0000000..1508f99 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/BTPayPalRequestFactory.m @@ -0,0 +1,45 @@ +#import "BTPayPalRequestFactory.h" +#import "PPOTRequestFactory.h" + +@implementation BTPayPalRequestFactory + +- (PPOTCheckoutRequest *)checkoutRequestWithApprovalURL:(NSURL *)approvalURL + clientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme +{ + return [PPOTRequestFactory checkoutRequestWithApprovalURL:approvalURL + pairingId:[PPOTRequest tokenFromApprovalURL:approvalURL] + clientID:clientID + environment:environment + callbackURLScheme:callbackURLScheme]; +} + +- (PPOTBillingAgreementRequest *)billingAgreementRequestWithApprovalURL:(NSURL *)approvalURL + clientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme +{ + return [PPOTRequestFactory billingAgreementRequestWithApprovalURL:approvalURL + pairingId:[PPOTRequest tokenFromApprovalURL:approvalURL] + clientID:clientID + environment:environment + callbackURLScheme:callbackURLScheme]; +} + +- (PPOTAuthorizationRequest *)requestWithScopeValues:(NSSet *)scopeValues + privacyURL:(NSURL *)privacyURL + agreementURL:(NSURL *)agreementURL + clientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme +{ + return [PPOTRequestFactory authorizationRequestWithScopeValues:scopeValues + privacyURL:privacyURL + agreementURL:agreementURL + clientID:clientID + environment:environment + callbackURLScheme:callbackURLScheme]; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalDataCollector/PPDataCollector.m b/Pods/Braintree/BraintreePayPal/PayPalDataCollector/PPDataCollector.m new file mode 100644 index 0000000..66cf239 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalDataCollector/PPDataCollector.m @@ -0,0 +1,71 @@ +// +// PPDataCollector.m +// PPDataCollector +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPDataCollector_Internal.h" +#import "PPRCClientMetadataIDProvider.h" + +#import "PPOTDevice.h" +#import "PPOTVersion.h" +#import "PPOTMacros.h" +#import "PPOTURLSession.h" + +@implementation PPDataCollector + ++ (NSString *)generateClientMetadataID:(NSString *)pairingID { + static PPRCClientMetadataIDProvider *clientMetadataIDProvider; + __block NSString *clientMetadataPairingID = [pairingID copy]; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + PPRCClientMetadataIDProviderNetworkAdapterBlock adapterBlock = ^(NSURLRequest *request, PPRCClientMetadataIDProviderNetworkResponseBlock completionBlock) { + [[PPOTURLSession session] sendRequest:request completionBlock:^(NSData* responseData, NSHTTPURLResponse *response, __unused NSError *error) { + completionBlock(response, responseData); + }]; + }; + + clientMetadataIDProvider = [[PPRCClientMetadataIDProvider alloc] initWithAppGuid:[PPOTDevice appropriateIdentifier] + sourceAppVersion:PayPalOTVersion() + networkAdapterBlock:adapterBlock + pairingID:clientMetadataPairingID]; + // On first time, do not use a pairing ID to generate the client metadata ID because it's already been paired + clientMetadataPairingID = nil; + }); + + NSString *clientMetadataID = [clientMetadataIDProvider clientMetadataID:clientMetadataPairingID]; + PPLog(@"ClientMetadataID: %@", clientMetadataID); + return clientMetadataID; +} + ++ (NSString *)generateClientMetadataID { + return [PPDataCollector generateClientMetadataID:nil]; +} + ++ (nonnull NSString *)clientMetadataID:(nullable NSString *)pairingID { + return [self generateClientMetadataID:pairingID]; +} + ++ (nonnull NSString *)clientMetadataID { + return [self generateClientMetadataID]; +} + ++ (nonnull NSString *)collectPayPalDeviceData { + NSMutableDictionary *dataDictionary = [NSMutableDictionary new]; + NSString *payPalClientMetadataId = [PPDataCollector generateClientMetadataID]; + if (payPalClientMetadataId) { + dataDictionary[@"correlation_id"] = payPalClientMetadataId; + } + + NSError *error; + NSData *data = [NSJSONSerialization dataWithJSONObject:dataDictionary options:0 error:&error]; + if (!data) { + NSLog(@"ERROR: Failed to create deviceData string, error = %@", error); + } + + return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalDataCollector/PPDataCollector_Internal.h b/Pods/Braintree/BraintreePayPal/PayPalDataCollector/PPDataCollector_Internal.h new file mode 100644 index 0000000..fb8be94 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalDataCollector/PPDataCollector_Internal.h @@ -0,0 +1,33 @@ +// +// PPDataCollector.h +// PayPalDataCollector +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPDataCollector.h" + +@interface PPDataCollector () + +/** + @brief Generates a client metadata ID using an optional pairing ID. + + @note This is an internal method for generating raw client metadata IDs, which is not + the correct format for device data when creating a transaction. + + @param pairingID a pairing ID to associate with this clientMetadataID must be 10-32 chars long or null + @return a client metadata ID to send as a header +*/ ++ (nonnull NSString *)generateClientMetadataID:(nullable NSString *)pairingID; + +/** + @brief Generates a client metadata ID. + + @note This is an internal method for generating raw client metadata IDs, which is not + the correct format for device data when creating a transaction. + + @return a client metadata ID to send as a header +*/ ++ (nonnull NSString *)generateClientMetadataID; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalDataCollector/Public/PPDataCollector.h b/Pods/Braintree/BraintreePayPal/PayPalDataCollector/Public/PPDataCollector.h new file mode 100644 index 0000000..2121bdf --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalDataCollector/Public/PPDataCollector.h @@ -0,0 +1,43 @@ +// +// PPDataCollector.h +// PayPalDataCollector +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import + +@interface PPDataCollector : NSObject + +/** + @brief Returns a client metadata ID. + + @note This returns a raw client metadata ID, which is not the correct format for device data + when creating a transaction. Instead, it is recommended to use `collectPayPalDeviceData`. + + @param pairingID a pairing ID to associate with this clientMetadataID must be 10-32 chars long or null + @return a client metadata ID to send as a header +*/ ++ (nonnull NSString *)clientMetadataID:(nullable NSString *)pairingID; + +/** + @brief Returns a client metadata ID. + + @note This returns a raw client metadata ID, which is not the correct format for device data + when creating a transaction. Instead, it is recommended to use `collectPayPalDeviceData`. + + @return a client metadata ID to send as a header +*/ ++ (nonnull NSString *)clientMetadataID DEPRECATED_MSG_ATTRIBUTE("Use [PPDataCollector collectPayPalDeviceData] to generate a device data string."); + +/** + @brief Collects device data for PayPal. + + @discussion This should be used when the user is paying with PayPal or Venmo only. + + @return a deviceData string that should be passed into server-side calls, such as `Transaction.sale`, + for PayPal transactions. This JSON serialized string contains a PayPal fraud ID. +*/ ++ (nonnull NSString *)collectPayPalDeviceData; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalDataCollector/Public/PayPalDataCollector.h b/Pods/Braintree/BraintreePayPal/PayPalDataCollector/Public/PayPalDataCollector.h new file mode 100644 index 0000000..65963f4 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalDataCollector/Public/PayPalDataCollector.h @@ -0,0 +1,17 @@ +// +// PayPalDataCollector.h +// PayPalDataCollector +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import + +//! Project version number for PayPalRisk. +FOUNDATION_EXPORT double PayPalDataCollectorVersionNumber; + +//! Project version string for PayPalRisk. +FOUNDATION_EXPORT const unsigned char PayPalDataCollectorVersionString[]; + +#import "PPRCClientMetadataIDProvider.h" +#import "PPDataCollector.h" diff --git a/Pods/Braintree/BraintreePayPal/PayPalDataCollector/Risk/PPRCClientMetadataIDProvider.h b/Pods/Braintree/BraintreePayPal/PayPalDataCollector/Risk/PPRCClientMetadataIDProvider.h new file mode 100644 index 0000000..b22a0ad --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalDataCollector/Risk/PPRCClientMetadataIDProvider.h @@ -0,0 +1,57 @@ +// +// PPRiskComponentClientMetadataIDProvider.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import + +/** + @brief Block that processes a given HTTP response +*/ +typedef void (^PPRCClientMetadataIDProviderNetworkResponseBlock)(NSHTTPURLResponse * _Nonnull response, NSData * _Nonnull data); + +/** + @brief Networking adapter block which is passed a URL request, the block must send the request, and then passes on the response to the given network response block +*/ +typedef void (^PPRCClientMetadataIDProviderNetworkAdapterBlock)(NSURLRequest * _Nonnull request, _Nonnull PPRCClientMetadataIDProviderNetworkResponseBlock); + +/** + @brief Interface exposed from the Risk Component to bootstrap the Risk Component +*/ +@interface PPRCClientMetadataIDProvider : NSObject + +/** + @brief Initializes the risk component + + @param appGuid the application's GUID + @param sourceAppVersion version of the source app/library + @param networkAdapterBlock the adapter block to send requests +*/ +- (nonnull instancetype)initWithAppGuid:(nonnull NSString *)appGuid + sourceAppVersion:(nonnull NSString *)sourceAppVersion + networkAdapterBlock:(nonnull PPRCClientMetadataIDProviderNetworkAdapterBlock)networkAdapterBlock; + +/** + @brief Initializes the risk component + + @param appGuid the application's GUID + @param sourceAppVersion version of the source app/library + @param networkAdapterBlock the adapter block to send requests + @param pairingID the pairing ID to associate with +*/ +- (nonnull instancetype)initWithAppGuid:(nonnull NSString *)appGuid + sourceAppVersion:(nonnull NSString *)sourceAppVersion + networkAdapterBlock:(nonnull PPRCClientMetadataIDProviderNetworkAdapterBlock)networkAdapterBlock + pairingID:(nullable NSString *)pairingID; + +/** + @brief Generates a client metadata ID + + @param pairingID a pairing ID to associate with this clientMetadataID must be 10-32 chars long or null + @return a client metadata ID +*/ +- (nonnull NSString *)clientMetadataID:(nullable NSString *)pairingID; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalDataCollector/Risk/libPPRiskComponent.a b/Pods/Braintree/BraintreePayPal/PayPalDataCollector/Risk/libPPRiskComponent.a new file mode 100644 index 0000000..aa23802 Binary files /dev/null and b/Pods/Braintree/BraintreePayPal/PayPalDataCollector/Risk/libPPRiskComponent.a differ diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPFPTIData.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPFPTIData.h new file mode 100644 index 0000000..2571a1a --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPFPTIData.h @@ -0,0 +1,49 @@ +// +// PPFPTIData.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import + +/** + @brief Represents the analytics data and metadata for the analytics request. +*/ +@interface PPFPTIData: NSObject + +/** + @brief Designated initializer + + @param params the analytics data to send + @param deviceID the device ID + @param sessionID the session's ID + @param userAgent the user agent string to use + @param trackerURL the tracker URL to send the data to +*/ +- (nonnull instancetype)initWithParams:(nonnull NSDictionary *)params + deviceID:(nonnull NSString *)deviceID + sessionID:(nonnull NSString *)sessionID + userAgent:(nonnull NSString *)userAgent + trackerURL:(nonnull NSURL *)trackerURL; + +/** + @brief The intended NSURL to send the data to +*/ +@property (nonatomic, copy, readonly, nonnull) NSURL *trackerURL; + +/** + @brief The user agent string to use for the request +*/ +@property (nonatomic, copy, readonly, nonnull) NSString *userAgent; + +/** + @brief The analytics data and metadata to send. + + @discussion This data is not the same as the initial params data passed in the + initializer. The format of the dictionary is different and keys/values may be changed. + Usually transformed into a JSON object in the request body. +*/ +- (nonnull NSDictionary *)dataAsDictionary; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPFPTIData.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPFPTIData.m new file mode 100644 index 0000000..533046a --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPFPTIData.m @@ -0,0 +1,97 @@ +// +// PPFPTIData.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPFPTIData.h" + +@interface PPFPTIData () + +@property (nonatomic, strong) NSMutableDictionary *params; +@property (nonatomic, copy) NSString *deviceID; +@property (nonatomic, copy) NSString *sessionID; +@property (nonatomic, copy) NSString *userAgent; +@property (nonatomic, copy) NSURL *trackerURL; + +@end + +@implementation PPFPTIData + +- (instancetype)initWithParams:(NSDictionary *)params + deviceID:(NSString *)deviceID + sessionID:(NSString *)sessionID + userAgent:(NSString *)userAgent + trackerURL:(NSURL *)trackerURL { + self = [super init]; + if (self) { + self.params = [params mutableCopy]; + self.deviceID = deviceID; + self.sessionID = sessionID; + self.userAgent = userAgent; + self.trackerURL = trackerURL; + } + return self; +} + +/* + Sample request + { + "events": { + "actor": { + "tracking_visitor_id":"912bddaa1390abe0eed4d1b541ff46e198", + "tracking_visit_id":"982bddcd1390abe0d4d1b541ff46e12198" + }, + "channel":"mobile", + "tracking_event":"1363303116", + "event_params": { + "sv":"mobile", + "expn":"channel", + "t":"1161775163140", + "g":"-420", + "page":"main" + } + } + } + */ +- (NSDictionary *)dataAsDictionary { + NSTimeInterval impressionTimeInterval = [[NSDate date] timeIntervalSince1970]; + + // Note: If this method is called multiple times, the time may be different + NSString *trackingEventString = [PPFPTIData clientTimestampSinceEpochInMilliseconds:impressionTimeInterval]; + + self.params[@"g"] = [PPFPTIData gmtOffsetInMinutes]; + self.params[@"t"] = [PPFPTIData clientTimestampInLocalTimeZoneSinceEpochInMilliseconds:impressionTimeInterval]; + self.params[@"sv"] = @"mobile"; + + NSDictionary *data = @{ + @"events": @{ + @"actor": @{ + @"tracking_visitor_id": self.deviceID, + @"tracking_visit_id": self.sessionID + }, + @"channel" : @"mobile", + @"tracking_event": trackingEventString, + @"event_params": self.params + } + }; + return data; +} + ++ (NSString *)clientTimestampSinceEpochInMilliseconds:(NSTimeInterval)timeInterval { + return [NSString stringWithFormat:@"%lld", (long long)(timeInterval * 1000)]; +} + ++ (NSString *)clientTimestampInLocalTimeZoneSinceEpochInMilliseconds:(NSTimeInterval)timeInterval { + float timeZoneOffset = [[NSTimeZone systemTimeZone] secondsFromGMT]; + long long timeOffsetInMSInLocalTZ = (long long)((timeInterval - timeZoneOffset)*1000); + return [NSString stringWithFormat:@"%lld", timeOffsetInMSInLocalTZ]; +} + ++ (NSString *)gmtOffsetInMinutes { + float timeZoneOffset = [[NSTimeZone systemTimeZone] secondsFromGMT]; + return [NSString stringWithFormat:@"%d", (int)(timeZoneOffset/60.0)]; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPFPTITracker.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPFPTITracker.h new file mode 100644 index 0000000..50cf144 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPFPTITracker.h @@ -0,0 +1,55 @@ +// +// PPFPTITracker.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import + +@class PPFPTIData; + +/** + @brief Delegate for sending the passed in data +*/ +@protocol PPFPTINetworkAdapterDelegate + +/** + @brief Sends the data using whatever transport the delegate implements. + + @param fptiData contains the data to send, which URL to send it to, and other request metadata +*/ +- (void)sendRequestWithData:(nonnull PPFPTIData*)fptiData; + +@end + +/** + @brief Tracker to send analytics data to. +*/ +@interface PPFPTITracker : NSObject + +/** + @brief Designated initializer. + + @param deviceUDID the device's UDID + @param sessionID the session ID to associate all events to + @param networkAdapterDelegate network delegate responsible for sending requests +*/ +- (nonnull instancetype)initWithDeviceUDID:(nonnull NSString *)deviceUDID + sessionID:(nonnull NSString *)sessionID + networkAdapterDelegate:(nullable id)networkAdapterDelegate; + + +/** + @brief The delegate which actually sends the data +*/ +@property (nonatomic, weak, readwrite, nullable) id networkAdapterDelegate; + +/** + @brief Sends an event with various metrics and data + + @param params the analytics data to send +*/ +- (void)submitEventWithParams:(nonnull NSDictionary *)params; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPFPTITracker.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPFPTITracker.m new file mode 100644 index 0000000..8588476 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPFPTITracker.m @@ -0,0 +1,79 @@ +// +// PPFPTITracker.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import + +#import "PPFPTITracker.h" + +#import "PPFPTIData.h" +#import "PPOTDevice.h" +#import "PPOTVersion.h" + +static NSString* const kTrackerURLAsNSString = @"https://api-m.paypal.com/v1/tracking/events"; + +@interface PPFPTITracker () + +@property (nonatomic, copy, readwrite) NSString *deviceUDID; +@property (nonatomic, copy, readwrite) NSString *sessionID; +@property (nonatomic, copy, readwrite) NSURL *trackerURL; + +@property (nonatomic, copy, readwrite) NSString *userAgent; + +@end + +@implementation PPFPTITracker + +- (instancetype)initWithDeviceUDID:(NSString *)deviceUDID + sessionID:(NSString *)sessionID + networkAdapterDelegate:(id)networkAdapterDelegate { + if (self = [super init]) { + self.deviceUDID = deviceUDID; + self.sessionID = sessionID; + self.trackerURL = [NSURL URLWithString:kTrackerURLAsNSString]; + self.userAgent = [self computeUserAgent]; + self.networkAdapterDelegate = networkAdapterDelegate; + } + return self; +} + +- (void)submitEventWithParams:(NSDictionary *)params { + PPFPTIData *data = [[PPFPTIData alloc] initWithParams:params + deviceID:self.deviceUDID + sessionID:self.sessionID + userAgent:self.userAgent + trackerURL:self.trackerURL]; + if (self.networkAdapterDelegate) { + [self.networkAdapterDelegate sendRequestWithData:data]; + } +} + +- (NSString *)computeUserAgent { + NSLocale *currentLocale = [NSLocale currentLocale]; + NSString *countryCode = [currentLocale objectForKey:NSLocaleCountryCode]; + NSString *language = [currentLocale objectForKey:NSLocaleLanguageCode]; + +#ifdef DEBUG + NSString *releaseMode = @"DEBUG"; +#else + NSString *releaseMode = @"RELEASE"; +#endif + + // PayPalSDK/OneTouchCore-iOS 3.2.2-11-g8b1c0e3 (iPhone; CPU iPhone OS 8_4_1; en-US; iPhone (iPhone5,1); iPhone5,1; DEBUG) + return [NSString stringWithFormat:@"PayPalSDK/OneTouchCore-iOS %@ (%@; CPU %@ %@; %@-%@; %@; %@; %@)", + PayPalOTVersion(), + [UIDevice currentDevice].model, + [UIDevice currentDevice].systemName, + [[UIDevice currentDevice].systemVersion stringByReplacingOccurrencesOfString:@"." withString:@"_"], + language, + countryCode, + [PPOTDevice deviceName], + [PPOTDevice hardwarePlatform], + releaseMode + ]; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPOTAnalyticsDefines.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPOTAnalyticsDefines.h new file mode 100644 index 0000000..4cf43de --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPOTAnalyticsDefines.h @@ -0,0 +1,28 @@ +// +// PPOTAnalyticsDefines.h + +#ifndef TRACKING_DEFINES_H +#define TRACKING_DEFINES_H + +// "Page" is analytics-talk for "Screen" +// "Link" is analytics-talk for "Button, underlined text, or other tappable affordance" + +// Versioning +#define kAnalyticsVersion @"iOS:MODE:" + +// AppSwitch +#define kAnalyticsAppSwitchWalletPresent @"mobile:otc:checkwallet:present:" // followed by protocol +#define kAnalyticsAppSwitchWalletAbsent @"mobile:otc:checkwallet:absent:" // followed by protocol + +#define kAnalyticsAppSwitchPreflightBrowser @"mobile:otc:preflight:browser:" // followed by protocol +#define kAnalyticsAppSwitchPreflightWallet @"mobile:otc:preflight:wallet:" // followed by protocol +#define kAnalyticsAppSwitchPreflightNone @"mobile:otc:preflight:none:" // followed by protocol + +#define kAnalyticsAppSwitchToBrowser @"mobile:otc:switchaway:browser:" // followed by protocol +#define kAnalyticsAppSwitchToWallet @"mobile:otc:switchaway:wallet:" // followed by protocol + +#define kAnalyticsAppSwitchCancel @"mobile:otc:switchback:cancel:" +#define kAnalyticsAppSwitchReturn @"mobile:otc:switchback:return:" + +#endif /* TRACKING_DEFINES_H */ + diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPOTAnalyticsTracker.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPOTAnalyticsTracker.h new file mode 100644 index 0000000..bc196a9 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPOTAnalyticsTracker.h @@ -0,0 +1,31 @@ +// +// PPOTAnalyticsTracker.h +// PayPalOneTouch +// +// Copyright © 2014 PayPal, Inc. All rights reserved. +// + +#import + +@interface PPOTAnalyticsTracker : NSObject + +/** + @brief Retrieves singleton instance. +*/ ++ (nonnull PPOTAnalyticsTracker *)sharedManager; + +/** + @brief Tracks a "page"/action taken. + + @param pagename the page or "action" taken + @param environment the environment (production, sandbox, etc.) + @param clientID the client ID of the request + @param error an optional error that occurred + @param hermesToken web token +*/ +- (void)trackPage:(nonnull NSString *)pagename + environment:(nonnull NSString *)environment + clientID:(nullable NSString *)clientID + error:(nullable NSError *)error + hermesToken:(nullable NSString *)hermesToken; +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPOTAnalyticsTracker.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPOTAnalyticsTracker.m new file mode 100644 index 0000000..f639ce8 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Analytics/PPOTAnalyticsTracker.m @@ -0,0 +1,348 @@ +// +// PPOTAnalyticsTracker.m +// PayPalOneTouch +// +// Copyright © 2014 PayPal, Inc. All rights reserved. +// + +#import + +#import "PPOTAnalyticsTracker.h" + +#import "PPOTCore_Internal.h" +#import "PPOTVersion.h" +#import "PPOTDevice.h" +#import "PPOTMacros.h" +#import "PPOTSimpleKeychain.h" +#import "PPOTString.h" +#import "PPOTURLSession.h" +#import "PPFPTIData.h" +#import "PPFPTITracker.h" +#import "PPOTAnalyticsDefines.h" +#if __has_include("BraintreeCore.h") +#import "BTLogger_Internal.h" +#else +#import +#endif + +#define kTimeForSession (30 * 60) // How long should an Omniture session last. +#define kKeychainIdentifierForUDID @"PayPal_OTC_Analytics_UDID" + +#define kFPTIVersKey @"vers" +#define kFPTIPageKey @"page" +#define kFPTILginKey @"lgin" +#define kFPTIRstaKey @"rsta" +#define kFPTIMosvKey @"mosv" +#define kFPTIMdvsKey @"mdvs" +#define kFPTIMapvKey @"mapv" +#define kFPTIEccdKey @"eccd" +#define kFPTIErpgKey @"erpg" +#define kFPTIFltkKey @"fltk" +#define kFPTITxntKey @"txnt" +#define kFPTIApinKey @"apin" +#define kFPTIBchnKey @"bchn" +#define kFPTISrceKey @"srce" +#define kFPTIBzsrKey @"bzsr" +#define kFPTIPgrpKey @"pgrp" +#define kFPTIVidKey @"vid" +#define kFPTIDsidKey @"dsid" +#define kFPTIClidKey @"clid" + + +@interface PPOTAnalyticsTracker () + +@property (nonatomic, copy, readwrite) NSString *deviceUDID; +@property (nonatomic, copy, readwrite) NSDictionary *trackerParams; + +@property (nonatomic, assign, readwrite) BOOL sessionImpressionSent; +@property (nonatomic, copy, readwrite) NSString *sessionID; +@property (nonatomic, copy, readwrite) NSDate *lastImpressionDate; + +@property (nonatomic, strong, readwrite) NSMutableArray *apiEndpoints; +@property (nonatomic, strong, readwrite) NSMutableArray *apiRoundtripTimes; + +@property (nonatomic, strong, readwrite) PPFPTITracker *fptiTracker; + +@property (nonatomic, strong, readwrite) PPOTURLSession *urlSession; + +@end + +@implementation PPOTAnalyticsTracker + ++ (nonnull PPOTAnalyticsTracker *)sharedManager { + static PPOTAnalyticsTracker* sharedManager = nil; + + static dispatch_once_t pred; + dispatch_once(&pred, ^{ + sharedManager = [[PPOTAnalyticsTracker alloc] init]; + + sharedManager.deviceUDID = [[NSString alloc] initWithData:[PPOTSimpleKeychain dataForKey:kKeychainIdentifierForUDID] + encoding:NSUTF8StringEncoding]; + if ([sharedManager.deviceUDID length] == 0) { + sharedManager.deviceUDID = [PPOTString generateUniquishIdentifier]; + [PPOTSimpleKeychain setData:[sharedManager.deviceUDID dataUsingEncoding:NSUTF8StringEncoding] + forKey:kKeychainIdentifierForUDID]; + } + + // trackingVars are the standard params to add to every request + NSMutableDictionary *trackingVars = [[NSMutableDictionary alloc] init]; + trackingVars[kFPTIMapvKey] = PayPalOTVersion(); // "App" Version number + trackingVars[kFPTIRstaKey] = [[self class] deviceLocale]; // Locale (consumer app bases this on payerCountry) + trackingVars[kFPTIMosvKey] = [NSString stringWithFormat:@"iOS %@", [UIDevice currentDevice].systemVersion]; // Mobile OS + version + trackingVars[kFPTIMdvsKey] = [PPOTDevice deviceName]; // Mobile Device Name, i.e. iPhone 4S + + sharedManager.trackerParams = trackingVars; + + // Initialize FPTI: + sharedManager.fptiTracker = [[PPFPTITracker alloc] initWithDeviceUDID:sharedManager.deviceUDID + sessionID:sharedManager.sessionID + networkAdapterDelegate:sharedManager]; + }); + + return sharedManager; +} + +- (nonnull instancetype)init { + if (self = [super init]) { + _apiRoundtripTimes = [NSMutableArray arrayWithCapacity:4]; + _apiEndpoints = [NSMutableArray arrayWithCapacity:4]; + _sessionImpressionSent = NO; + } + return self; +} + +- (void)dealloc { + [_urlSession finishTasksAndInvalidate]; +} + +#pragma mark - Smart getter for sessionID + +- (nonnull NSString *)sessionID { + // For Omniture, the session should last 30 minutes + if (_lastImpressionDate != nil && [[NSDate date] timeIntervalSinceDate:_lastImpressionDate] >= kTimeForSession) { + _sessionID = nil; + self.sessionImpressionSent = NO; + } + + if (_sessionID == nil) { + _sessionID = [PPOTAnalyticsTracker newOmnitureSessionID]; + } + + return _sessionID; +} + +/** + Generates a session ID + + @return a session ID + */ ++ (nonnull NSString *)newOmnitureSessionID { + // The javascript is sed=Math&&Math.random?Math.floor(Math.random()*10000000000000):tm.getTime(),sess='s'+Math.floor(tm.getTime()/10800000)%10+sed + // JavaScript Math.random gives a value between 0 and 1 + srandom((unsigned)[[NSDate date] timeIntervalSince1970]); // Seed the random number generator + NSUInteger rnumber = (NSUInteger) (10000000000000 * ((float) random() / (float) RAND_MAX)); + + // Javascript getTime is # of milliseconds from 1/1/1970 + return [NSString stringWithFormat:@"%lu", (unsigned long)(rnumber + (NSUInteger)floor((([NSDate timeIntervalSinceReferenceDate] + NSTimeIntervalSince1970) / (float) 10800)) % 10)]; +} + +#pragma mark - + +- (void)trackPage:(nonnull NSString *)pagename + environment:(nonnull NSString *)environment + clientID:(nullable NSString *)clientID + error:(nullable NSError *)error + hermesToken:(nullable NSString *)hermesToken { + // Use PPAsserts to catch bad parameters in Debug version: + PPAssert([pagename length], @"pagename must be non-empty"); + PPAssert(environment, @"environment can't be nil (can be empty string, though)"); + PPAssert(clientID, @"clientID can't be nil (can be empty string, though)"); + + // Sanity-check parameters to prevent crashes in Release version: + if (![pagename length]) { + return; + } + if (!environment) { + environment = @""; + } + if (!clientID) { + clientID = @""; + } + + NSMutableDictionary *params = [[NSMutableDictionary alloc] init]; + + NSString *version = [kAnalyticsVersion stringByReplacingOccurrencesOfString:@"MODE" withString:environment]; + NSString *nameStr = [NSString stringWithFormat:@"%@:%@", pagename, version]; + if (error != nil) { + nameStr = [nameStr stringByAppendingString:@"|error"]; + } + + params[kFPTIVersKey] = version; + params[kFPTIPageKey] = nameStr; + params[kFPTILginKey] = @"out"; + params[kFPTIPgrpKey] = (error == nil) ? pagename : [pagename stringByAppendingString:@"|error"]; + params[kFPTIBchnKey] = @"otc"; + params[kFPTISrceKey] = @"otc"; + params[kFPTIBzsrKey] = @"mobile"; + params[kFPTIVidKey] = self.sessionID; + params[kFPTIDsidKey] = self.deviceUDID; + params[kFPTIClidKey] = clientID; + params[@"e"] = @"im"; + params[@"apid"] = [self appBundleInformation]; + + if ([hermesToken length]) { + params[kFPTIFltkKey] = hermesToken; + } + + [self addTrackerParamsTo:params]; + [self addAPIEndpointParamsTo:params]; + [self addErrorParamsTo:params withError:error]; + + // Send to FPTI. In this case, the FPTITracker prepares/formats the data which then is sent back to this instance's + // PPFPTINetworkAdapterDelegate method. + [self.fptiTracker submitEventWithParams:params]; +} + +#pragma mark - Helper methods for tracker data + +/** + Adds tracker level parameters to the params request. Tracker level params are constant parameters (say a device name) + which do not need to be re-calculated. + + @param params dictionary to add data to + */ +- (void)addTrackerParamsTo:(nonnull NSMutableDictionary *)params { + // If there is a standard set of properties/parameters to send on each call, add it now. + if (self.trackerParams != nil && [self.trackerParams count]) { + if (_sessionImpressionSent) { + // Always send the rsta value + params[@"rsta"] = self.trackerParams[@"rsta"]; + } + else { + [params addEntriesFromDictionary:self.trackerParams]; + } + } +} + +/** + Return the bundle information for analytics + + @return bundle information as a string + */ +- (nonnull NSString *)appBundleInformation { + NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; + return [NSString stringWithFormat:@"%@|%@|%@|%@|%@|%@", + infoDictionary[@"CFBundleExecutable"], + infoDictionary[@"CFBundleIdentifier"], + infoDictionary[@"CFBundleName"], + infoDictionary[@"CFBundleShortVersionString"], + infoDictionary[@"CFBundleVersion"], + infoDictionary[@"CFBundleDisplayName"]]; +} + +/** + Adds the API endpoint params + + @param params dictionary to add data to + */ +- (void)addAPIEndpointParamsTo:(nonnull NSMutableDictionary *)params { + if ([self.apiRoundtripTimes count]) { + NSMutableString *timesString = [NSMutableString string]; + NSMutableString *endpointsString = [NSMutableString string]; + + for (NSUInteger index = 0; index < [self.apiRoundtripTimes count]; index++) { + if ([timesString length]) { + [timesString appendString:@"|"]; + [endpointsString appendString:@"|"]; + } + [timesString appendFormat:@"%ld", (long)[self.apiRoundtripTimes[index] integerValue]]; + [endpointsString appendString:self.apiEndpoints[index]]; + } + + params[kFPTITxntKey] = timesString; + params[kFPTIApinKey] = endpointsString; + + [self.apiRoundtripTimes removeAllObjects]; + [self.apiEndpoints removeAllObjects]; + } +} + +/** + Adds the error param information (if there is an error + + @param params dictionary to add data to + @param error the error + */ +- (void)addErrorParamsTo:(nonnull NSMutableDictionary *)params withError:(nullable NSError *)error { + if (error != nil) { + if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorCancelled) { + // if Canceled, don't report as an error + } + else { + params[kFPTIEccdKey] = [NSString stringWithFormat:@"%ld", (long)error.code]; + params[kFPTIErpgKey] = ([error.localizedDescription length] > 0) ? error.localizedDescription : @"Unknown error"; + } + } +} + + +#pragma mark - PPFPTINetworkAdapterDelegate + +- (void)sendRequestWithData:(nonnull __attribute__((unused)) PPFPTIData*)fptiData { + NSDictionary *fptiDataDictionary = [fptiData dataAsDictionary]; + NSDictionary *params = fptiDataDictionary[@"events"][@"event_params"]; + NSString *nameStr = params[@"page"]; + + NSArray *pageComponents = [nameStr componentsSeparatedByString:@":"]; + NSString *environment = pageComponents[[pageComponents count] - 2]; + + if ([environment isEqualToString:@"mock"]) { + return; + } + + NSURL* url = [fptiData trackerURL]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + request.HTTPShouldUsePipelining = YES; + [request setHTTPMethod:@"POST"]; + [request setValue:[fptiData userAgent] forHTTPHeaderField:@"User-Agent"]; + [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; + + NSError *error; + NSData *fptiJSONData = [NSJSONSerialization dataWithJSONObject:fptiDataDictionary options:0 error:&error]; + if (fptiJSONData == nil && error != NULL) { + // ignore the error + } else { + [request setHTTPBody:fptiJSONData]; + [self.urlSession sendRequest:request completionBlock:nil]; + } +} + +#pragma mark - + ++ (NSString *)deviceLocale { + // unlike NSLocaleIdentifier, this will always be either just language (@"en") or else language_COUNTRY (@"en_US") + NSString *language = [[self class] deviceLanguage]; + NSString *country = [[self class] deviceCountryCode]; + if ([country length]) { + return [NSString stringWithFormat:@"%@_%@", language, country]; + } + else { + return language; + } +} + ++ (NSString *)deviceLanguage { + return [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]; +} + ++ (NSString *)deviceCountryCode { + //gives the country code from the device + NSString *countryCode = [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode]; + if (!countryCode) { + // NSLocaleCountryCode can return nil if device's Region is set to English, Esperanto, etc. + countryCode = @""; + } + return countryCode; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Configuration/PPDefaultConfigurationJSON.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Configuration/PPDefaultConfigurationJSON.h new file mode 100644 index 0000000..8b80793 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Configuration/PPDefaultConfigurationJSON.h @@ -0,0 +1,1730 @@ +unsigned char configuration_otc_config_ios_json[] = { + 0x7b, 0x0a, 0x20, 0x20, 0x22, 0x6f, 0x73, 0x22, 0x3a, 0x20, 0x22, 0x69, + 0x4f, 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x22, 0x66, 0x69, 0x6c, 0x65, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3a, + 0x20, 0x22, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x31, 0x2d, 0x31, 0x31, + 0x54, 0x31, 0x36, 0x3a, 0x34, 0x32, 0x3a, 0x30, 0x30, 0x5a, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x22, 0x31, 0x2e, 0x30, 0x22, 0x3a, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x5f, + 0x72, 0x65, 0x63, 0x69, 0x70, 0x65, 0x73, 0x5f, 0x69, 0x6e, 0x5f, 0x64, + 0x65, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x72, + 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x77, 0x61, 0x6c, 0x6c, + 0x65, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x3a, + 0x20, 0x22, 0x33, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, + 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x5b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x64, 0x61, 0x5f, 0x44, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, 0x41, 0x54, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x64, 0x65, 0x5f, 0x42, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, + 0x43, 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, 0x44, 0x45, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, + 0x65, 0x5f, 0x44, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, 0x4c, 0x55, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x41, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x41, + 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x41, 0x54, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x41, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x42, 0x45, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x42, 0x47, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x42, 0x48, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x42, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x43, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x43, 0x48, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x43, 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x43, 0x5a, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x44, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x44, + 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x44, 0x5a, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x45, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x45, 0x53, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x46, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x46, 0x52, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x47, 0x42, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x47, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x48, 0x4b, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x48, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x49, 0x45, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x49, 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x49, + 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4a, 0x4f, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x4a, 0x50, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4b, 0x57, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x4b, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4c, 0x54, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4c, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x4c, 0x56, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4d, 0x41, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x4d, 0x58, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4d, 0x59, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x4e, 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4e, + 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4e, 0x5a, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x4f, 0x4d, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x50, 0x48, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x50, 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x50, 0x54, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x51, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x52, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x52, 0x55, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x53, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x53, 0x45, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x53, 0x47, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x53, + 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x53, 0x4b, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x54, 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x54, 0x52, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x55, 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x59, 0x45, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x73, 0x5f, 0x41, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, + 0x41, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x42, 0x48, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x73, 0x5f, 0x43, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x44, 0x5a, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x73, 0x5f, 0x45, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x45, + 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x46, 0x49, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, + 0x5f, 0x47, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x48, 0x55, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x73, 0x5f, 0x4a, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4b, 0x57, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4b, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, + 0x4c, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4c, 0x55, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x73, 0x5f, 0x4c, 0x56, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4d, 0x41, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x73, 0x5f, 0x4d, 0x58, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4e, + 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4f, 0x4d, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, + 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x51, 0x41, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x73, 0x5f, 0x52, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x53, 0x41, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x73, 0x5f, 0x53, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, + 0x53, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x54, 0x4e, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x73, 0x5f, 0x55, 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x59, 0x45, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x66, 0x72, 0x5f, 0x41, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x42, + 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x42, 0x48, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, + 0x5f, 0x43, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x43, 0x48, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x66, 0x72, 0x5f, 0x43, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x44, 0x5a, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x66, 0x72, 0x5f, 0x45, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, + 0x46, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x46, 0x52, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, + 0x72, 0x5f, 0x47, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x48, 0x55, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x66, 0x72, 0x5f, 0x4a, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4b, + 0x57, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4b, 0x5a, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, + 0x5f, 0x4c, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4c, 0x55, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x66, 0x72, 0x5f, 0x4c, 0x56, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4d, 0x41, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4e, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, + 0x4f, 0x4d, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, + 0x72, 0x5f, 0x51, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x52, 0x4f, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x66, 0x72, 0x5f, 0x53, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x53, + 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x53, 0x4b, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, + 0x5f, 0x54, 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x55, 0x53, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x66, 0x72, 0x5f, 0x59, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x74, 0x5f, 0x49, 0x54, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x69, 0x77, 0x5f, 0x49, 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6a, 0x61, 0x5f, + 0x4a, 0x50, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x6e, 0x62, 0x5f, 0x4e, 0x4f, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, + 0x6c, 0x5f, 0x42, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x6c, 0x5f, 0x4e, 0x4c, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x6e, 0x6f, 0x5f, 0x4e, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x6c, 0x5f, 0x50, + 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x70, 0x74, 0x5f, 0x42, 0x52, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x74, + 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x75, 0x5f, 0x45, 0x45, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x72, 0x75, 0x5f, 0x4c, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x75, 0x5f, 0x4c, 0x56, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x72, 0x75, 0x5f, 0x52, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x65, 0x5f, + 0x53, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x73, 0x76, 0x5f, 0x53, 0x45, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, + 0x72, 0x5f, 0x54, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x41, 0x45, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x7a, 0x68, 0x5f, 0x42, 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x43, + 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x43, 0x5a, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, + 0x5f, 0x44, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x45, 0x45, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x7a, 0x68, 0x5f, 0x46, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x47, 0x52, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x48, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, + 0x48, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4a, 0x4f, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, + 0x68, 0x5f, 0x4b, 0x57, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4b, 0x5a, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x7a, 0x68, 0x5f, 0x4c, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4c, + 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4c, 0x56, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, + 0x5f, 0x4d, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4e, 0x5a, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x7a, 0x68, 0x5f, 0x4f, 0x4d, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x50, 0x54, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x51, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, + 0x52, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x53, 0x41, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, + 0x68, 0x5f, 0x53, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x53, 0x4b, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x7a, 0x68, 0x5f, 0x54, 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x55, + 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x59, 0x45, 0x22, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x22, + 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x75, + 0x72, 0x69, 0x2e, 0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x70, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x66, 0x75, 0x74, 0x75, + 0x72, 0x65, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, + 0x70, 0x65, 0x6e, 0x69, 0x64, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x22, 0x3a, 0x20, + 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, + 0x70, 0x70, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x6f, 0x75, + 0x63, 0x68, 0x2e, 0x76, 0x33, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x6f, 0x6d, + 0x2e, 0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x2a, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, + 0x6f, 0x6d, 0x2e, 0x79, 0x6f, 0x75, 0x72, 0x63, 0x6f, 0x6d, 0x70, 0x61, + 0x6e, 0x79, 0x2e, 0x70, 0x70, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x77, + 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x22, 0x3a, 0x20, 0x22, 0x32, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x65, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x73, 0x22, + 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x64, 0x61, 0x5f, 0x44, 0x4b, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, + 0x5f, 0x41, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, 0x42, 0x45, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x64, 0x65, 0x5f, 0x43, 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, 0x44, 0x45, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x64, 0x65, 0x5f, 0x44, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, + 0x4c, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x41, 0x45, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x41, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x41, 0x54, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x41, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x42, + 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x42, 0x47, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x42, 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x42, 0x52, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x43, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x43, 0x48, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x43, 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x43, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x44, 0x45, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x44, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x44, 0x5a, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x45, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x45, + 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x46, 0x49, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x46, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x47, 0x42, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x47, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x48, 0x4b, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x48, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x49, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x49, 0x4c, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x49, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4a, 0x4f, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x4a, 0x50, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4b, + 0x57, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4b, 0x5a, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x4c, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4c, 0x55, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x4c, 0x56, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4d, 0x41, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4d, 0x58, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x4d, 0x59, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4e, 0x4c, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x4e, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4e, 0x5a, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x4f, 0x4d, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x50, + 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x50, 0x4c, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x51, 0x41, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x52, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x52, 0x55, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x53, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x53, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x53, 0x47, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x53, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x53, 0x4b, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x54, 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x54, + 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x55, 0x53, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x59, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x41, 0x45, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x73, 0x5f, 0x41, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x42, 0x48, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x73, 0x5f, 0x43, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, + 0x44, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x45, 0x45, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x73, 0x5f, 0x45, 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x46, 0x49, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x73, 0x5f, 0x47, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x48, + 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4a, 0x4f, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, + 0x5f, 0x4b, 0x57, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4b, 0x5a, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x73, 0x5f, 0x4c, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4c, 0x55, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4c, 0x56, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, + 0x4d, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4d, 0x58, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x73, 0x5f, 0x4e, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4f, 0x4d, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x73, 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x51, + 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x52, 0x4f, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, + 0x5f, 0x53, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x53, 0x49, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x73, 0x5f, 0x53, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x54, 0x4e, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x73, 0x5f, 0x55, 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, + 0x59, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x41, 0x45, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, + 0x72, 0x5f, 0x42, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x42, 0x48, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x66, 0x72, 0x5f, 0x43, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x43, + 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x43, 0x5a, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, + 0x5f, 0x44, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x45, 0x45, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x66, 0x72, 0x5f, 0x46, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x46, 0x52, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x66, 0x72, 0x5f, 0x47, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, + 0x48, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4a, 0x4f, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, + 0x72, 0x5f, 0x4b, 0x57, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4b, 0x5a, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x66, 0x72, 0x5f, 0x4c, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4c, + 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4c, 0x56, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, + 0x5f, 0x4d, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4e, 0x5a, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x66, 0x72, 0x5f, 0x4f, 0x4d, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x50, 0x54, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x66, 0x72, 0x5f, 0x51, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, + 0x52, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x53, 0x41, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, + 0x72, 0x5f, 0x53, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x53, 0x4b, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x66, 0x72, 0x5f, 0x54, 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x55, + 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x59, 0x45, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x74, + 0x5f, 0x49, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x77, 0x5f, 0x49, 0x4c, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x6a, 0x61, 0x5f, 0x4a, 0x50, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x62, 0x5f, 0x4e, 0x4f, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x6e, 0x6c, 0x5f, 0x42, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x6c, 0x5f, + 0x4e, 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x6e, 0x6f, 0x5f, 0x4e, 0x4f, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, + 0x6c, 0x5f, 0x50, 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x74, 0x5f, 0x42, 0x52, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x70, 0x74, 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x75, 0x5f, 0x45, + 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x72, 0x75, 0x5f, 0x4c, 0x54, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x75, + 0x5f, 0x4c, 0x56, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x75, 0x5f, 0x52, 0x55, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x73, 0x65, 0x5f, 0x53, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x76, 0x5f, 0x53, 0x45, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x74, 0x72, 0x5f, 0x54, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, + 0x41, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x42, 0x48, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, + 0x68, 0x5f, 0x43, 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x43, 0x5a, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x7a, 0x68, 0x5f, 0x44, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x45, + 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x46, 0x49, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, + 0x5f, 0x47, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x48, 0x4b, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x7a, 0x68, 0x5f, 0x48, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4a, 0x4f, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4b, 0x57, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, + 0x4b, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4c, 0x54, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, + 0x68, 0x5f, 0x4c, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4c, 0x56, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x7a, 0x68, 0x5f, 0x4d, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4e, + 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4f, 0x4d, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, + 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x51, 0x41, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x7a, 0x68, 0x5f, 0x52, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x53, 0x41, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x53, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, + 0x53, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x54, 0x4e, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, + 0x68, 0x5f, 0x55, 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x59, 0x45, 0x22, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x6f, + 0x70, 0x65, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, + 0x2f, 0x2f, 0x75, 0x72, 0x69, 0x2e, 0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x66, + 0x75, 0x74, 0x75, 0x72, 0x65, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x68, 0x6f, 0x6e, 0x65, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x64, 0x22, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x61, 0x79, 0x70, + 0x61, 0x6c, 0x2e, 0x70, 0x70, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, + 0x74, 0x6f, 0x75, 0x63, 0x68, 0x2e, 0x76, 0x32, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x70, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3a, 0x20, 0x5b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x2a, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x79, 0x6f, 0x75, 0x72, 0x63, 0x6f, + 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x70, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x3a, + 0x20, 0x22, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x3a, 0x20, 0x22, 0x31, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x65, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x61, 0x5f, 0x44, 0x4b, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x64, 0x65, 0x5f, 0x41, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, 0x42, + 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, 0x43, 0x48, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, + 0x5f, 0x44, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, 0x44, 0x4b, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x64, 0x65, 0x5f, 0x4c, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x41, 0x52, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x41, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x41, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x42, 0x45, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x42, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x43, 0x41, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x43, 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x43, + 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x44, 0x45, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x44, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x45, 0x53, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x46, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x46, 0x52, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x47, 0x42, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x48, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x49, 0x45, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x49, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4a, 0x50, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x4c, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4d, + 0x58, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4e, 0x4c, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x4e, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x50, 0x4c, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x52, 0x55, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x53, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x53, 0x47, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x54, 0x52, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x55, 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x41, 0x52, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x73, 0x5f, 0x45, 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x46, + 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4c, 0x55, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, + 0x5f, 0x4d, 0x58, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x50, 0x54, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x73, 0x5f, 0x55, 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x42, 0x45, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x66, 0x72, 0x5f, 0x43, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, + 0x43, 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x46, 0x49, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, + 0x72, 0x5f, 0x46, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4c, 0x55, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x66, 0x72, 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x55, + 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x69, 0x74, 0x5f, 0x49, 0x54, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6a, 0x61, + 0x5f, 0x4a, 0x50, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x62, 0x5f, 0x4e, 0x4f, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x6e, 0x6c, 0x5f, 0x42, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x6c, 0x5f, 0x4e, 0x4c, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x6e, 0x6f, 0x5f, 0x4e, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x6c, 0x5f, + 0x50, 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x70, 0x74, 0x5f, 0x42, 0x52, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, + 0x74, 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x75, 0x5f, 0x52, 0x55, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x73, 0x65, 0x5f, 0x53, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x76, 0x5f, 0x53, + 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x74, 0x72, 0x5f, 0x54, 0x52, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, + 0x5f, 0x43, 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x46, 0x49, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x7a, 0x68, 0x5f, 0x48, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4c, 0x55, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, + 0x55, 0x53, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x73, 0x63, 0x6f, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x75, 0x72, 0x69, 0x2e, 0x70, 0x61, 0x79, + 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2f, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x70, 0x61, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x68, + 0x6f, 0x6e, 0x65, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x64, 0x22, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x70, + 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x70, 0x70, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x2e, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x2e, 0x76, 0x31, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, + 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x61, 0x79, 0x70, 0x61, + 0x6c, 0x2e, 0x2a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x79, 0x6f, 0x75, + 0x72, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x70, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x22, 0x3a, 0x20, 0x22, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x3a, 0x20, 0x22, + 0x33, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x68, 0x74, + 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x75, 0x72, 0x69, 0x2e, 0x70, 0x61, + 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2f, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x70, 0x61, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, + 0x68, 0x6f, 0x6e, 0x65, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6f, 0x70, 0x65, 0x6e, 0x69, 0x64, + 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x3a, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6c, + 0x69, 0x76, 0x65, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x75, 0x72, 0x6c, + 0x22, 0x3a, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x2e, 0x70, 0x61, 0x79, + 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x65, 0x2d, + 0x74, 0x6f, 0x75, 0x63, 0x68, 0x2d, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x2f, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x22, 0x30, 0x30, 0x38, + 0x31, 0x45, 0x44, 0x46, 0x35, 0x34, 0x36, 0x43, 0x42, 0x46, 0x36, 0x32, + 0x44, 0x45, 0x32, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x4d, 0x49, + 0x49, 0x44, 0x7a, 0x7a, 0x43, 0x43, 0x41, 0x72, 0x65, 0x67, 0x41, 0x77, + 0x49, 0x42, 0x41, 0x67, 0x49, 0x4a, 0x41, 0x49, 0x48, 0x74, 0x39, 0x55, + 0x62, 0x4c, 0x39, 0x69, 0x33, 0x69, 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, + 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, 0x77, + 0x55, 0x41, 0x4d, 0x48, 0x34, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, + 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6c, 0x56, 0x54, 0x4d, 0x52, + 0x4d, 0x77, 0x45, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x49, 0x44, 0x41, + 0x70, 0x44, 0x59, 0x57, 0x78, 0x70, 0x5a, 0x6d, 0x39, 0x79, 0x62, 0x6d, + 0x6c, 0x68, 0x4d, 0x52, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x51, + 0x51, 0x48, 0x44, 0x41, 0x68, 0x54, 0x59, 0x57, 0x34, 0x67, 0x53, 0x6d, + 0x39, 0x7a, 0x5a, 0x54, 0x45, 0x50, 0x4d, 0x41, 0x30, 0x47, 0x41, 0x31, + 0x55, 0x45, 0x43, 0x67, 0x77, 0x47, 0x55, 0x47, 0x46, 0x35, 0x55, 0x47, + 0x46, 0x73, 0x4d, 0x52, 0x49, 0x77, 0x45, 0x41, 0x59, 0x44, 0x56, 0x51, + 0x51, 0x4c, 0x44, 0x41, 0x6c, 0x43, 0x63, 0x6d, 0x46, 0x70, 0x62, 0x6e, + 0x52, 0x79, 0x5a, 0x57, 0x55, 0x78, 0x49, 0x6a, 0x41, 0x67, 0x42, 0x67, + 0x4e, 0x56, 0x42, 0x41, 0x4d, 0x4d, 0x47, 0x56, 0x42, 0x79, 0x62, 0x32, + 0x52, 0x31, 0x59, 0x33, 0x52, 0x70, 0x62, 0x32, 0x34, 0x67, 0x51, 0x6e, + 0x4a, 0x76, 0x64, 0x33, 0x4e, 0x6c, 0x63, 0x69, 0x42, 0x54, 0x64, 0x32, + 0x6c, 0x30, 0x59, 0x32, 0x67, 0x77, 0x48, 0x68, 0x63, 0x4e, 0x4d, 0x54, + 0x55, 0x77, 0x4e, 0x44, 0x45, 0x78, 0x4d, 0x54, 0x63, 0x31, 0x4d, 0x44, + 0x49, 0x35, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x54, 0x63, 0x77, 0x4e, 0x44, + 0x45, 0x77, 0x4d, 0x54, 0x63, 0x31, 0x4d, 0x44, 0x49, 0x35, 0x57, 0x6a, + 0x42, 0x2b, 0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, + 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55, 0x7a, 0x45, 0x54, 0x4d, 0x42, + 0x45, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x41, 0x77, 0x4b, 0x51, 0x32, + 0x46, 0x73, 0x61, 0x57, 0x5a, 0x76, 0x63, 0x6d, 0x35, 0x70, 0x59, 0x54, + 0x45, 0x52, 0x4d, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x77, + 0x77, 0x49, 0x55, 0x32, 0x46, 0x75, 0x49, 0x45, 0x70, 0x76, 0x63, 0x32, + 0x55, 0x78, 0x44, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, + 0x6f, 0x4d, 0x42, 0x6c, 0x42, 0x68, 0x65, 0x56, 0x42, 0x68, 0x62, 0x44, + 0x45, 0x53, 0x4d, 0x42, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x77, + 0x77, 0x4a, 0x51, 0x6e, 0x4a, 0x68, 0x61, 0x57, 0x35, 0x30, 0x63, 0x6d, + 0x56, 0x6c, 0x4d, 0x53, 0x49, 0x77, 0x49, 0x41, 0x59, 0x44, 0x56, 0x51, + 0x51, 0x44, 0x44, 0x42, 0x6c, 0x51, 0x63, 0x6d, 0x39, 0x6b, 0x64, 0x57, + 0x4e, 0x30, 0x61, 0x57, 0x39, 0x75, 0x49, 0x45, 0x4a, 0x79, 0x62, 0x33, + 0x64, 0x7a, 0x5a, 0x58, 0x49, 0x67, 0x55, 0x33, 0x64, 0x70, 0x64, 0x47, + 0x4e, 0x6f, 0x4d, 0x49, 0x49, 0x42, 0x49, 0x6a, 0x41, 0x4e, 0x42, 0x67, + 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, + 0x45, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, 0x38, 0x41, 0x4d, 0x49, + 0x49, 0x42, 0x43, 0x67, 0x4b, 0x43, 0x41, 0x51, 0x45, 0x41, 0x74, 0x2b, + 0x43, 0x63, 0x36, 0x47, 0x42, 0x33, 0x51, 0x44, 0x46, 0x43, 0x68, 0x65, + 0x69, 0x56, 0x6f, 0x4c, 0x6c, 0x43, 0x59, 0x32, 0x46, 0x55, 0x52, 0x46, + 0x48, 0x30, 0x49, 0x6a, 0x4a, 0x66, 0x78, 0x73, 0x52, 0x38, 0x6c, 0x35, + 0x49, 0x4b, 0x59, 0x56, 0x4d, 0x66, 0x2b, 0x47, 0x6a, 0x62, 0x41, 0x4e, + 0x76, 0x53, 0x2f, 0x48, 0x74, 0x55, 0x59, 0x69, 0x70, 0x34, 0x72, 0x66, + 0x53, 0x6a, 0x47, 0x34, 0x58, 0x6c, 0x49, 0x54, 0x70, 0x50, 0x6b, 0x77, + 0x4f, 0x31, 0x63, 0x46, 0x2f, 0x78, 0x61, 0x42, 0x77, 0x54, 0x33, 0x55, + 0x42, 0x59, 0x39, 0x76, 0x76, 0x69, 0x51, 0x6c, 0x56, 0x4d, 0x62, 0x6f, + 0x56, 0x66, 0x74, 0x6c, 0x67, 0x78, 0x5a, 0x2f, 0x69, 0x55, 0x6a, 0x41, + 0x6c, 0x78, 0x4b, 0x66, 0x32, 0x38, 0x42, 0x45, 0x39, 0x36, 0x62, 0x53, + 0x35, 0x33, 0x74, 0x4f, 0x62, 0x66, 0x54, 0x75, 0x48, 0x6e, 0x72, 0x62, + 0x2b, 0x6b, 0x6e, 0x65, 0x59, 0x51, 0x49, 0x5a, 0x71, 0x57, 0x43, 0x67, + 0x34, 0x38, 0x6d, 0x5a, 0x53, 0x63, 0x35, 0x6d, 0x52, 0x32, 0x67, 0x71, + 0x68, 0x62, 0x73, 0x33, 0x35, 0x47, 0x43, 0x34, 0x75, 0x64, 0x48, 0x30, + 0x45, 0x45, 0x6f, 0x4e, 0x49, 0x48, 0x46, 0x53, 0x76, 0x41, 0x63, 0x65, + 0x73, 0x55, 0x70, 0x51, 0x7a, 0x52, 0x33, 0x4d, 0x55, 0x55, 0x37, 0x50, + 0x57, 0x52, 0x62, 0x6f, 0x43, 0x6c, 0x4f, 0x76, 0x77, 0x45, 0x57, 0x76, + 0x6e, 0x62, 0x68, 0x6d, 0x44, 0x48, 0x6c, 0x42, 0x34, 0x6f, 0x59, 0x61, + 0x49, 0x72, 0x57, 0x78, 0x50, 0x2b, 0x75, 0x54, 0x41, 0x54, 0x76, 0x36, + 0x63, 0x57, 0x66, 0x65, 0x72, 0x6b, 0x75, 0x37, 0x37, 0x52, 0x74, 0x51, + 0x4a, 0x49, 0x6f, 0x62, 0x66, 0x53, 0x51, 0x76, 0x52, 0x56, 0x52, 0x43, + 0x44, 0x71, 0x6c, 0x41, 0x6a, 0x62, 0x49, 0x2f, 0x63, 0x37, 0x67, 0x30, + 0x36, 0x46, 0x7a, 0x6a, 0x65, 0x33, 0x50, 0x39, 0x31, 0x7a, 0x6d, 0x57, + 0x6a, 0x4e, 0x62, 0x4b, 0x6b, 0x69, 0x30, 0x6d, 0x75, 0x30, 0x68, 0x47, + 0x46, 0x53, 0x6b, 0x47, 0x4c, 0x6d, 0x7a, 0x68, 0x4c, 0x31, 0x5a, 0x30, + 0x46, 0x63, 0x38, 0x33, 0x67, 0x78, 0x46, 0x42, 0x36, 0x59, 0x68, 0x54, + 0x51, 0x4f, 0x64, 0x63, 0x33, 0x66, 0x57, 0x61, 0x62, 0x79, 0x4b, 0x4b, + 0x44, 0x39, 0x7a, 0x36, 0x72, 0x5a, 0x63, 0x4f, 0x4c, 0x53, 0x57, 0x34, + 0x77, 0x37, 0x55, 0x77, 0x49, 0x44, 0x41, 0x51, 0x41, 0x42, 0x6f, 0x31, + 0x41, 0x77, 0x54, 0x6a, 0x41, 0x64, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, + 0x34, 0x45, 0x46, 0x67, 0x51, 0x55, 0x66, 0x49, 0x44, 0x53, 0x77, 0x6e, + 0x79, 0x4f, 0x4b, 0x49, 0x44, 0x55, 0x4a, 0x46, 0x41, 0x59, 0x75, 0x41, + 0x30, 0x51, 0x51, 0x6d, 0x65, 0x53, 0x74, 0x2b, 0x67, 0x77, 0x48, 0x77, + 0x59, 0x44, 0x56, 0x52, 0x30, 0x6a, 0x42, 0x42, 0x67, 0x77, 0x46, 0x6f, + 0x41, 0x55, 0x66, 0x49, 0x44, 0x53, 0x77, 0x6e, 0x79, 0x4f, 0x4b, 0x49, + 0x44, 0x55, 0x4a, 0x46, 0x41, 0x59, 0x75, 0x41, 0x30, 0x51, 0x51, 0x6d, + 0x65, 0x53, 0x74, 0x2b, 0x67, 0x77, 0x44, 0x41, 0x59, 0x44, 0x56, 0x52, + 0x30, 0x54, 0x42, 0x41, 0x55, 0x77, 0x41, 0x77, 0x45, 0x42, 0x2f, 0x7a, + 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47, 0x39, 0x77, + 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x41, 0x4f, 0x43, 0x41, 0x51, + 0x45, 0x41, 0x4b, 0x55, 0x77, 0x39, 0x4c, 0x31, 0x50, 0x57, 0x42, 0x42, + 0x44, 0x2f, 0x74, 0x48, 0x44, 0x53, 0x61, 0x74, 0x6e, 0x57, 0x70, 0x36, + 0x55, 0x4e, 0x6e, 0x37, 0x52, 0x74, 0x73, 0x4d, 0x75, 0x2b, 0x62, 0x4a, + 0x6d, 0x35, 0x62, 0x6a, 0x30, 0x31, 0x70, 0x43, 0x37, 0x6a, 0x58, 0x35, + 0x67, 0x4b, 0x6d, 0x37, 0x35, 0x77, 0x55, 0x4b, 0x4f, 0x44, 0x72, 0x55, + 0x6e, 0x47, 0x41, 0x73, 0x7a, 0x52, 0x6f, 0x52, 0x75, 0x6a, 0x73, 0x79, + 0x4a, 0x4a, 0x72, 0x47, 0x4b, 0x7a, 0x62, 0x64, 0x53, 0x68, 0x4c, 0x6c, + 0x49, 0x35, 0x48, 0x4c, 0x56, 0x68, 0x39, 0x63, 0x52, 0x31, 0x74, 0x70, + 0x72, 0x33, 0x73, 0x2f, 0x39, 0x57, 0x36, 0x44, 0x42, 0x6b, 0x41, 0x4e, + 0x50, 0x68, 0x30, 0x43, 0x6c, 0x77, 0x48, 0x37, 0x74, 0x33, 0x35, 0x64, + 0x74, 0x30, 0x43, 0x77, 0x59, 0x48, 0x38, 0x61, 0x63, 0x7a, 0x37, 0x66, + 0x71, 0x52, 0x66, 0x54, 0x6a, 0x4a, 0x66, 0x54, 0x63, 0x63, 0x6a, 0x6e, + 0x66, 0x50, 0x42, 0x35, 0x45, 0x46, 0x63, 0x70, 0x4b, 0x49, 0x50, 0x76, + 0x33, 0x6c, 0x64, 0x38, 0x4c, 0x62, 0x52, 0x2f, 0x59, 0x6c, 0x43, 0x57, + 0x62, 0x72, 0x66, 0x55, 0x72, 0x7a, 0x51, 0x4d, 0x2f, 0x4b, 0x31, 0x46, + 0x64, 0x5a, 0x61, 0x4b, 0x37, 0x65, 0x6c, 0x48, 0x2f, 0x64, 0x72, 0x52, + 0x73, 0x2b, 0x44, 0x45, 0x42, 0x46, 0x4c, 0x70, 0x33, 0x4b, 0x71, 0x77, + 0x33, 0x62, 0x57, 0x74, 0x34, 0x7a, 0x30, 0x36, 0x41, 0x56, 0x31, 0x72, + 0x51, 0x56, 0x6d, 0x59, 0x32, 0x79, 0x61, 0x6b, 0x61, 0x46, 0x69, 0x70, + 0x70, 0x62, 0x72, 0x73, 0x72, 0x64, 0x77, 0x49, 0x4c, 0x36, 0x75, 0x4f, + 0x71, 0x4f, 0x2b, 0x53, 0x66, 0x52, 0x55, 0x62, 0x4d, 0x5a, 0x67, 0x31, + 0x34, 0x4b, 0x6b, 0x38, 0x57, 0x76, 0x61, 0x42, 0x67, 0x6d, 0x34, 0x6c, + 0x36, 0x61, 0x56, 0x36, 0x64, 0x73, 0x6c, 0x6e, 0x79, 0x62, 0x66, 0x6f, + 0x4a, 0x6b, 0x73, 0x6e, 0x73, 0x42, 0x73, 0x6d, 0x45, 0x69, 0x65, 0x39, + 0x6e, 0x6d, 0x54, 0x50, 0x69, 0x55, 0x39, 0x5a, 0x2b, 0x63, 0x50, 0x75, + 0x4e, 0x2f, 0x75, 0x6e, 0x6a, 0x4d, 0x42, 0x70, 0x34, 0x50, 0x6e, 0x43, + 0x54, 0x42, 0x4b, 0x70, 0x63, 0x39, 0x6c, 0x2b, 0x50, 0x4a, 0x71, 0x47, + 0x71, 0x38, 0x48, 0x46, 0x6e, 0x42, 0x6c, 0x44, 0x42, 0x4b, 0x77, 0x2f, + 0x4e, 0x49, 0x38, 0x45, 0x65, 0x70, 0x73, 0x51, 0x3d, 0x3d, 0x22, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x6d, 0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x75, 0x72, + 0x6c, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, + 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, 0x2e, 0x70, 0x61, + 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x6e, 0x65, + 0x2d, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x2d, 0x6c, 0x6f, 0x67, 0x69, 0x6e, + 0x2f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x22, 0x30, 0x30, + 0x43, 0x34, 0x39, 0x36, 0x45, 0x31, 0x41, 0x41, 0x41, 0x34, 0x33, 0x39, + 0x41, 0x34, 0x42, 0x43, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x4d, + 0x49, 0x49, 0x44, 0x6f, 0x54, 0x43, 0x43, 0x41, 0x6f, 0x6d, 0x67, 0x41, + 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4a, 0x41, 0x4d, 0x53, 0x57, 0x34, + 0x61, 0x71, 0x6b, 0x4f, 0x61, 0x53, 0x38, 0x4d, 0x41, 0x30, 0x47, 0x43, + 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43, + 0x77, 0x55, 0x41, 0x4d, 0x47, 0x63, 0x78, 0x43, 0x7a, 0x41, 0x4a, 0x42, + 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, 0x41, 0x6c, 0x56, 0x54, 0x4d, + 0x52, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, 0x56, 0x51, 0x51, 0x49, 0x44, + 0x41, 0x68, 0x4a, 0x62, 0x47, 0x78, 0x70, 0x62, 0x6d, 0x39, 0x70, 0x63, + 0x7a, 0x45, 0x51, 0x4d, 0x41, 0x34, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, + 0x77, 0x77, 0x48, 0x51, 0x32, 0x68, 0x70, 0x59, 0x32, 0x46, 0x6e, 0x62, + 0x7a, 0x45, 0x53, 0x4d, 0x42, 0x41, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, + 0x67, 0x77, 0x4a, 0x51, 0x6e, 0x4a, 0x68, 0x61, 0x57, 0x35, 0x30, 0x63, + 0x6d, 0x56, 0x6c, 0x4d, 0x52, 0x38, 0x77, 0x48, 0x51, 0x59, 0x44, 0x56, + 0x51, 0x51, 0x4c, 0x44, 0x42, 0x5a, 0x54, 0x59, 0x57, 0x35, 0x6b, 0x59, + 0x6d, 0x39, 0x34, 0x49, 0x45, 0x4a, 0x79, 0x62, 0x33, 0x64, 0x7a, 0x5a, + 0x58, 0x49, 0x67, 0x55, 0x33, 0x64, 0x70, 0x64, 0x47, 0x4e, 0x6f, 0x4d, + 0x42, 0x34, 0x58, 0x44, 0x54, 0x45, 0x31, 0x4d, 0x44, 0x51, 0x78, 0x4d, + 0x44, 0x45, 0x34, 0x4d, 0x54, 0x4d, 0x78, 0x4f, 0x56, 0x6f, 0x58, 0x44, + 0x54, 0x49, 0x77, 0x4d, 0x44, 0x51, 0x78, 0x4d, 0x7a, 0x45, 0x34, 0x4d, + 0x54, 0x4d, 0x78, 0x4f, 0x56, 0x6f, 0x77, 0x5a, 0x7a, 0x45, 0x4c, 0x4d, + 0x41, 0x6b, 0x47, 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56, + 0x56, 0x4d, 0x78, 0x45, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4e, 0x56, 0x42, + 0x41, 0x67, 0x4d, 0x43, 0x45, 0x6c, 0x73, 0x62, 0x47, 0x6c, 0x75, 0x62, + 0x32, 0x6c, 0x7a, 0x4d, 0x52, 0x41, 0x77, 0x44, 0x67, 0x59, 0x44, 0x56, + 0x51, 0x51, 0x48, 0x44, 0x41, 0x64, 0x44, 0x61, 0x47, 0x6c, 0x6a, 0x59, + 0x57, 0x64, 0x76, 0x4d, 0x52, 0x49, 0x77, 0x45, 0x41, 0x59, 0x44, 0x56, + 0x51, 0x51, 0x4b, 0x44, 0x41, 0x6c, 0x43, 0x63, 0x6d, 0x46, 0x70, 0x62, + 0x6e, 0x52, 0x79, 0x5a, 0x57, 0x55, 0x78, 0x48, 0x7a, 0x41, 0x64, 0x42, + 0x67, 0x4e, 0x56, 0x42, 0x41, 0x73, 0x4d, 0x46, 0x6c, 0x4e, 0x68, 0x62, + 0x6d, 0x52, 0x69, 0x62, 0x33, 0x67, 0x67, 0x51, 0x6e, 0x4a, 0x76, 0x64, + 0x33, 0x4e, 0x6c, 0x63, 0x69, 0x42, 0x54, 0x64, 0x32, 0x6c, 0x30, 0x59, + 0x32, 0x67, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4d, 0x41, 0x30, 0x47, 0x43, + 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x41, + 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, 0x67, + 0x67, 0x45, 0x4b, 0x41, 0x6f, 0x49, 0x42, 0x41, 0x51, 0x44, 0x56, 0x6a, + 0x6e, 0x43, 0x34, 0x37, 0x42, 0x75, 0x55, 0x6d, 0x30, 0x50, 0x4b, 0x69, + 0x35, 0x73, 0x55, 0x53, 0x69, 0x30, 0x32, 0x77, 0x47, 0x4c, 0x38, 0x7a, + 0x71, 0x56, 0x6a, 0x52, 0x72, 0x64, 0x74, 0x74, 0x34, 0x59, 0x44, 0x79, + 0x50, 0x51, 0x64, 0x45, 0x4c, 0x6c, 0x69, 0x74, 0x66, 0x76, 0x34, 0x33, + 0x31, 0x59, 0x37, 0x48, 0x70, 0x54, 0x36, 0x7a, 0x2f, 0x58, 0x75, 0x73, + 0x75, 0x39, 0x2f, 0x32, 0x6d, 0x6a, 0x6c, 0x63, 0x76, 0x79, 0x6b, 0x47, + 0x4f, 0x31, 0x2b, 0x6f, 0x6b, 0x6d, 0x36, 0x56, 0x44, 0x69, 0x4e, 0x49, + 0x61, 0x48, 0x4d, 0x65, 0x65, 0x7a, 0x37, 0x56, 0x76, 0x33, 0x54, 0x6f, + 0x37, 0x4a, 0x33, 0x5a, 0x43, 0x4e, 0x52, 0x2f, 0x57, 0x5a, 0x44, 0x46, + 0x79, 0x7a, 0x62, 0x59, 0x37, 0x6c, 0x6e, 0x69, 0x77, 0x49, 0x53, 0x53, + 0x6f, 0x4c, 0x4d, 0x68, 0x37, 0x4d, 0x46, 0x36, 0x66, 0x73, 0x4f, 0x4b, + 0x59, 0x76, 0x63, 0x33, 0x6e, 0x41, 0x52, 0x65, 0x7a, 0x30, 0x51, 0x73, + 0x31, 0x4a, 0x70, 0x2b, 0x66, 0x58, 0x2b, 0x30, 0x44, 0x4b, 0x43, 0x48, + 0x39, 0x32, 0x36, 0x71, 0x34, 0x5a, 0x33, 0x4f, 0x57, 0x59, 0x71, 0x33, + 0x4e, 0x48, 0x50, 0x72, 0x41, 0x79, 0x38, 0x45, 0x32, 0x51, 0x4d, 0x7a, + 0x63, 0x47, 0x36, 0x38, 0x58, 0x4a, 0x65, 0x5a, 0x47, 0x59, 0x45, 0x66, + 0x56, 0x75, 0x75, 0x37, 0x53, 0x61, 0x64, 0x48, 0x48, 0x6b, 0x70, 0x76, + 0x76, 0x53, 0x4e, 0x32, 0x4b, 0x53, 0x48, 0x35, 0x64, 0x4e, 0x48, 0x78, + 0x43, 0x6b, 0x6e, 0x6d, 0x31, 0x4b, 0x70, 0x57, 0x34, 0x49, 0x6f, 0x47, + 0x67, 0x75, 0x58, 0x65, 0x70, 0x55, 0x6c, 0x6c, 0x64, 0x6d, 0x66, 0x31, + 0x4b, 0x6f, 0x72, 0x52, 0x58, 0x30, 0x44, 0x4f, 0x51, 0x71, 0x2f, 0x37, + 0x35, 0x30, 0x58, 0x4f, 0x50, 0x30, 0x72, 0x76, 0x68, 0x2b, 0x78, 0x44, + 0x48, 0x37, 0x45, 0x5a, 0x53, 0x4c, 0x67, 0x63, 0x43, 0x69, 0x38, 0x31, + 0x30, 0x6f, 0x74, 0x7a, 0x50, 0x34, 0x63, 0x50, 0x67, 0x2f, 0x4d, 0x35, + 0x46, 0x79, 0x6a, 0x36, 0x6c, 0x50, 0x41, 0x6a, 0x34, 0x54, 0x5a, 0x41, + 0x72, 0x46, 0x76, 0x71, 0x55, 0x4f, 0x4b, 0x6e, 0x41, 0x76, 0x74, 0x72, + 0x69, 0x39, 0x4c, 0x45, 0x41, 0x55, 0x50, 0x2b, 0x2f, 0x6c, 0x61, 0x42, + 0x32, 0x6d, 0x64, 0x4c, 0x36, 0x36, 0x38, 0x61, 0x75, 0x39, 0x6b, 0x53, + 0x56, 0x37, 0x68, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, 0x55, + 0x44, 0x42, 0x4f, 0x4d, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, 0x44, + 0x67, 0x51, 0x57, 0x42, 0x42, 0x53, 0x31, 0x4b, 0x34, 0x32, 0x42, 0x43, + 0x49, 0x55, 0x4c, 0x5a, 0x2f, 0x51, 0x46, 0x6b, 0x4a, 0x51, 0x6c, 0x6a, + 0x2b, 0x4d, 0x6e, 0x63, 0x37, 0x61, 0x47, 0x36, 0x6a, 0x41, 0x66, 0x42, + 0x67, 0x4e, 0x56, 0x48, 0x53, 0x4d, 0x45, 0x47, 0x44, 0x41, 0x57, 0x67, + 0x42, 0x53, 0x31, 0x4b, 0x34, 0x32, 0x42, 0x43, 0x49, 0x55, 0x4c, 0x5a, + 0x2f, 0x51, 0x46, 0x6b, 0x4a, 0x51, 0x6c, 0x6a, 0x2b, 0x4d, 0x6e, 0x63, + 0x37, 0x61, 0x47, 0x36, 0x6a, 0x41, 0x4d, 0x42, 0x67, 0x4e, 0x56, 0x48, + 0x52, 0x4d, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2f, 0x4d, + 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, + 0x51, 0x45, 0x42, 0x43, 0x77, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x41, + 0x51, 0x42, 0x45, 0x64, 0x75, 0x45, 0x78, 0x58, 0x62, 0x79, 0x4d, 0x74, + 0x63, 0x6d, 0x6b, 0x36, 0x6e, 0x6f, 0x4c, 0x64, 0x6f, 0x4a, 0x64, 0x46, + 0x74, 0x6d, 0x63, 0x4c, 0x50, 0x7a, 0x43, 0x4f, 0x6d, 0x52, 0x31, 0x6b, + 0x31, 0x68, 0x47, 0x55, 0x44, 0x68, 0x34, 0x31, 0x51, 0x57, 0x4a, 0x67, + 0x46, 0x63, 0x75, 0x5a, 0x6c, 0x4d, 0x32, 0x35, 0x46, 0x2f, 0x71, 0x56, + 0x4b, 0x58, 0x53, 0x7a, 0x4c, 0x42, 0x52, 0x6f, 0x63, 0x31, 0x73, 0x73, + 0x45, 0x65, 0x55, 0x5a, 0x6c, 0x31, 0x41, 0x47, 0x79, 0x68, 0x4f, 0x4f, + 0x34, 0x39, 0x62, 0x2f, 0x4d, 0x66, 0x45, 0x50, 0x6f, 0x2f, 0x79, 0x56, + 0x77, 0x63, 0x7a, 0x32, 0x35, 0x34, 0x6f, 0x39, 0x50, 0x6d, 0x34, 0x45, + 0x39, 0x43, 0x76, 0x64, 0x71, 0x64, 0x4f, 0x38, 0x6d, 0x50, 0x70, 0x43, + 0x72, 0x45, 0x2f, 0x50, 0x6a, 0x72, 0x2b, 0x37, 0x54, 0x4e, 0x4b, 0x79, + 0x4d, 0x56, 0x73, 0x6b, 0x74, 0x6f, 0x4e, 0x33, 0x42, 0x35, 0x56, 0x35, + 0x4b, 0x31, 0x34, 0x2b, 0x47, 0x51, 0x56, 0x4f, 0x69, 0x53, 0x48, 0x67, + 0x65, 0x73, 0x45, 0x51, 0x61, 0x59, 0x71, 0x39, 0x63, 0x79, 0x78, 0x55, + 0x63, 0x6c, 0x4d, 0x73, 0x31, 0x51, 0x7a, 0x79, 0x4e, 0x48, 0x53, 0x65, + 0x33, 0x67, 0x44, 0x4e, 0x34, 0x31, 0x46, 0x46, 0x44, 0x58, 0x69, 0x45, + 0x37, 0x6b, 0x6a, 0x31, 0x68, 0x38, 0x6f, 0x6f, 0x34, 0x4d, 0x68, 0x48, + 0x37, 0x77, 0x63, 0x56, 0x76, 0x2b, 0x39, 0x6f, 0x6c, 0x4f, 0x57, 0x45, + 0x74, 0x61, 0x77, 0x47, 0x56, 0x78, 0x53, 0x69, 0x2f, 0x55, 0x39, 0x4b, + 0x56, 0x54, 0x6d, 0x4e, 0x35, 0x53, 0x68, 0x44, 0x4a, 0x67, 0x54, 0x77, + 0x75, 0x4d, 0x37, 0x34, 0x61, 0x53, 0x6e, 0x52, 0x77, 0x77, 0x45, 0x6a, + 0x32, 0x62, 0x58, 0x45, 0x61, 0x44, 0x4d, 0x62, 0x55, 0x58, 0x59, 0x58, + 0x44, 0x2f, 0x70, 0x34, 0x53, 0x50, 0x42, 0x71, 0x32, 0x61, 0x33, 0x65, + 0x63, 0x76, 0x65, 0x6c, 0x7a, 0x73, 0x59, 0x70, 0x57, 0x64, 0x77, 0x79, + 0x46, 0x37, 0x69, 0x58, 0x6f, 0x57, 0x43, 0x72, 0x50, 0x56, 0x4c, 0x4d, + 0x34, 0x36, 0x44, 0x38, 0x4d, 0x34, 0x50, 0x65, 0x65, 0x6e, 0x54, 0x7a, + 0x71, 0x36, 0x65, 0x66, 0x6e, 0x58, 0x34, 0x6d, 0x7a, 0x67, 0x53, 0x2f, + 0x66, 0x4f, 0x71, 0x49, 0x39, 0x67, 0x72, 0x6a, 0x53, 0x32, 0x52, 0x38, + 0x62, 0x74, 0x77, 0x39, 0x49, 0x64, 0x7a, 0x22, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x76, + 0x65, 0x6c, 0x6f, 0x70, 0x22, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x75, 0x72, + 0x6c, 0x22, 0x3a, 0x20, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, + 0x2f, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x67, + 0x69, 0x6e, 0x67, 0x2e, 0x62, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x72, 0x65, + 0x65, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x6f, 0x6e, 0x65, 0x2d, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x2d, + 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x2f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x65, + 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, + 0x3a, 0x20, 0x22, 0x30, 0x30, 0x43, 0x39, 0x36, 0x46, 0x30, 0x39, 0x32, + 0x45, 0x31, 0x34, 0x42, 0x35, 0x31, 0x45, 0x43, 0x46, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x22, 0x3a, 0x20, 0x22, 0x4d, 0x49, 0x49, 0x44, 0x4f, 0x7a, 0x43, 0x43, + 0x41, 0x69, 0x4f, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x4a, + 0x41, 0x4d, 0x6c, 0x76, 0x43, 0x53, 0x34, 0x55, 0x74, 0x52, 0x37, 0x50, + 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, + 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x4d, 0x44, 0x51, 0x78, + 0x43, 0x7a, 0x41, 0x4a, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x59, 0x54, + 0x41, 0x6c, 0x56, 0x54, 0x4d, 0x52, 0x45, 0x77, 0x44, 0x77, 0x59, 0x44, + 0x56, 0x51, 0x51, 0x49, 0x44, 0x41, 0x68, 0x4a, 0x62, 0x47, 0x78, 0x70, + 0x62, 0x6d, 0x39, 0x70, 0x63, 0x7a, 0x45, 0x53, 0x4d, 0x42, 0x41, 0x47, + 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77, 0x4a, 0x51, 0x6e, 0x4a, 0x68, + 0x61, 0x57, 0x35, 0x30, 0x63, 0x6d, 0x56, 0x6c, 0x4d, 0x42, 0x34, 0x58, + 0x44, 0x54, 0x45, 0x31, 0x4d, 0x44, 0x4d, 0x79, 0x4d, 0x44, 0x41, 0x78, + 0x4d, 0x54, 0x63, 0x79, 0x4d, 0x56, 0x6f, 0x58, 0x44, 0x54, 0x45, 0x32, + 0x4d, 0x44, 0x4d, 0x78, 0x4f, 0x54, 0x41, 0x78, 0x4d, 0x54, 0x63, 0x79, + 0x4d, 0x56, 0x6f, 0x77, 0x4e, 0x44, 0x45, 0x4c, 0x4d, 0x41, 0x6b, 0x47, + 0x41, 0x31, 0x55, 0x45, 0x42, 0x68, 0x4d, 0x43, 0x56, 0x56, 0x4d, 0x78, + 0x45, 0x54, 0x41, 0x50, 0x42, 0x67, 0x4e, 0x56, 0x42, 0x41, 0x67, 0x4d, + 0x43, 0x45, 0x6c, 0x73, 0x62, 0x47, 0x6c, 0x75, 0x62, 0x32, 0x6c, 0x7a, + 0x4d, 0x52, 0x49, 0x77, 0x45, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x4b, + 0x44, 0x41, 0x6c, 0x43, 0x63, 0x6d, 0x46, 0x70, 0x62, 0x6e, 0x52, 0x79, + 0x5a, 0x57, 0x55, 0x77, 0x67, 0x67, 0x45, 0x69, 0x4d, 0x41, 0x30, 0x47, + 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, + 0x41, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, 0x44, 0x77, 0x41, 0x77, + 0x67, 0x67, 0x45, 0x4b, 0x41, 0x6f, 0x49, 0x42, 0x41, 0x51, 0x44, 0x66, + 0x43, 0x52, 0x68, 0x4f, 0x47, 0x65, 0x4d, 0x6a, 0x34, 0x63, 0x69, 0x35, + 0x42, 0x62, 0x62, 0x73, 0x2f, 0x78, 0x30, 0x47, 0x2b, 0x50, 0x6b, 0x62, + 0x65, 0x4c, 0x37, 0x69, 0x47, 0x45, 0x73, 0x58, 0x35, 0x55, 0x57, 0x51, + 0x65, 0x41, 0x38, 0x6f, 0x43, 0x57, 0x55, 0x38, 0x6a, 0x70, 0x69, 0x70, + 0x46, 0x54, 0x43, 0x32, 0x37, 0x31, 0x51, 0x30, 0x66, 0x35, 0x42, 0x51, + 0x7a, 0x58, 0x43, 0x4e, 0x38, 0x4c, 0x34, 0x4c, 0x6e, 0x77, 0x47, 0x76, + 0x74, 0x6d, 0x32, 0x63, 0x67, 0x41, 0x45, 0x69, 0x76, 0x53, 0x42, 0x4f, + 0x44, 0x6f, 0x37, 0x58, 0x48, 0x73, 0x6d, 0x78, 0x72, 0x46, 0x6a, 0x4b, + 0x64, 0x51, 0x78, 0x31, 0x53, 0x37, 0x46, 0x49, 0x75, 0x46, 0x52, 0x4b, + 0x4f, 0x31, 0x38, 0x55, 0x66, 0x38, 0x72, 0x49, 0x47, 0x6d, 0x5a, 0x48, + 0x69, 0x4a, 0x66, 0x68, 0x43, 0x62, 0x55, 0x45, 0x47, 0x69, 0x6c, 0x70, + 0x77, 0x4d, 0x74, 0x37, 0x68, 0x55, 0x4d, 0x6a, 0x6a, 0x76, 0x32, 0x58, + 0x44, 0x75, 0x66, 0x50, 0x43, 0x4d, 0x72, 0x4a, 0x38, 0x59, 0x6e, 0x32, + 0x79, 0x2f, 0x79, 0x44, 0x69, 0x35, 0x6e, 0x68, 0x73, 0x37, 0x55, 0x73, + 0x46, 0x68, 0x52, 0x4f, 0x6d, 0x39, 0x6f, 0x49, 0x32, 0x50, 0x79, 0x69, + 0x4a, 0x58, 0x30, 0x31, 0x79, 0x52, 0x32, 0x61, 0x67, 0x38, 0x63, 0x50, + 0x42, 0x62, 0x35, 0x41, 0x68, 0x6c, 0x77, 0x6d, 0x6a, 0x31, 0x79, 0x4d, + 0x57, 0x6d, 0x53, 0x75, 0x48, 0x56, 0x6e, 0x55, 0x4e, 0x38, 0x54, 0x30, + 0x72, 0x6a, 0x49, 0x58, 0x79, 0x72, 0x42, 0x68, 0x78, 0x54, 0x41, 0x6b, + 0x33, 0x6f, 0x6d, 0x51, 0x6b, 0x51, 0x64, 0x48, 0x4b, 0x6a, 0x32, 0x77, + 0x38, 0x61, 0x66, 0x64, 0x72, 0x41, 0x63, 0x4e, 0x55, 0x47, 0x69, 0x34, + 0x79, 0x55, 0x2f, 0x61, 0x35, 0x2f, 0x70, 0x6d, 0x62, 0x38, 0x74, 0x5a, + 0x70, 0x41, 0x61, 0x37, 0x33, 0x4f, 0x5a, 0x56, 0x64, 0x4f, 0x45, 0x51, + 0x65, 0x70, 0x4a, 0x41, 0x41, 0x49, 0x52, 0x57, 0x58, 0x65, 0x53, 0x32, + 0x42, 0x64, 0x4b, 0x54, 0x6b, 0x68, 0x66, 0x52, 0x4a, 0x63, 0x37, 0x57, + 0x45, 0x49, 0x6c, 0x62, 0x69, 0x2b, 0x39, 0x61, 0x32, 0x4f, 0x64, 0x74, + 0x4d, 0x33, 0x4f, 0x6b, 0x49, 0x73, 0x2b, 0x72, 0x5a, 0x45, 0x37, 0x2b, + 0x57, 0x56, 0x54, 0x38, 0x58, 0x51, 0x6f, 0x69, 0x4c, 0x78, 0x70, 0x55, + 0x64, 0x2f, 0x77, 0x4e, 0x41, 0x67, 0x4d, 0x42, 0x41, 0x41, 0x47, 0x6a, + 0x55, 0x44, 0x42, 0x4f, 0x4d, 0x42, 0x30, 0x47, 0x41, 0x31, 0x55, 0x64, + 0x44, 0x67, 0x51, 0x57, 0x42, 0x42, 0x51, 0x68, 0x62, 0x4a, 0x38, 0x44, + 0x74, 0x75, 0x4b, 0x46, 0x68, 0x47, 0x54, 0x73, 0x72, 0x76, 0x5a, 0x34, + 0x31, 0x56, 0x77, 0x35, 0x6a, 0x59, 0x62, 0x6d, 0x61, 0x7a, 0x41, 0x66, + 0x42, 0x67, 0x4e, 0x56, 0x48, 0x53, 0x4d, 0x45, 0x47, 0x44, 0x41, 0x57, + 0x67, 0x42, 0x51, 0x68, 0x62, 0x4a, 0x38, 0x44, 0x74, 0x75, 0x4b, 0x46, + 0x68, 0x47, 0x54, 0x73, 0x72, 0x76, 0x5a, 0x34, 0x31, 0x56, 0x77, 0x35, + 0x6a, 0x59, 0x62, 0x6d, 0x61, 0x7a, 0x41, 0x4d, 0x42, 0x67, 0x4e, 0x56, + 0x48, 0x52, 0x4d, 0x45, 0x42, 0x54, 0x41, 0x44, 0x41, 0x51, 0x48, 0x2f, + 0x4d, 0x41, 0x30, 0x47, 0x43, 0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, + 0x44, 0x51, 0x45, 0x42, 0x42, 0x51, 0x55, 0x41, 0x41, 0x34, 0x49, 0x42, + 0x41, 0x51, 0x41, 0x52, 0x67, 0x32, 0x77, 0x6a, 0x68, 0x4a, 0x61, 0x6e, + 0x68, 0x4b, 0x75, 0x31, 0x62, 0x77, 0x36, 0x33, 0x2b, 0x58, 0x66, 0x6a, + 0x32, 0x35, 0x4f, 0x55, 0x61, 0x30, 0x32, 0x6a, 0x4b, 0x2b, 0x69, 0x34, + 0x76, 0x68, 0x6b, 0x57, 0x65, 0x75, 0x43, 0x47, 0x64, 0x35, 0x2f, 0x6b, + 0x78, 0x41, 0x31, 0x64, 0x5a, 0x4d, 0x6a, 0x42, 0x66, 0x53, 0x4d, 0x78, + 0x68, 0x34, 0x38, 0x34, 0x78, 0x42, 0x70, 0x61, 0x71, 0x52, 0x49, 0x4f, + 0x48, 0x76, 0x5a, 0x6d, 0x52, 0x70, 0x4b, 0x63, 0x78, 0x43, 0x67, 0x63, + 0x69, 0x38, 0x78, 0x52, 0x62, 0x62, 0x4a, 0x69, 0x61, 0x58, 0x72, 0x62, + 0x31, 0x76, 0x49, 0x65, 0x50, 0x54, 0x54, 0x69, 0x34, 0x6c, 0x66, 0x55, + 0x36, 0x63, 0x70, 0x66, 0x73, 0x6e, 0x6a, 0x4d, 0x46, 0x43, 0x48, 0x44, + 0x6b, 0x38, 0x45, 0x2f, 0x30, 0x41, 0x78, 0x49, 0x66, 0x4f, 0x70, 0x51, + 0x30, 0x42, 0x53, 0x4a, 0x59, 0x33, 0x35, 0x57, 0x71, 0x42, 0x34, 0x35, + 0x78, 0x61, 0x49, 0x57, 0x42, 0x41, 0x59, 0x38, 0x6c, 0x51, 0x32, 0x70, + 0x4e, 0x66, 0x69, 0x50, 0x79, 0x4b, 0x34, 0x6b, 0x7a, 0x61, 0x6a, 0x53, + 0x4f, 0x67, 0x2b, 0x6b, 0x62, 0x45, 0x4b, 0x4c, 0x6d, 0x41, 0x30, 0x75, + 0x64, 0x59, 0x79, 0x38, 0x74, 0x73, 0x79, 0x64, 0x74, 0x2b, 0x38, 0x38, + 0x2b, 0x52, 0x38, 0x38, 0x72, 0x59, 0x4b, 0x74, 0x34, 0x71, 0x44, 0x42, + 0x6f, 0x2b, 0x5a, 0x35, 0x7a, 0x67, 0x4a, 0x32, 0x66, 0x5a, 0x76, 0x62, + 0x41, 0x70, 0x39, 0x39, 0x63, 0x42, 0x41, 0x53, 0x48, 0x71, 0x4d, 0x43, + 0x6f, 0x55, 0x6f, 0x50, 0x62, 0x39, 0x36, 0x59, 0x57, 0x45, 0x68, 0x61, + 0x57, 0x68, 0x6a, 0x41, 0x72, 0x56, 0x47, 0x7a, 0x67, 0x65, 0x76, 0x70, + 0x6f, 0x70, 0x4b, 0x41, 0x39, 0x61, 0x4f, 0x41, 0x46, 0x64, 0x6e, 0x64, + 0x50, 0x4b, 0x4c, 0x62, 0x65, 0x36, 0x79, 0x32, 0x39, 0x62, 0x62, 0x66, + 0x4c, 0x66, 0x51, 0x71, 0x61, 0x74, 0x30, 0x42, 0x31, 0x66, 0x56, 0x6d, + 0x75, 0x74, 0x43, 0x49, 0x48, 0x47, 0x49, 0x58, 0x74, 0x73, 0x50, 0x48, + 0x51, 0x44, 0x65, 0x2f, 0x63, 0x58, 0x4a, 0x74, 0x6f, 0x4a, 0x6b, 0x37, + 0x48, 0x6d, 0x44, 0x30, 0x38, 0x2b, 0x2b, 0x43, 0x39, 0x59, 0x76, 0x6a, + 0x78, 0x6c, 0x53, 0x69, 0x38, 0x6a, 0x78, 0x4c, 0x62, 0x35, 0x6e, 0x49, + 0x41, 0x30, 0x51, 0x47, 0x49, 0x30, 0x79, 0x6a, 0x22, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x6f, 0x75, 0x74, + 0x5f, 0x72, 0x65, 0x63, 0x69, 0x70, 0x65, 0x73, 0x5f, 0x69, 0x6e, 0x5f, + 0x64, 0x65, 0x63, 0x72, 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x70, + 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x77, 0x61, 0x6c, + 0x6c, 0x65, 0x74, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, + 0x3a, 0x20, 0x22, 0x33, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, + 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x73, 0x22, 0x3a, 0x20, + 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x64, 0x61, 0x5f, 0x44, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, 0x41, + 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, 0x42, 0x45, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, + 0x5f, 0x43, 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, 0x44, 0x45, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x64, 0x65, 0x5f, 0x44, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, 0x4c, 0x55, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x41, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x41, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x41, 0x54, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x41, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x42, 0x45, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x42, 0x47, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x42, + 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x42, 0x52, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x43, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x43, 0x48, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x43, 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x43, 0x5a, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x44, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x44, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x44, 0x5a, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x45, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x45, 0x53, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x46, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x46, + 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x47, 0x42, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x47, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x48, 0x4b, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x48, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x49, 0x45, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x49, 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x49, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4a, 0x4f, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x4a, 0x50, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4b, 0x57, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x4b, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4c, + 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4c, 0x55, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x4c, 0x56, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4d, 0x41, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x4d, 0x58, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4d, 0x59, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4e, 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x4e, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4e, 0x5a, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x4f, 0x4d, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x50, 0x48, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x50, 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x50, + 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x51, 0x41, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x52, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x52, 0x55, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x53, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x53, 0x45, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x53, 0x47, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x53, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x53, 0x4b, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x54, 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x54, 0x52, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x55, 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x59, + 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x41, 0x45, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, + 0x5f, 0x41, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x42, 0x48, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x73, 0x5f, 0x43, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x44, 0x5a, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x73, 0x5f, 0x45, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, + 0x45, 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x46, 0x49, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x73, 0x5f, 0x47, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x48, 0x55, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x73, 0x5f, 0x4a, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4b, + 0x57, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4b, 0x5a, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, + 0x5f, 0x4c, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4c, 0x55, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x73, 0x5f, 0x4c, 0x56, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4d, 0x41, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4d, 0x58, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, + 0x4e, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4f, 0x4d, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x73, 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x51, 0x41, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x73, 0x5f, 0x52, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x53, + 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x53, 0x49, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, + 0x5f, 0x53, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x54, 0x4e, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x73, 0x5f, 0x55, 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x59, 0x45, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x66, 0x72, 0x5f, 0x41, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, + 0x42, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x42, 0x48, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, + 0x72, 0x5f, 0x43, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x43, 0x48, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x66, 0x72, 0x5f, 0x43, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x44, + 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x45, 0x45, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, + 0x5f, 0x46, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x46, 0x52, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x66, 0x72, 0x5f, 0x47, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x48, 0x55, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4a, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, + 0x4b, 0x57, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4b, 0x5a, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, + 0x72, 0x5f, 0x4c, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4c, 0x55, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x66, 0x72, 0x5f, 0x4c, 0x56, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4d, + 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4e, 0x5a, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, + 0x5f, 0x4f, 0x4d, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x50, 0x54, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x66, 0x72, 0x5f, 0x51, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x52, 0x4f, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x66, 0x72, 0x5f, 0x53, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, + 0x53, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x53, 0x4b, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, + 0x72, 0x5f, 0x54, 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x55, 0x53, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x66, 0x72, 0x5f, 0x59, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x74, 0x5f, 0x49, + 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x69, 0x77, 0x5f, 0x49, 0x4c, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6a, 0x61, + 0x5f, 0x4a, 0x50, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x62, 0x5f, 0x4e, 0x4f, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x6e, 0x6c, 0x5f, 0x42, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x6c, 0x5f, 0x4e, 0x4c, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x6e, 0x6f, 0x5f, 0x4e, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x6c, 0x5f, + 0x50, 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x70, 0x74, 0x5f, 0x42, 0x52, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, + 0x74, 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x75, 0x5f, 0x45, 0x45, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x72, 0x75, 0x5f, 0x4c, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x75, 0x5f, 0x4c, + 0x56, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x72, 0x75, 0x5f, 0x52, 0x55, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x65, + 0x5f, 0x53, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x76, 0x5f, 0x53, 0x45, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x74, 0x72, 0x5f, 0x54, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x41, 0x45, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x42, 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, + 0x43, 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x43, 0x5a, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, + 0x68, 0x5f, 0x44, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x45, 0x45, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x7a, 0x68, 0x5f, 0x46, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x47, + 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x48, 0x4b, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, + 0x5f, 0x48, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4a, 0x4f, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x7a, 0x68, 0x5f, 0x4b, 0x57, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4b, 0x5a, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4c, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, + 0x4c, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4c, 0x56, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, + 0x68, 0x5f, 0x4d, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4e, 0x5a, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x7a, 0x68, 0x5f, 0x4f, 0x4d, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x50, + 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x51, 0x41, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, + 0x5f, 0x52, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x53, 0x41, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x7a, 0x68, 0x5f, 0x53, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x53, 0x4b, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x54, 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, + 0x55, 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x59, 0x45, 0x22, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x65, 0x22, 0x3a, 0x20, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x61, 0x79, + 0x70, 0x61, 0x6c, 0x2e, 0x70, 0x70, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x2e, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x2e, 0x76, 0x33, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x3a, 0x20, + 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, + 0x2a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x79, 0x6f, 0x75, 0x72, 0x63, + 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x70, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, + 0x3a, 0x20, 0x22, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x3a, 0x20, 0x22, 0x32, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x75, + 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x65, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x61, 0x5f, 0x44, 0x4b, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x64, 0x65, 0x5f, 0x41, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, + 0x42, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, 0x43, 0x48, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, + 0x65, 0x5f, 0x44, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x5f, 0x44, 0x4b, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x64, 0x65, 0x5f, 0x4c, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x41, + 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x41, 0x52, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x41, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x41, 0x55, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x42, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x42, 0x47, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x42, 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x42, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x43, 0x41, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x43, 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x43, 0x4e, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x43, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x44, + 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x44, 0x4b, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x44, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x45, 0x45, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x45, 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x46, 0x49, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x46, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x47, 0x42, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x47, 0x52, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x48, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x48, 0x55, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x49, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x49, + 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x49, 0x54, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x4a, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4a, 0x50, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x4b, 0x57, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4b, 0x5a, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4c, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x4c, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4c, 0x56, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x4d, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4d, 0x58, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x4d, 0x59, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4e, + 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4e, 0x4f, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x4e, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x4f, 0x4d, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x50, 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x50, 0x4c, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, + 0x51, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x52, 0x4f, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x6e, 0x5f, 0x52, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x53, 0x41, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x6e, 0x5f, 0x53, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x53, + 0x47, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x53, 0x49, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, + 0x5f, 0x53, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x54, 0x4e, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x6e, 0x5f, 0x54, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x55, 0x53, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x6e, 0x5f, 0x59, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, + 0x41, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x41, 0x52, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x73, 0x5f, 0x42, 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x43, 0x5a, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x73, 0x5f, 0x44, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x45, + 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x45, 0x53, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, + 0x5f, 0x46, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x47, 0x52, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x73, 0x5f, 0x48, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4a, 0x4f, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4b, 0x57, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, + 0x4b, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4c, 0x54, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x73, 0x5f, 0x4c, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4c, 0x56, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x73, 0x5f, 0x4d, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4d, + 0x58, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x4e, 0x5a, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, + 0x5f, 0x4f, 0x4d, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x50, 0x54, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x65, 0x73, 0x5f, 0x51, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x52, 0x4f, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x65, 0x73, 0x5f, 0x53, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, + 0x53, 0x49, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x53, 0x4b, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, + 0x73, 0x5f, 0x54, 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x65, 0x73, 0x5f, 0x55, 0x53, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x65, 0x73, 0x5f, 0x59, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x41, + 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x42, 0x45, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, + 0x5f, 0x42, 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x43, 0x41, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x66, 0x72, 0x5f, 0x43, 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x43, 0x5a, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x66, 0x72, 0x5f, 0x44, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, + 0x45, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x46, 0x49, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, + 0x72, 0x5f, 0x46, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x47, 0x52, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x66, 0x72, 0x5f, 0x48, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4a, + 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4b, 0x57, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, + 0x5f, 0x4b, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4c, 0x54, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x66, 0x72, 0x5f, 0x4c, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4c, 0x56, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4d, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, + 0x4e, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x4f, 0x4d, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, + 0x72, 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x51, 0x41, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x66, 0x72, 0x5f, 0x52, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x53, + 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x53, 0x49, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, + 0x5f, 0x53, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x54, 0x4e, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x66, 0x72, 0x5f, 0x55, 0x53, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x66, 0x72, 0x5f, 0x59, 0x45, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x69, 0x74, 0x5f, 0x49, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x69, 0x77, 0x5f, + 0x49, 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x6a, 0x61, 0x5f, 0x4a, 0x50, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, + 0x62, 0x5f, 0x4e, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x6c, 0x5f, 0x42, 0x45, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x6e, 0x6c, 0x5f, 0x4e, 0x4c, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x6f, 0x5f, 0x4e, + 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x70, 0x6c, 0x5f, 0x50, 0x4c, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x74, + 0x5f, 0x42, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x70, 0x74, 0x5f, 0x50, 0x54, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x72, 0x75, 0x5f, 0x45, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x75, 0x5f, 0x4c, 0x54, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x72, 0x75, 0x5f, 0x4c, 0x56, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x72, 0x75, 0x5f, + 0x52, 0x55, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x73, 0x65, 0x5f, 0x53, 0x45, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, + 0x76, 0x5f, 0x53, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x72, 0x5f, 0x54, 0x52, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x7a, 0x68, 0x5f, 0x41, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x42, + 0x48, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x43, 0x4e, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, + 0x5f, 0x43, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x44, 0x5a, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x7a, 0x68, 0x5f, 0x45, 0x45, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x46, 0x49, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x47, 0x52, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, + 0x48, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x48, 0x55, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, + 0x68, 0x5f, 0x4a, 0x4f, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4b, 0x57, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x7a, 0x68, 0x5f, 0x4b, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4c, + 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4c, 0x55, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, + 0x5f, 0x4c, 0x56, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4d, 0x41, 0x22, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x7a, 0x68, 0x5f, 0x4e, 0x5a, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x4f, 0x4d, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x50, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, + 0x51, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x52, 0x4f, 0x22, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, + 0x68, 0x5f, 0x53, 0x41, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x53, 0x49, 0x22, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x7a, 0x68, 0x5f, 0x53, 0x4b, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x54, + 0x4e, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x7a, 0x68, 0x5f, 0x55, 0x53, 0x22, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x7a, 0x68, + 0x5f, 0x59, 0x45, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x22, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x63, + 0x6f, 0x6d, 0x2e, 0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x70, 0x70, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x6f, 0x75, 0x63, 0x68, + 0x2e, 0x76, 0x32, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x6f, 0x6d, 0x2e, 0x70, + 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x2a, 0x22, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x63, 0x6f, 0x6d, + 0x2e, 0x79, 0x6f, 0x75, 0x72, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, + 0x2e, 0x70, 0x70, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x22, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x62, 0x72, 0x6f, + 0x77, 0x73, 0x65, 0x72, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x22, 0x3a, 0x20, 0x22, 0x30, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x5d, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x22, 0x62, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x5f, 0x61, + 0x67, 0x72, 0x65, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x63, + 0x69, 0x70, 0x65, 0x73, 0x5f, 0x69, 0x6e, 0x5f, 0x64, 0x65, 0x63, 0x72, + 0x65, 0x61, 0x73, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x72, 0x69, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x3a, 0x20, + 0x5b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x22, 0x3a, 0x20, 0x22, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, + 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, 0x3a, 0x20, 0x22, + 0x30, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x5d, 0x0a, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x0a +}; +unsigned int configuration_otc_config_ios_json_len = 20723; diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Configuration/PPOTConfiguration.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Configuration/PPOTConfiguration.h new file mode 100644 index 0000000..f1b893e --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Configuration/PPOTConfiguration.h @@ -0,0 +1,91 @@ +// +// PPOTConfiguration.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import +#import "PPOTCore.h" +#import "PPOTRequest.h" + +@interface PPOTConfigurationRecipe : NSObject +@property (nonatomic, assign, readwrite) PPOTRequestTarget target; +@property (nonatomic, strong, readwrite) NSNumber *protocolVersion; +@property (nonatomic, strong, readwrite) NSArray *supportedLocales; // these have been uppercased, to prevent capitalization mistakes +@property (nonatomic, strong, readwrite) NSString *targetAppURLScheme; +@property (nonatomic, strong, readwrite) NSArray *targetAppBundleIDs; +@end + +@interface PPOTConfigurationRecipeEndpoint : NSObject +@property (nonatomic, strong, readwrite) NSString *url; +@property (nonatomic, strong, readwrite) NSString *certificateSerialNumber; +@property (nonatomic, strong, readwrite) NSString *base64EncodedCertificate; +@end + +@interface PPOTConfigurationOAuthRecipe : PPOTConfigurationRecipe +@property (nonatomic, strong, readwrite) NSSet *scope; +@property (nonatomic, strong, readwrite) NSDictionary *endpoints; // dictionary of PPOTConfigurationRecipeEndpoint +@end + +@interface PPOTConfigurationCheckoutRecipe : PPOTConfigurationRecipe +// no subclass-specific properties, so far +@end + +@interface PPOTConfigurationBillingAgreementRecipe : PPOTConfigurationRecipe +// no subclass-specific properties, so far +@end + +@class PPOTConfiguration; + +typedef void (^PPOTConfigurationCompletionBlock)(PPOTConfiguration *currentConfiguration); + +@interface PPOTConfiguration : NSObject + +/** + @brief In the background: if the cached configuration is stale, then downloads the latest version. +*/ ++ (void)updateCacheAsNecessary; + +/** + @brief Returns the current configuration, either from cache or else the hardcoded default configuration. +*/ ++ (PPOTConfiguration *)getCurrentConfiguration; + +/** + @brief This method is here only for PPOTConfigurationTest. + + @discussion Everyone else, please stick to using [PPOTConfiguration getCurrentConfiguration]!!! +*/ ++ (PPOTConfiguration *)configurationWithDictionary:(NSDictionary *)dictionary; + +#if DEBUG ++ (void)useHardcodedConfiguration:(BOOL)useHardcodedConfiguration; +#endif + +@property (nonatomic, strong, readwrite) NSString *fileTimestamp; +@property (nonatomic, strong, readwrite) NSArray *prioritizedOAuthRecipes; +@property (nonatomic, strong, readwrite) NSArray *prioritizedCheckoutRecipes; +@property (nonatomic, strong, readwrite) NSArray *prioritizedBillingAgreementRecipes; + +@end + +// The following definitions are for backwards compatibility +@interface PPConfiguration: PPOTConfiguration +@end + +@interface PPConfigurationCheckoutRecipe : PPOTConfigurationCheckoutRecipe +@end + +@interface PPConfigurationBillingAgreementRecipe : PPOTConfigurationBillingAgreementRecipe +@end + +@interface PPConfigurationOAuthRecipe : PPOTConfigurationOAuthRecipe +@end + +@interface PPConfigurationRecipeEndpoint : PPOTConfigurationRecipeEndpoint +@end + + + + diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Configuration/PPOTConfiguration.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Configuration/PPOTConfiguration.m new file mode 100644 index 0000000..be18a76 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Configuration/PPOTConfiguration.m @@ -0,0 +1,574 @@ +// +// PPOTConfiguration.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTConfiguration.h" +#import "PPOTJSONHelper.h" +#import "PPOTMacros.h" +#import "PPOTSimpleKeychain.h" +#import "PPOTURLSession.h" +#if __has_include("BraintreeCore.h") +#import "BTLogger_Internal.h" +#else +#import +#endif +#import + +#include "PPDefaultConfigurationJSON.h" +// `PPDefaultConfigurationJSON.h` is generated by a build script from `otc-config.ios.json`; +// it defines these two variables: +// unsigned char configuration_otc_config_ios_json[]; +// unsigned int configuration_otc_config_ios_json_len; +// `configuration_otc_config_ios_json` holds the contents of the `otc-config.ios.json` file. + +#define PPEnvironmentProduction @"live" + +#define kConfigurationFileDownloadURL CARDIO_STR(@"https://www.paypalobjects.com/webstatic/otc/otc-config.ios.json") +#define kConfigurationFileDownloadTimeout 60 +#define kConfigurationFileDownloadRetryInterval (5 * 60) // 5 minutes + +#define kPPOTConfigurationFileMaximumAcceptableObsolescence (4 * 60 * 60) // 4 hours + +#define kPPOTConfigurationSupportedProtocolVersionsForWallet @[@1, @2, @3] +#define kPPOTConfigurationSupportedProtocolVersionsForBrowser @[@0, @3] + +#define kPPOTConfigurationKeyOs CARDIO_STR(@"os") +#define kPPOTConfigurationKeyFileTimestamp CARDIO_STR(@"file_timestamp") +#define kPPOTConfigurationKeyTarget CARDIO_STR(@"target") +#define kPPOTConfigurationKeyProtocolVersion CARDIO_STR(@"protocol") +#define kPPOTConfigurationKeySupportedLocales CARDIO_STR(@"supported_locales") +#define kPPOTConfigurationKeyScope CARDIO_STR(@"scope") +#define kPPOTConfigurationKeyURLScheme CARDIO_STR(@"scheme") +#define kPPOTConfigurationKeyApplications CARDIO_STR(@"applications") +#define kPPOTConfigurationKeyEndpoints CARDIO_STR(@"endpoints") +#define kPPOTConfigurationKeyURL CARDIO_STR(@"url") +#define kPPOTConfigurationKeyCertificateSerialNumber CARDIO_STR(@"certificate_serial_number") +#define kPPOTConfigurationKeyCertificate CARDIO_STR(@"certificate") +#define kPPOTConfigurationKeyOAuthRecipes CARDIO_STR(@"oauth2_recipes_in_decreasing_priority_order") +#define kPPOTConfigurationKeyCheckoutRecipes CARDIO_STR(@"checkout_recipes_in_decreasing_priority_order") +#define kPPOTConfigurationKeyBillingAgreementRecipes CARDIO_STR(@"billing_agreement_recipes_in_decreasing_priority_order") + +#define kPPOTConfigurationValueWallet CARDIO_STR(@"wallet") +#define kPPOTConfigurationValueBrowser CARDIO_STR(@"browser") + +#define kPPOTCoderKeyConfigurationRecipeTarget CARDIO_STR(@"target") +#define kPPOTCoderKeyConfigurationRecipeProtocolVersion CARDIO_STR(@"protocol") +#define kPPOTCoderKeyConfigurationRecipeSupportedLocales CARDIO_STR(@"supportedLocales") +#define kPPOTCoderKeyConfigurationRecipeTargetAppURLScheme CARDIO_STR(@"targetAppURLScheme") +#define kPPOTCoderKeyConfigurationRecipeTargetAppBundleIDs CARDIO_STR(@"targetAppBundleIDs") +#define kPPOTCoderKeyConfigurationRecipeEndpoints CARDIO_STR(@"endpoints") +#define kPPOTCoderKeyConfigurationRecipeScope CARDIO_STR(@"scope") +#define kPPOTCoderKeyConfigurationRecipeURL CARDIO_STR(@"url") +#define kPPOTCoderKeyConfigurationRecipeCertificateSerialNumber CARDIO_STR(@"certificate_serial_number") +#define kPPOTCoderKeyConfigurationRecipeCertificate CARDIO_STR(@"certificate") + +#define kPPOTCoderKeyConfigurationDownloadTime CARDIO_STR(@"downloadTime") +#define kPPOTCoderKeyConfigurationTimestamp CARDIO_STR(@"timestamp") +#define kPPOTCoderKeyConfigurationOAuthRecipes CARDIO_STR(@"oAuthRecipes") +#define kPPOTCoderKeyConfigurationCheckoutRecipes CARDIO_STR(@"checkoutRecipes") +#define kPPOTCoderKeyConfigurationBillingAgreementRecipes CARDIO_STR(@"billingAgreementRecipes") + +#define kPPOTKeychainConfiguration CARDIO_STR(@"PayPal_OTC_Configuration") + +#define LOG_ERROR_AND_RETURN_NIL { PPSDKLog(@"Bad configuration: error %d", __LINE__); return nil; } + +#define STRING_FROM_DICTIONARY(STRING, DICTIONARY, KEY) \ +NSString *STRING = [PPOTJSONHelper stringFromDictionary:DICTIONARY withKey:KEY]; \ +if (!STRING) LOG_ERROR_AND_RETURN_NIL + +#define DICTIONARY_FROM_DICTIONARY(DICTIONARY1, DICTIONARY2, KEY, REQUIRED) \ +NSDictionary *DICTIONARY1 = [PPOTJSONHelper dictionaryFromDictionary:DICTIONARY2 withKey:KEY]; \ +if (REQUIRED && !DICTIONARY1) LOG_ERROR_AND_RETURN_NIL + +#define STRING_ARRAY_FROM_DICTIONARY(ARRAY, DICTIONARY, KEY, REQUIRED) \ +NSArray *ARRAY = [PPOTJSONHelper stringArrayFromDictionary:DICTIONARY withKey:KEY]; \ +if (REQUIRED && !ARRAY) LOG_ERROR_AND_RETURN_NIL + +#define DICTIONARY_ARRAY_FROM_DICTIONARY(ARRAY, DICTIONARY, KEY, REQUIRED) \ +NSArray *ARRAY = [PPOTJSONHelper dictionaryArrayFromDictionary:DICTIONARY withKey:KEY]; \ +if (REQUIRED && !ARRAY) LOG_ERROR_AND_RETURN_NIL + +#pragma mark - PPOTConfigurationRecipe + +@implementation PPOTConfigurationRecipe + +- (instancetype)initWithDictionary:(NSDictionary *)dictionary { + STRING_FROM_DICTIONARY(targetString, dictionary, kPPOTConfigurationKeyTarget) + STRING_FROM_DICTIONARY(protocolVersionString, dictionary, kPPOTConfigurationKeyProtocolVersion) + NSNumber *protocolVersionNumber = [NSNumber numberWithInteger:[protocolVersionString integerValue]]; + + if ((self = [super init])) { + if ([targetString isEqualToString:kPPOTConfigurationValueWallet]) { + _target = PPOTRequestTargetOnDeviceApplication; + + if (![kPPOTConfigurationSupportedProtocolVersionsForWallet containsObject:protocolVersionNumber]) { + LOG_ERROR_AND_RETURN_NIL + } + _protocolVersion = protocolVersionNumber; + + STRING_ARRAY_FROM_DICTIONARY(supportedLocalesArray, dictionary, kPPOTConfigurationKeySupportedLocales, NO) + // protect against capitalization mistakes: + NSMutableArray *uppercasedSupportedLocalesArray = [NSMutableArray arrayWithCapacity:[supportedLocalesArray count]]; + for (NSString *locale in supportedLocalesArray) { + [uppercasedSupportedLocalesArray addObject:[locale uppercaseString]]; + } + _supportedLocales = uppercasedSupportedLocalesArray; + + STRING_FROM_DICTIONARY(targetAppURLScheme, dictionary, kPPOTConfigurationKeyURLScheme) + if ([targetAppURLScheme rangeOfString:@":"].location != NSNotFound || + [targetAppURLScheme rangeOfString:@"/"].location != NSNotFound) { + LOG_ERROR_AND_RETURN_NIL + } + _targetAppURLScheme = targetAppURLScheme; + + STRING_ARRAY_FROM_DICTIONARY(targetsArray, dictionary, kPPOTConfigurationKeyApplications, YES) + _targetAppBundleIDs = targetsArray; + } + else if ([targetString isEqualToString:kPPOTConfigurationValueBrowser]) { + _target = PPOTRequestTargetBrowser; + + if (![kPPOTConfigurationSupportedProtocolVersionsForBrowser containsObject:protocolVersionNumber]) { + LOG_ERROR_AND_RETURN_NIL + } + _protocolVersion = protocolVersionNumber; + } + else { + LOG_ERROR_AND_RETURN_NIL + } + } + + return self; +} + +#pragma mark - NSCoding + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if ((self = [self init])) { + _target = ((NSNumber *)[aDecoder decodeObjectForKey:kPPOTCoderKeyConfigurationRecipeTarget]).unsignedIntegerValue; + _protocolVersion = [aDecoder decodeObjectForKey:kPPOTCoderKeyConfigurationRecipeProtocolVersion]; + + if (_target == PPOTRequestTargetOnDeviceApplication) { + _targetAppURLScheme = [aDecoder decodeObjectForKey:kPPOTCoderKeyConfigurationRecipeTargetAppURLScheme]; + _targetAppBundleIDs = [aDecoder decodeObjectForKey:kPPOTCoderKeyConfigurationRecipeTargetAppBundleIDs]; + _supportedLocales = [aDecoder decodeObjectForKey:kPPOTCoderKeyConfigurationRecipeSupportedLocales]; + } + } + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:@(self.target) forKey:kPPOTCoderKeyConfigurationRecipeTarget]; + [aCoder encodeObject:self.protocolVersion forKey:kPPOTCoderKeyConfigurationRecipeProtocolVersion]; + if (self.target == PPOTRequestTargetOnDeviceApplication) { + [aCoder encodeObject:self.targetAppURLScheme forKey:kPPOTCoderKeyConfigurationRecipeTargetAppURLScheme]; + [aCoder encodeObject:self.targetAppBundleIDs forKey:kPPOTCoderKeyConfigurationRecipeTargetAppBundleIDs]; + [aCoder encodeObject:self.supportedLocales forKey:kPPOTCoderKeyConfigurationRecipeSupportedLocales]; + } +} + +@end + +#pragma mark - PPOTConfigurationRecipeEndpoint + +@implementation PPOTConfigurationRecipeEndpoint + +- (instancetype)initWithURL:(NSString *)url withCertificateSerialNumber:(NSString *)certificateSerialNumber withBase64EncodedCertificate:(NSString *)base64EncodedCertificate { + if ((self = [super init])) { + if (![url length] || ![certificateSerialNumber length] || ![base64EncodedCertificate length]) { + LOG_ERROR_AND_RETURN_NIL + } + + if (![url hasPrefix:@"https://"] && ![url hasPrefix:@"http://"]) { + LOG_ERROR_AND_RETURN_NIL + } + + _url = url; + _certificateSerialNumber = certificateSerialNumber; + _base64EncodedCertificate = base64EncodedCertificate; + } + return self; +} + +#pragma mark - NSCoding + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if ((self = [super init])) { + _url = [aDecoder decodeObjectForKey:kPPOTCoderKeyConfigurationRecipeURL]; + _certificateSerialNumber = [aDecoder decodeObjectForKey:kPPOTCoderKeyConfigurationRecipeCertificateSerialNumber]; + _base64EncodedCertificate = [aDecoder decodeObjectForKey:kPPOTCoderKeyConfigurationRecipeCertificate]; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.url forKey:kPPOTCoderKeyConfigurationRecipeURL]; + [aCoder encodeObject:self.certificateSerialNumber forKey:kPPOTCoderKeyConfigurationRecipeCertificateSerialNumber]; + [aCoder encodeObject:self.base64EncodedCertificate forKey:kPPOTCoderKeyConfigurationRecipeCertificate]; +} + +@end + +#pragma mark - PPOTConfigurationOAuthRecipe + +@implementation PPOTConfigurationOAuthRecipe + +- (instancetype)initWithDictionary:(NSDictionary *)dictionary { + if ((self = [super initWithDictionary:dictionary])) { + STRING_ARRAY_FROM_DICTIONARY(scopeStrings, dictionary, kPPOTConfigurationKeyScope, YES) + _scope = [NSSet setWithArray:scopeStrings]; + + DICTIONARY_FROM_DICTIONARY(jsonEndpoints, dictionary, kPPOTConfigurationKeyEndpoints, + self.target == PPOTRequestTargetBrowser && [self.protocolVersion isEqual:@(3)]) + if (![jsonEndpoints count]) { + _endpoints = nil; + } + else { + NSMutableDictionary *endpoints = [NSMutableDictionary dictionaryWithCapacity:[jsonEndpoints count]]; + for (NSString *environment in jsonEndpoints) { + NSString *url = jsonEndpoints[environment][kPPOTConfigurationKeyURL]; + NSString *certificateSerialNumber = jsonEndpoints[environment][kPPOTConfigurationKeyCertificateSerialNumber]; + NSString *base64EncodedCertificate = jsonEndpoints[environment][kPPOTConfigurationKeyCertificate]; + + PPOTConfigurationRecipeEndpoint *endpoint = [[PPOTConfigurationRecipeEndpoint alloc] initWithURL:url + withCertificateSerialNumber:certificateSerialNumber + withBase64EncodedCertificate:base64EncodedCertificate]; + if (!endpoint) { + LOG_ERROR_AND_RETURN_NIL + } + + endpoints[environment] = endpoint; + } + + if (!endpoints[PPEnvironmentProduction]) { + LOG_ERROR_AND_RETURN_NIL + } + + _endpoints = endpoints; + } + } + return self; +} + +#pragma mark - NSCoding + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if ((self = [super initWithCoder:aDecoder])) { + _scope = [aDecoder decodeObjectForKey:kPPOTCoderKeyConfigurationRecipeScope]; + + if (self.target == PPOTRequestTargetBrowser) { + _endpoints = [aDecoder decodeObjectForKey:kPPOTCoderKeyConfigurationRecipeEndpoints]; + } + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [super encodeWithCoder:aCoder]; + [aCoder encodeObject:self.scope forKey:kPPOTCoderKeyConfigurationRecipeScope]; + + if (self.target == PPOTRequestTargetBrowser) { + [aCoder encodeObject:self.endpoints forKey:kPPOTCoderKeyConfigurationRecipeEndpoints]; + } +} + +@end + +#pragma mark - PPOTConfigurationCheckoutRecipe + +@implementation PPOTConfigurationCheckoutRecipe + +- (instancetype)initWithDictionary:(NSDictionary *)dict { + if ((self = [super initWithDictionary:dict])) { + // no subclass-specific properties, so far + } + return self; +} + +#pragma mark - NSCoding + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if ((self = [super initWithCoder:aDecoder])) { + // no subclass-specific properties, so far + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [super encodeWithCoder:aCoder]; + // no subclass-specific properties, so far +} + +@end + +#pragma mark - PPOTConfigurationBillingAgreementRecipe + +@implementation PPOTConfigurationBillingAgreementRecipe + +- (instancetype)initWithDictionary:(NSDictionary *)dict { + if ((self = [super initWithDictionary:dict])) { + // no subclass-specific properties, so far + } + return self; +} + +#pragma mark - NSCoding + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if ((self = [super initWithCoder:aDecoder])) { + // no subclass-specific properties, so far + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [super encodeWithCoder:aCoder]; + // no subclass-specific properties, so far +} + +@end + +#pragma mark - PPOTConfiguration + +typedef void (^PPOTConfigurationFileDownloadCompletionBlock)(NSData *fileData); + +@interface PPOTConfiguration () +@property (nonatomic, strong, readwrite) NSDate *downloadTime; +@end + +@implementation PPOTConfiguration + +#pragma mark - debug-only stuff + +#if DEBUG +static BOOL alwaysUseHardcodedConfiguration = NO; + ++ (void)useHardcodedConfiguration:(BOOL)useHardcodedConfiguration { + alwaysUseHardcodedConfiguration = useHardcodedConfiguration; +} +#endif + +#pragma mark - public methods + ++ (void)updateCacheAsNecessary { + // If there is no persisted configuration, or if it's stale, + // then download a fresh configuration file and persist it. + + static int nobodyIsWorkingOnThisAtTheMoment = 1; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + if (OSAtomicCompareAndSwapInt(1, 0, &nobodyIsWorkingOnThisAtTheMoment)) { + + PPOTConfiguration *currentConfiguration = [PPOTConfiguration fetchPersistentConfiguration]; + + if (!currentConfiguration || fabs([currentConfiguration.downloadTime timeIntervalSinceNow]) > kPPOTConfigurationFileMaximumAcceptableObsolescence) { + + static NSDate *lastConfigurationFileDownloadAttemptTime = nil; + + if (!lastConfigurationFileDownloadAttemptTime || + fabs([lastConfigurationFileDownloadAttemptTime timeIntervalSinceNow]) > kConfigurationFileDownloadRetryInterval) { + lastConfigurationFileDownloadAttemptTime = [NSDate date]; + + NSURL *url = [NSURL URLWithString:kConfigurationFileDownloadURL]; + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + [request setHTTPMethod:@"GET"]; + + // TODO: Can simplify by not specifying timeout interval. This might be better anyway to not specify because of slow networks. + PPOTURLSession *session = [PPOTURLSession sessionWithTimeoutIntervalForRequest:kConfigurationFileDownloadTimeout]; + [session sendRequest:request + completionBlock:^(NSData *data, __attribute__((unused)) NSHTTPURLResponse *response, __attribute__((unused)) NSError *error) { +#if DEBUG + NSString *dataString = nil; + if (data) { + dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + } + else { + dataString = @""; + } + [[BTLogger sharedLogger] debug:@"Downloaded JSON config\n-> HTTP status: %ld\n-> file contents:\n%@\n", (long)response.statusCode, dataString]; +#endif + PPOTConfiguration *configuration = data ? [[PPOTConfiguration alloc] initWithJSON:data] : nil; + if (configuration) { + configuration.downloadTime = [NSDate date]; + [PPOTConfiguration storePersistentConfiguration:configuration]; + } + [session finishTasksAndInvalidate]; + }]; + } + } + + nobodyIsWorkingOnThisAtTheMoment = 1; + } +#pragma clang diagnostic pop +} + ++ (PPOTConfiguration *)getCurrentConfiguration { +#if DEBUG + if (alwaysUseHardcodedConfiguration) { + return [self defaultConfiguration]; + } +#endif + + PPOTConfiguration *currentConfiguration = [PPOTConfiguration fetchPersistentConfiguration]; + + if (!currentConfiguration) { + currentConfiguration = [self defaultConfiguration]; + } + + return currentConfiguration; +} + ++ (PPOTConfiguration *)configurationWithDictionary:(NSDictionary *)dictionary { + return [[PPOTConfiguration alloc] initWithDictionary:dictionary]; +} + +#pragma mark - private methods + ++ (void)initialize { +#if DEBUG + NSAssert([PPOTConfiguration defaultConfiguration] != nil, @"otc-config.ios.json is invalid"); +#endif + if (self == [PPOTConfiguration class]) { + [self updateCacheAsNecessary]; + } +} + ++ (PPOTConfiguration *)defaultConfiguration { + NSData *defaultConfigurationJSON = [NSData dataWithBytes:configuration_otc_config_ios_json + length:configuration_otc_config_ios_json_len]; +#if DEBUG + NSString *str = [[NSString alloc] initWithData:defaultConfigurationJSON encoding:NSUTF8StringEncoding]; + [[BTLogger sharedLogger] debug:@"Using default JSON config %@\n", str]; +#endif + + PPOTConfiguration *defaultConfiguration = [[PPOTConfiguration alloc] initWithJSON:defaultConfigurationJSON]; + + return defaultConfiguration; +} + +- (instancetype)initWithDictionary:(NSDictionary *)dictionary { + STRING_FROM_DICTIONARY(os, dictionary, kPPOTConfigurationKeyOs) + + if (![os isEqualToString:@"iOS"]) { + LOG_ERROR_AND_RETURN_NIL + } + + STRING_FROM_DICTIONARY(fileTimestamp, dictionary, kPPOTConfigurationKeyFileTimestamp) + + // Currently we only support config file format 1.0. + // If we ever need to update the file format, then the code here would presumably + // first look for sub-dictionary "2.0" (or whatever) and then fallback to "1.0" as needed. + DICTIONARY_FROM_DICTIONARY(subDictionary, dictionary, @"1.0", YES) + + DICTIONARY_ARRAY_FROM_DICTIONARY(prioritizedOAuthRecipesDictionaries, subDictionary, kPPOTConfigurationKeyOAuthRecipes, NO) + DICTIONARY_ARRAY_FROM_DICTIONARY(prioritizedCheckoutRecipesDictionaries, subDictionary, kPPOTConfigurationKeyCheckoutRecipes, NO) + DICTIONARY_ARRAY_FROM_DICTIONARY(prioritizedBillingAgreementRecipesDictionaries, subDictionary, kPPOTConfigurationKeyBillingAgreementRecipes, NO) + + if ((self = [super init])) { + _downloadTime = [NSDate dateWithTimeIntervalSince1970:0]; // by default, mark file as obsolete + _fileTimestamp = fileTimestamp; + + _prioritizedOAuthRecipes = [self prioritizedRecipesFromArray:prioritizedOAuthRecipesDictionaries withRecipeAdapter:^PPOTConfigurationRecipe *(NSDictionary *recipeDictionary) { + return [[PPOTConfigurationOAuthRecipe alloc] initWithDictionary:recipeDictionary]; + }]; + + _prioritizedCheckoutRecipes = [self prioritizedRecipesFromArray:prioritizedCheckoutRecipesDictionaries withRecipeAdapter:^PPOTConfigurationRecipe* (NSDictionary* recipeDictionary) { + return [[PPOTConfigurationCheckoutRecipe alloc] initWithDictionary:recipeDictionary]; + }]; + + _prioritizedBillingAgreementRecipes = [self prioritizedRecipesFromArray:prioritizedBillingAgreementRecipesDictionaries withRecipeAdapter:^PPOTConfigurationRecipe* (NSDictionary* recipeDictionary) { + return [[PPOTConfigurationBillingAgreementRecipe alloc] initWithDictionary:recipeDictionary]; + }]; + + if (!_prioritizedOAuthRecipes || !_prioritizedCheckoutRecipes || !_prioritizedBillingAgreementRecipes) { + return nil; + } + } + return self; +} + +- (NSArray*)prioritizedRecipesFromArray:(NSArray*)recipes withRecipeAdapter:(PPOTConfigurationRecipe* (^)(NSDictionary*))recipeAdapter { + NSMutableArray *prioritizedRecipes = [NSMutableArray arrayWithCapacity:[recipes count]]; + for (NSDictionary *recipeDictionary in recipes) { + PPOTConfigurationRecipe *recipe = recipeAdapter(recipeDictionary); + if (recipe) { + [prioritizedRecipes addObject:recipe]; + } + } + return prioritizedRecipes; +} + +- (instancetype)initWithJSON:(NSData *)jsonData { + NSError *error = nil; + id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; + if (error || ![jsonObject isKindOfClass:[NSDictionary class]]) { + LOG_ERROR_AND_RETURN_NIL + } + + self = [self initWithDictionary:((NSDictionary *)jsonObject)]; + return self; +} + +#pragma mark - description + +- (NSString *)description { + return [NSString stringWithFormat:@"PPOTConfiguration: %ld Authorization recipes, %ld Checkout recipes, %ld Billing Agreement recipes", + (unsigned long)[self.prioritizedOAuthRecipes count], + (unsigned long)[self.prioritizedCheckoutRecipes count], + (unsigned long)[self.prioritizedBillingAgreementRecipes count]]; +} + +#pragma mark - NSCoding + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if ((self = [self init])) { + _downloadTime = [aDecoder decodeObjectForKey:kPPOTCoderKeyConfigurationDownloadTime]; + _fileTimestamp = [aDecoder decodeObjectForKey:kPPOTCoderKeyConfigurationTimestamp]; + _prioritizedOAuthRecipes = [aDecoder decodeObjectForKey:kPPOTCoderKeyConfigurationOAuthRecipes]; + _prioritizedCheckoutRecipes = [aDecoder decodeObjectForKey:kPPOTCoderKeyConfigurationCheckoutRecipes]; + _prioritizedBillingAgreementRecipes = [aDecoder decodeObjectForKey:kPPOTCoderKeyConfigurationBillingAgreementRecipes]; + } + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.downloadTime forKey:kPPOTCoderKeyConfigurationDownloadTime]; + [aCoder encodeObject:self.fileTimestamp forKey:kPPOTCoderKeyConfigurationTimestamp]; + [aCoder encodeObject:self.prioritizedOAuthRecipes forKey:kPPOTCoderKeyConfigurationOAuthRecipes]; + [aCoder encodeObject:self.prioritizedCheckoutRecipes forKey:kPPOTCoderKeyConfigurationCheckoutRecipes]; + [aCoder encodeObject:self.prioritizedBillingAgreementRecipes forKey:kPPOTCoderKeyConfigurationBillingAgreementRecipes]; +} + +#pragma mark - keychain persistence + ++ (PPOTConfiguration *)fetchPersistentConfiguration { + return (PPOTConfiguration *) [PPOTSimpleKeychain unarchiveObjectWithDataForKey:kPPOTKeychainConfiguration]; +} + ++ (void)storePersistentConfiguration:(PPOTConfiguration *)configuration { + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:configuration]; + [PPOTSimpleKeychain setData:data forKey:kPPOTKeychainConfiguration]; +} + +@end + +@implementation PPConfiguration +@end + +@implementation PPConfigurationCheckoutRecipe +@end + +@implementation PPConfigurationBillingAgreementRecipe +@end + +@implementation PPConfigurationOAuthRecipe +@end + +@implementation PPConfigurationRecipeEndpoint +@end + diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAppSwitchResponse.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAppSwitchResponse.h new file mode 100644 index 0000000..375c2b2 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAppSwitchResponse.h @@ -0,0 +1,73 @@ +// +// PPOTAppSwitchResponse.h +// PayPalOneTouch +// +// Copyright © 2014 PayPal, Inc. All rights reserved. +// + +#import +#import "PPOTAppSwitchUtil.h" + +@class PPOTConfigurationRecipe; + +@interface PPOTAppSwitchResponse : NSObject + +/** + @brief info from the most recent request +*/ +@property (nonatomic, readonly) NSString *encryptionKey; + +@property (nonatomic, readonly) PPAppSwitchResponseAction action; + +/** + @brief represents payment_code_type for version 3 for now +*/ +@property (nonatomic, readonly) PPAppSwitchResponseType responseType; + +@property (nonatomic, readonly) NSInteger version; +@property (nonatomic, readonly) NSString *displayName; +@property (nonatomic, readonly) NSString *email; +@property (nonatomic, readonly) NSString *accessToken; +/** + @brief represents payment_code in version 3 for now +*/ +@property (nonatomic, readonly) NSString *authorizationCode; +@property (nonatomic, readonly) NSInteger expiresIn; +@property (nonatomic, readonly) NSArray *scope; +/** + @brief not sent yet +*/ +@property (nonatomic, readonly) NSString *photoURL; + +@property (nonatomic, readonly) NSDictionary *decodedPayload; +/** + @brief can contain debug_id and message +*/ +@property (nonatomic, readonly) NSDictionary *error; +@property (nonatomic, readonly) NSString *environment; + +/** + @brief version 0 and 2 +*/ +@property (nonatomic, readonly) NSString *webURL; + +/** + @brief version 3 +*/ +@property (nonatomic, readonly) NSDate *timeStamp; +@property (nonatomic, readonly) NSString *msgID; + +/** + @brief version 0 +*/ +- (instancetype)initWithHermesURL:(NSURL *)url environment:(NSString *)environment; + +/** + @brief version 1, 2, 3 +*/ +- (instancetype)initWithEncodedURL:(NSURL *)url encryptionKey:(NSString *)encryptionKey; + +- (BOOL)validResponse; + + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAppSwitchResponse.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAppSwitchResponse.m new file mode 100644 index 0000000..56275de --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAppSwitchResponse.m @@ -0,0 +1,218 @@ +// +// PPOTAppSwitchResponse.m +// PayPalOneTouch +// +// Copyright © 2014 PayPal, Inc. All rights reserved. +// + +#import "PPOTAppSwitchResponse.h" +#import "PPOTString.h" +#import "PPOTTime.h" +#import "PPOTEncryptionHelper.h" +#import "PPOTJSONHelper.h" + +@implementation PPOTAppSwitchResponse + +- (instancetype)initWithEncodedURL:(NSURL *)url encryptionKey:(NSString *)encryptionKey { + if (!url) { + return nil; + } + self = [self initWithURL:url]; + if (self) { + _encryptionKey = encryptionKey; + + // convert query string to dictionary, handles URLEncoding + NSDictionary *query = [PPOTAppSwitchUtil parseQueryString:[url query]]; + + + // base64 encoded payload + NSString *encodedPayload = [PPOTJSONHelper stringFromDictionary:query withKey:kPPOTAppSwitchPayloadKey]; + if (encodedPayload.length) { + // parse payload + _decodedPayload = [PPOTJSONHelper dictionaryWithBase64EncodedJSONString:encodedPayload]; + } + + if (_encryptionKey.length) { + // base64 encoded encrypted payload + NSString *encodedEncryptedPayload = [PPOTJSONHelper stringFromDictionary:query withKey:kPPOTAppSwitchEncryptedPayloadKey]; + if (encodedEncryptedPayload.length) { + // parse encrypted payload + NSData *encryptedData = [[NSData alloc] initWithBase64EncodedString:encodedEncryptedPayload + options:NSDataBase64DecodingIgnoreUnknownCharacters]; + [self parseEncryptedPayload:encryptedData]; + } + } + + [self parsePayload]; + } + return self; +} + +- (instancetype)initWithHermesURL:(NSURL *)url environment:(NSString *)environment { + if (!url) { + return nil; + } + self = [self initWithURL:url]; + if (self) { + // TODO: add error parsing since hermes may pass a error or abroted flag. + _responseType = PPAppSwitchResponseTypeWeb; + _webURL = [url absoluteString]; + _environment = environment; + } + return self; +} + +- (instancetype)initWithURL:(NSURL *)url { + self = [self init]; + if (self) { + // extract action from URL + if ([[PPOTAppSwitchUtil actionFromURLAction:url] isEqualToString:kPPOTAppSwitchCancelAction]) { + _action = PPAppSwitchResponseActionCancel; + } else if ([[PPOTAppSwitchUtil actionFromURLAction:url] isEqualToString:kPPOTAppSwitchSuccessAction]) { + _action = PPAppSwitchResponseActionSuccess; + } else { + _action = PPAppSwitchResponseActionUnknown; + } + } + return self; +} + +- (void)parsePayload { + + NSNumber *version = [PPOTJSONHelper numberFromDictionary:_decodedPayload withKey:kPPOTAppSwitchProtocolVersionKey]; + // Wallet not always sends version, default to 1 + _version = (version != nil) ? [version integerValue] : 1; + + // in version 3+ the response_type is no longer sent + NSString *responseType = nil; + if (_version >= 3) { + responseType = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchPaymentCodeTypeKey]; + if (responseType == nil) { + responseType = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchResponseTypeKey]; + } + } else { + responseType = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchResponseTypeKey]; + } + + if ([responseType isEqualToString:kPPOTAppSwitchResponseTypeCode] || [responseType isEqualToString:kPPOTAppSwitchResposneAuthCodeKey]) { + _responseType = PPAppSwitchResponseTypeAuthorizationCode; + } else if ([responseType isEqualToString:kPPOTAppSwitchResponseTypeToken]) { + _responseType = PPAppSwitchResponseTypeToken; + } else if ([responseType isEqualToString:kPPOTAppSwitchResponseTypeWeb]) { + _responseType = PPAppSwitchResponseTypeWeb; + } else { + _responseType = PPAppSwitchResponseTypeUnknown; + } + + _displayName = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchDisplayNameKey]; + _email = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchEmailKey]; + // TODO: remove check until we fix with BT + if (!_email.length) { + _email = [_displayName copy]; + } + _accessToken = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchAccessTokenKey]; + + if (_version >= 3) { + _authorizationCode = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchPaymentCodeKey];; + if (![_authorizationCode length]) { + _authorizationCode = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchAuthorizationCodeKey]; + } + } else { + _authorizationCode = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchAuthorizationCodeKey]; + } + + NSNumber *expiresIn = [PPOTJSONHelper numberFromDictionary:_decodedPayload withKey:kPPOTAppSwitchExpiresInKey]; + if (expiresIn != nil) { + _expiresIn = [expiresIn integerValue]; + } + + NSString *scope = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchScopesKey]; + if (scope.length) { + _scope = [scope componentsSeparatedByString:@" "]; + } + + _photoURL = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchPhotoURLKey]; + + _webURL = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchWebURLKey]; + + // The decoded payload may have been JSON decoded where the error value is already a dictionary + NSDictionary *errorDict = [PPOTJSONHelper dictionaryFromDictionary:_decodedPayload withKey:kPPOTAppSwitchErrorKey]; + if (errorDict) { + _error = errorDict; + } else { + NSString *error = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchErrorKey]; + if (error.length) { + _error = [NSJSONSerialization JSONObjectWithData:[error dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil]; + } + } + + NSString *environment = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchEnvironmentKey]; + if (environment.length) { + _environment = [environment lowercaseString]; + } + + // TODO: BT not sending at a string and in weird format + NSString *strTimetamp = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchTimestampKey]; + if (strTimetamp) { + _timeStamp = [PPOTTime dateFromRFC3339LikeString:strTimetamp]; + } else { + NSNumber *timestamp = [PPOTJSONHelper numberFromDictionary:_decodedPayload withKey:kPPOTAppSwitchTimestampKey]; + if (timestamp != nil) { + _timeStamp = [NSDate dateWithTimeIntervalSince1970:[timestamp doubleValue]]; + } + } + + _msgID = [PPOTJSONHelper stringFromDictionary:_decodedPayload withKey:kPPOTAppSwitchMsgGUIDKey]; +} + +- (void)parseEncryptedPayload:(NSData *)encryptedPayload { + NSData *encryptionKey = [PPOTString dataWithHexString:_encryptionKey]; + NSData *decryptedPayload = [PPOTEncryptionHelper decryptAESCTRData:encryptedPayload encryptionKey:encryptionKey]; + if (decryptedPayload.length && encryptionKey.length) { + NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:decryptedPayload options:0 error:nil]; + if (jsonDictionary) { + // merge with existing payload + NSMutableDictionary *mergedDictionary = [NSMutableDictionary dictionaryWithCapacity:_decodedPayload.count + jsonDictionary.count]; + [mergedDictionary addEntriesFromDictionary:_decodedPayload]; + [mergedDictionary addEntriesFromDictionary:jsonDictionary]; + _decodedPayload = mergedDictionary; + } + } +} + +- (BOOL)validResponse { + if (self.action == PPAppSwitchResponseActionCancel) { + return YES; + } + + if (self.responseType == PPAppSwitchResponseTypeUnknown + || self.action == PPAppSwitchResponseActionUnknown + || (self.version < 0 || self.version > kPPOTAppSwitchCurrentVersionNumber) + ) { + return NO; + } + + // TOKEN not supported + + if (self.responseType == PPAppSwitchResponseTypeAuthorizationCode) { + if (!self.authorizationCode.length + || !self.email.length + || !self.displayName.length) { + return NO; + } + } + + if (self.responseType == PPAppSwitchResponseTypeWeb) { + if (!self.webURL.length) { + return NO; + } + } + + return YES; +} + +- (NSString *)description { + return [_decodedPayload description]; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAppSwitchUtil.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAppSwitchUtil.h new file mode 100644 index 0000000..b5526b9 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAppSwitchUtil.h @@ -0,0 +1,107 @@ +// +// PPOTAppSwitchUtil.h +// PayPalOneTouch +// +// Copyright © 2014 PayPal, Inc. All rights reserved. +// + +#import + +@class PPOTConfigurationRecipe; + +#define kPPOTAppSwitchCurrentVersionNumber 3 + +// Dictionary keys for PPTouch v1 protocol +#define kPPOTAppSwitchEnvironmentKey @"environment" +#define kPPOTAppSwitchEnvironmentURLKey @"environment_url" +#define kPPOTAppSwitchCustomEnvironmentKey @"custom" +#define kPPOTAppSwitchAppNameKey @"app_name" +#define kPPOTAppSwitchAppGuidKey @"app_guid" +#define kPPOTAppSwitchResponseTypeKey @"response_type" +#define kPPOTAppSwitchClientIdKey @"client_id" +#define kPPOTAppSwitchPayloadKey @"payload" +#define kPPOTAppSwitchHermesTokenKey @"token" +#define kPPOTAppSwitchHermesBATokenKey @"ba_token" +#define kPPOTAppSwitchXCancelKey @"x-cancel" +#define kPPOTAppSwitchXSuccessKey @"x-success" +#define kPPOTAppSwitchXSourceKey @"x-source" +#define kPPOTAppSwitchAuthenticateAction @"authenticate" +#define kPPOTAppSwitchSuccessAction @"success" +#define kPPOTAppSwitchCancelAction @"cancel" +#define kPPOTAppSwitchResponseTypeCode @"code" +#define kPPOTAppSwitchResponseTypeToken @"token" +#define kPPOTAppSwitchDisplayNameKey @"display_name" +#define kPPOTAppSwitchAccessTokenKey @"access_token" +#define kPPOTAppSwitchAuthorizationCodeKey @"authorization_code" +#define kPPOTAppSwitchExpiresInKey @"expires_in" +#define kPPOTAppSwitchScopesKey @"scope" +#define kPPOTAppSwitchEmailKey @"email" +#define kPPOTAppSwitchPhotoURLKey @"photo_url" +#define kPPOTAppSwitchAccountCountryKey @"account_country" +#define kPPOTAppSwitchLanguageKey @"language" +#define kPPOTAppSwitchProtocolVersionKey @"version" +#define kPPOTAppSwitchPrivacyURLKey @"privacy_url" +#define kPPOTAppSwitchAgreementURLKey @"agreement_url" +#define kPPOTAppSwitchErrorKey @"error" +#define kPPOTAppSwitchMessageKey @"message" + +// v2 extension +#define kPPOTAppSwitchResponseTypeWeb @"web" +#define kPPOTAppSwitchWebURLKey @"webURL" + +// v3 +#define kPPOTAppSwitchMetadataClientIDKey @"client_metadata_id" +#define kPPOTAppSwitchKeyIDKey @"key_id" +#define kPPOTAppSwitchMsgGUIDKey @"msg_GUID" +#define kPPOTAppSwitchSymKey @"sym_key" +#define kPPOTAppSwitchTimestampKey @"timestamp" +#define kPPOTAppSwitchLoginAction @"login" +#define kPPOTAppSwitchEncryptedPayloadKey @"payloadEnc" +#define kPPOTAppSwitchPaymentCodeTypeKey @"payment_code_type" +#define kPPOTAppSwitchPaymentCodeKey @"payment_code" +#define kPPOTAppSwitchResposneAuthCodeKey @"authcode" +#define kPPOTAppSwitchKeyDeviceName @"device_name" + +#define PPRequestEnvironmentProduction @"live" +#define PPRequestEnvironmentNoNetwork @"mock" +#define PPRequestEnvironmentSandbox @"sandbox" + + +typedef NS_ENUM(NSUInteger, PPAppSwitchResponseAction) { + PPAppSwitchResponseActionUnknown, + PPAppSwitchResponseActionCancel, + PPAppSwitchResponseActionSuccess +}; + +typedef NS_ENUM(NSUInteger, PPAppSwitchResponseType) { + PPAppSwitchResponseTypeUnknown, + PPAppSwitchResponseTypeToken, + PPAppSwitchResponseTypeAuthorizationCode, + PPAppSwitchResponseTypeWeb, +}; + +@interface PPOTAppSwitchUtil : NSObject + ++ (NSString *)bundleId; ++ (NSString *)bundleName; ++ (BOOL)isCallbackURLSchemeValid:(NSString *)callbackURLScheme; + +/** + @brief handles urlencoding +*/ ++ (NSDictionary *)parseQueryString:(NSString *)query; + ++ (NSURL *)URLAction:(NSString *)action + targetAppURLScheme:(NSString *)targetAppURLScheme + callbackURLScheme:(NSString *)callbackURLScheme + payload:(NSDictionary *)payload; + ++ (NSURL *)URLAction:(NSString *)action + callbackURLScheme:(NSString *)callbackURLScheme + payload:(NSDictionary *)payload; + ++ (void)redirectURLsForCallbackURLScheme:(NSString *)callbackURLScheme withReturnURL:(NSString **)returnURL withCancelURL:(NSString **)cancelURL; ++ (BOOL)isValidURLAction:(NSURL *)urlAction; ++ (NSString *)actionFromURLAction:(NSURL *)urlAction; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAppSwitchUtil.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAppSwitchUtil.m new file mode 100644 index 0000000..dda7b72 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAppSwitchUtil.m @@ -0,0 +1,184 @@ +// +// PPOTAppSwitchUtil.m +// PayPalOneTouch +// +// Copyright © 2014 PayPal, Inc. All rights reserved. +// +#import + +#import "PPOTAppSwitchUtil.h" +#import "PPOTConfiguration.h" +#import "PPOTMacros.h" +#import "PPOTAnalyticsTracker.h" +#import "PPOTVersion.h" +#import "PPOTPersistentRequestData.h" +#import "PPOTString.h" +#import "PPOTJSONHelper.h" +#import "PPOTAnalyticsDefines.h" + +#define STR_TO_URL_SCHEME(str) [NSURL URLWithString:[NSString stringWithFormat:@"%@://", str]] + +@implementation PPOTAppSwitchUtil + ++ (NSString *)bundleId { + return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"]; +} + ++ (NSString *)bundleName { + return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"]; +} + ++ (BOOL)isCallbackURLSchemeValid:(NSString *)callbackURLScheme { + NSString *bundleID = [[self bundleId] lowercaseString]; + + // There are issues returning to the app if the return URL begins with a `-` + // Allow callback URLs that remove the leading `-` + // Ex: An app with Bundle ID `-com.example.myapp` can use the callback URL `com.example.myapp.payments` + if (bundleID.length <= 1) { + return NO; + } else if ([[bundleID substringToIndex:1] isEqualToString:@"-"] && ![[callbackURLScheme lowercaseString] hasPrefix:bundleID]) { + bundleID = [bundleID substringFromIndex:1]; + } + + if (bundleID && ![[callbackURLScheme lowercaseString] hasPrefix:bundleID]) { + PPSDKLog(@"callback URL scheme must start with %@ ", bundleID); + return NO; + } + + // check the actual plist that the app is fully configured rather than just making canOpenURL call + NSArray *urlTypes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"]; + for (NSDictionary *item in urlTypes) { + NSArray *bundleURLSchemes = item[@"CFBundleURLSchemes"]; + if (NSNotFound != [bundleURLSchemes indexOfObject:callbackURLScheme]) { + return YES; + } + } + PPSDKLog(@"callback URL scheme %@ is not found in .plist", callbackURLScheme); + return NO; +} + ++ (NSString *)protocolFromTargetAppURLScheme:(NSString *)targetAppURLScheme { + NSArray *components = [targetAppURLScheme componentsSeparatedByString:@"."]; + return components[[components count] - 1]; +} + ++ (NSDictionary *)parseQueryString:(NSString *)query { + NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:6]; + NSArray *pairs = [query componentsSeparatedByString:@"&"]; + + for (NSString *pair in pairs) { + NSArray *elements = [pair componentsSeparatedByString:@"="]; + if (elements.count > 1) { + NSString *key = [[elements objectAtIndex:0] stringByRemovingPercentEncoding]; + NSString *val = [[elements objectAtIndex:1] stringByRemovingPercentEncoding]; + if (key.length && val.length) { + dict[key] = val; + } + } + } + return dict; +} + ++ (NSURL *)URLAction:(NSString *)action + targetAppURLScheme:(NSString *)targetAppURLScheme + callbackURLScheme:(NSString *)callbackURLScheme + payload:(NSDictionary *)payload { + NSString *successURL; + NSString *cancelURL; + [self redirectURLsForCallbackURLScheme:callbackURLScheme withReturnURL:&successURL withCancelURL:&cancelURL]; + + NSString *encodedPayload = [PPOTString stringByURLEncodingAllCharactersInString:[PPOTJSONHelper base64EncodedJSONStringWithDictionary:payload]]; + NSString* urlString = [NSString stringWithFormat:@"%@://%@?%@=%@&%@=%@&%@=%@&%@=%@", + targetAppURLScheme, action, kPPOTAppSwitchPayloadKey, encodedPayload, + kPPOTAppSwitchXSourceKey, [self bundleId], + kPPOTAppSwitchXSuccessKey, successURL, + kPPOTAppSwitchXCancelKey, cancelURL]; + + return [NSURL URLWithString:urlString]; +} + ++ (NSURL *)URLAction:(NSString *)action + callbackURLScheme:(NSString *)callbackURLScheme + payload:(NSDictionary *)payload { + NSString *successURL; + NSString *cancelURL; + [self redirectURLsForCallbackURLScheme:callbackURLScheme withReturnURL:&successURL withCancelURL:&cancelURL]; + + NSString *encodedPayload = [PPOTString stringByURLEncodingAllCharactersInString:[PPOTJSONHelper base64EncodedJSONStringWithDictionary:payload]]; + NSString* urlString = [NSString stringWithFormat:@"%@?%@=%@&%@=%@&%@=%@&%@=%@", + action, kPPOTAppSwitchPayloadKey, encodedPayload, + kPPOTAppSwitchXSourceKey, [self bundleId], + kPPOTAppSwitchXSuccessKey, successURL, + kPPOTAppSwitchXCancelKey, cancelURL]; + + return [NSURL URLWithString:urlString]; +} + +#pragma mark - build or parse our redirect urls + ++ (void)redirectURLsForCallbackURLScheme:(NSString *)callbackURLScheme withReturnURL:(NSString * __autoreleasing *)returnURL withCancelURL:(NSString * __autoreleasing *)cancelURL { + PPAssert(returnURL, @"redirectURLsForCallbackURLScheme: returnURL is required"); + PPAssert(cancelURL, @"redirectURLsForCallbackURLScheme: cancelURL is required"); + + *returnURL = nil; + *cancelURL = nil; + + if ([PPOTAppSwitchUtil isCallbackURLSchemeValid:callbackURLScheme]) { + NSString *hostAndPath = [self redirectURLHostAndPath]; + *returnURL = [NSString stringWithFormat:@"%@://%@%@", callbackURLScheme, hostAndPath, kPPOTAppSwitchSuccessAction]; + *cancelURL = [NSString stringWithFormat:@"%@://%@%@", callbackURLScheme, hostAndPath, kPPOTAppSwitchCancelAction]; + } +} + ++ (BOOL)isValidURLAction:(NSURL *)urlAction { + NSString *scheme = urlAction.scheme; + if (!scheme.length) { + return NO; + } + + NSString *hostAndPath = [urlAction.host stringByAppendingString:urlAction.path]; + NSMutableArray *pathComponents = [[hostAndPath componentsSeparatedByString:@"/"] mutableCopy]; + [pathComponents removeLastObject]; // remove the action (`success`, `cancel`, etc) + hostAndPath = [pathComponents componentsJoinedByString:@"/"]; + if ([hostAndPath length]) { + hostAndPath = [hostAndPath stringByAppendingString:@"/"]; + } + if (![hostAndPath isEqualToString:[self redirectURLHostAndPath]]) { + return NO; + } + + NSString *action = [self actionFromURLAction:urlAction]; + if (!action.length) { + return NO; + } + + NSArray *validActions = @[kPPOTAppSwitchSuccessAction, kPPOTAppSwitchCancelAction, kPPOTAppSwitchAuthenticateAction]; + if (![validActions containsObject:action]) { + return NO; + } + + NSString *query = [urlAction query]; + if (!query.length) { + // should always have at least a payload or else a Hermes token + return NO; + } + + return YES; +} + ++ (NSString *)actionFromURLAction:(NSURL *)urlAction { + NSString *action = [urlAction.lastPathComponent componentsSeparatedByString:@"?"][0]; + if (![action length]) { + action = urlAction.host; + } + return action; +} + ++ (NSString *)redirectURLHostAndPath { + // Return either an empty string; + // or else a non-empty `host` or `host/path`, ending with `/` + + return @"onetouch/v1/"; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAuthorizationRequest.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAuthorizationRequest.m new file mode 100644 index 0000000..cf226cb --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAuthorizationRequest.m @@ -0,0 +1,180 @@ +// +// PPOTAuthorizationRequest.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTRequest_Internal.h" +#import "PPOTAppSwitchUtil.h" +#import "PPOTConfiguration.h" +#import "PPOTDevice.h" +#import "PPOTMacros.h" +#import "PPOTOAuth2AppSwitchRequest.h" +#import "PPOTOAuth2BrowserSwitchRequest.h" +#import "PPOTEncryptionHelper.h" +#import "PPOTString.h" + +#define PPRequestEnvironmentDevelop @"develop" + +@interface PPOTAuthorizationRequest () + +/// Set of requested scope-values. +/// Available scope-values are listed at https://developer.paypal.com/webapps/developer/docs/integration/direct/identity/attributes/ +@property (nonatomic, readwrite) NSSet *scopeValues; + +/// The URL of the merchant's privacy policy +@property (nonatomic, readwrite) NSURL *privacyURL; + +/// The URL of the merchant's user agreement +@property (nonatomic, readwrite) NSURL *agreementURL; + +@end + +#pragma mark - PPOTAuthorizationRequest implementation + +@implementation PPOTAuthorizationRequest + +- (instancetype)initWithScopeValues:(NSSet *)scopeValues + privacyURL:(NSURL *)privacyURL + agreementURL:(NSURL *)agreementURL + clientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme { + if (scopeValues.count == 0) { + PPSDKLog(@"scope is required."); + return nil; + } + + if (privacyURL == nil) { + PPSDKLog(@"merchantPrivacyPolicyURL is required."); + return nil; + } + if (agreementURL == nil) { + PPSDKLog(@"merchantUserAgreementURL is required."); + return nil; + } + + self = [super initWithClientID:clientID environment:environment callbackURLScheme:callbackURLScheme]; + if (self) { + _scopeValues = scopeValues; + _privacyURL = privacyURL; + _agreementURL = agreementURL; + } + + return self; +} + ++ (instancetype)requestWithScopeValues:(NSSet *)scopeValues + privacyURL:(NSURL *)privacyURL + agreementURL:(NSURL *)agreementURL + clientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme { + PPOTAuthorizationRequest *request = [[PPOTAuthorizationRequest alloc] initWithScopeValues:scopeValues + privacyURL:privacyURL + agreementURL:agreementURL + clientID:clientID + environment:environment + callbackURLScheme:callbackURLScheme]; + return request; +} + +#pragma mark - add subclass-specific info to appSwitchRequest + +- (PPOTSwitchRequest *)getAppSwitchRequestForConfigurationRecipe:(PPOTConfigurationRecipe *)configurationRecipe { + + PPOTOAuth2SwitchRequest *appSwitchRequest = nil; + + switch (configurationRecipe.target) { + case PPOTRequestTargetOnDeviceApplication: { + appSwitchRequest = [[PPOTOAuth2AppSwitchRequest alloc] initWithProtocolVersion:configurationRecipe.protocolVersion + appGuid:[PPOTDevice appropriateIdentifier] + clientID:self.clientID + environment:self.environment + callbackURLScheme:self.callbackURLScheme]; + break; + } + case PPOTRequestTargetBrowser: { + PPOTOAuth2BrowserSwitchRequest *browserSwitchRequest = [[PPOTOAuth2BrowserSwitchRequest alloc] initWithProtocolVersion:configurationRecipe.protocolVersion + appGuid:[PPOTDevice appropriateIdentifier] + clientID:self.clientID + environment:self.environment + callbackURLScheme:self.callbackURLScheme]; + PPOTConfigurationOAuthRecipe *ooauthRecipe = (PPOTConfigurationOAuthRecipe *)configurationRecipe; + NSString *relevantEnvironment = nil; + if (ooauthRecipe.endpoints[self.environment]) { + relevantEnvironment = self.environment; + } else if (![self.environment isEqualToString:PPRequestEnvironmentProduction] && + ![self.environment isEqualToString:PPRequestEnvironmentNoNetwork] && + ooauthRecipe.endpoints[PPRequestEnvironmentDevelop]) { + relevantEnvironment = PPRequestEnvironmentDevelop; + } else if (ooauthRecipe.endpoints[PPRequestEnvironmentProduction]) { + relevantEnvironment = PPRequestEnvironmentProduction; + } + + if (relevantEnvironment) { // this is merely a sanity check; presence of "live" was guaranteed in [PPOTConfigurationOAuthRecipe initWithDictionary:] + PPOTConfigurationRecipeEndpoint *endpoint = ooauthRecipe.endpoints[relevantEnvironment]; + browserSwitchRequest.endpoint = endpoint.url; + browserSwitchRequest.keyID = endpoint.certificateSerialNumber; + browserSwitchRequest.certificate = [[NSData alloc] initWithBase64EncodedString:endpoint.base64EncodedCertificate + options:NSDataBase64DecodingIgnoreUnknownCharacters]; + + browserSwitchRequest.encryptionKey = [PPOTString hexStringFromData:[PPOTEncryptionHelper generate256BitKey]]; + browserSwitchRequest.additionalPayloadAttributes = self.additionalPayloadAttributes; + appSwitchRequest = browserSwitchRequest; + } + + break; + } + default: { + break; + } + } + + if (appSwitchRequest) { + appSwitchRequest.targetAppURLScheme = configurationRecipe.targetAppURLScheme; + appSwitchRequest.responseType = PPAppSwitchResponseTypeAuthorizationCode; + appSwitchRequest.scope = [self.scopeValues allObjects]; + // mandatory field + appSwitchRequest.merchantName = [PPOTAppSwitchUtil bundleName]; + appSwitchRequest.privacyURL = [self.privacyURL absoluteString]; + appSwitchRequest.agreementURL = [self.agreementURL absoluteString]; + } + + return appSwitchRequest; +} + +#pragma mark - configuration methods + +- (BOOL)scopeIsSupportedByConfigurationRecipe:(PPOTConfigurationOAuthRecipe *)configurationRecipe { + if ([configurationRecipe.scope count] == 1 && [configurationRecipe.scope containsObject:@"*"]) { + return YES; + } + + return ([self.scopeValues isSubsetOfSet:configurationRecipe.scope]); +} + +- (void)getAppropriateConfigurationRecipe:(void (^)(PPOTConfigurationRecipe *configurationRecipe))completionBlock { + PPAssert(completionBlock, @"getAppropriateConfigurationRecipe: completionBlock is required"); + + PPOTConfiguration *currentConfiguration = [PPOTConfiguration getCurrentConfiguration]; + PPOTConfigurationOAuthRecipe *bestConfigurationRecipe = nil; + for (PPOTConfigurationOAuthRecipe *configurationRecipe in currentConfiguration.prioritizedOAuthRecipes) { + if (![self scopeIsSupportedByConfigurationRecipe:configurationRecipe]) { + continue; + } + + if (![self isConfigurationRecipeTargetSupported:configurationRecipe] || + ![self isConfigurationRecipeLocaleSupported:configurationRecipe]) { + continue; + } + + bestConfigurationRecipe = configurationRecipe; + break; + } + + completionBlock(bestConfigurationRecipe); +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAuthorizationRequest_Internal.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAuthorizationRequest_Internal.h new file mode 100644 index 0000000..65cc69a --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTAuthorizationRequest_Internal.h @@ -0,0 +1,19 @@ +// +// PPOTAuthorizationRequest_Internal.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTRequest.h" + +@interface PPOTAuthorizationRequest () + ++ (instancetype)requestWithScopeValues:(NSSet *)scopeValues + privacyURL:(NSURL *)privacyURL + agreementURL:(NSURL *)agreementURL + clientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTBillingAgreementRequest.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTBillingAgreementRequest.m new file mode 100644 index 0000000..82ed2ac --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTBillingAgreementRequest.m @@ -0,0 +1,79 @@ +// +// PPOTBillingAgreementRequest.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTRequest_Internal.h" +#import "PPOTCheckoutAppSwitchRequest.h" +#import "PPOTCheckoutBrowserSwitchRequest.h" +#import "PPOTConfiguration.h" +#import "PPOTDevice.h" +#import "PPOTMacros.h" + +#pragma mark - PPOTBillingAgreementRequest implementation + +@implementation PPOTBillingAgreementRequest + +#pragma mark - add subclass-specific info to appSwitchRequest + +- (PPOTSwitchRequest *)getAppSwitchRequestForConfigurationRecipe:(PPOTConfigurationRecipe *)configurationRecipe { + + PPOTCheckoutSwitchRequest *appSwitchRequest = nil; + + switch (configurationRecipe.target) { + case PPOTRequestTargetOnDeviceApplication: { + appSwitchRequest = [[PPOTCheckoutAppSwitchRequest alloc] initWithProtocolVersion:configurationRecipe.protocolVersion + appGuid:[PPOTDevice appropriateIdentifier] + clientID:self.clientID + environment:self.environment + callbackURLScheme:self.callbackURLScheme + pairingId:self.pairingId]; + break; + } + case PPOTRequestTargetBrowser: { + PPOTCheckoutBrowserSwitchRequest *browserSwitchRequest = + [[PPOTCheckoutBrowserSwitchRequest alloc] initWithProtocolVersion:configurationRecipe.protocolVersion + appGuid:[PPOTDevice appropriateIdentifier] + clientID:self.clientID + environment:self.environment + callbackURLScheme:self.callbackURLScheme + pairingId:self.pairingId]; + appSwitchRequest = browserSwitchRequest; + break; + } + default: { + break; + } + } + + if (appSwitchRequest) { + appSwitchRequest.targetAppURLScheme = configurationRecipe.targetAppURLScheme; + appSwitchRequest.responseType = PPAppSwitchResponseTypeWeb; + appSwitchRequest.approvalURL = [self.approvalURL absoluteString]; + } + + return appSwitchRequest; +} + +#pragma mark - configuration methods + +- (void)getAppropriateConfigurationRecipe:(void (^)(PPOTConfigurationRecipe *configurationRecipe))completionBlock { + PPAssert(completionBlock, @"getAppropriateConfigurationRecipe: completionBlock is required"); + + PPOTConfiguration *currentConfiguration = [PPOTConfiguration getCurrentConfiguration]; + PPOTConfigurationBillingAgreementRecipe *bestConfigurationRecipe = nil; + for (PPOTConfigurationBillingAgreementRecipe *configurationRecipe in currentConfiguration.prioritizedBillingAgreementRecipes) { + if (![self isConfigurationRecipeTargetSupported:configurationRecipe] || + ![self isConfigurationRecipeLocaleSupported:configurationRecipe]) { + continue; + } + bestConfigurationRecipe = configurationRecipe; + break; + } + + completionBlock(bestConfigurationRecipe); +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutAppSwitchRequest.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutAppSwitchRequest.h new file mode 100644 index 0000000..c4cbde6 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutAppSwitchRequest.h @@ -0,0 +1,12 @@ +// +// PPOTCheckoutAppSwitchRequest.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTCheckoutSwitchRequest.h" + +@interface PPOTCheckoutAppSwitchRequest : PPOTCheckoutSwitchRequest + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutAppSwitchRequest.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutAppSwitchRequest.m new file mode 100644 index 0000000..eef6a33 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutAppSwitchRequest.m @@ -0,0 +1,23 @@ +// +// PPOTCheckoutAppSwitchRequest.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTCheckoutAppSwitchRequest.h" +#import "PPOTMacros.h" + +@implementation PPOTCheckoutAppSwitchRequest + +- (NSDictionary *)payloadDictionary { + + NSMutableDictionary *payload = [[super payloadDictionary] mutableCopy]; + + payload[kPPOTAppSwitchAppGuidKey] = self.appGuid; + payload[kPPOTAppSwitchWebURLKey] = self.approvalURL; + + return payload; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutBrowserSwitchRequest.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutBrowserSwitchRequest.h new file mode 100644 index 0000000..ef81742 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutBrowserSwitchRequest.h @@ -0,0 +1,12 @@ +// +// PPOTCheckoutBrowserSwitchRequest.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTCheckoutSwitchRequest.h" + +@interface PPOTCheckoutBrowserSwitchRequest : PPOTCheckoutSwitchRequest + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutBrowserSwitchRequest.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutBrowserSwitchRequest.m new file mode 100644 index 0000000..f77aed0 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutBrowserSwitchRequest.m @@ -0,0 +1,40 @@ +// +// PPOTCheckoutBrowserSwitchRequest.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTCheckoutBrowserSwitchRequest.h" +#import "PPOTAppSwitchUtil.h" +#import "PPOTPersistentRequestData.h" +#import "PPOTTime.h" +#import "PPOTString.h" +#import "PPOTMacros.h" + +// TODO: have a factory/builder/json reader of sandbox, mock, etc + +@interface PPOTCheckoutBrowserSwitchRequest () +@property (nonatomic, readwrite) NSString *msgID; +@end + +@implementation PPOTCheckoutBrowserSwitchRequest + +- (NSURL *)encodedURL { + return [NSURL URLWithString:self.approvalURL]; +} + +- (void)addDataToPersistentRequestDataDictionary:(NSMutableDictionary *)requestDataDictionary { + [super addDataToPersistentRequestDataDictionary:requestDataDictionary]; + + NSString *queryString = [self.approvalURL componentsSeparatedByString:@"?"][1]; + NSDictionary *queryDictionary = [PPOTAppSwitchUtil parseQueryString:queryString]; + NSString *hermesToken = queryDictionary[kPPOTAppSwitchHermesTokenKey]; + if (hermesToken == nil) { + hermesToken = queryDictionary[kPPOTAppSwitchHermesBATokenKey]; + } + requestDataDictionary[kPPOTRequestDataDataDictionaryHermesTokenKey] = FORCE_VALUE_OR_NULL(hermesToken); + requestDataDictionary[kPPOTRequestDataDataDictionaryEnvironmentKey] = FORCE_VALUE_OR_NULL(self.environment); +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutRequest.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutRequest.m new file mode 100644 index 0000000..16366b8 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutRequest.m @@ -0,0 +1,130 @@ +// +// PPOTCheckoutRequest.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTRequest_Internal.h" +#import "PPOTCheckoutAppSwitchRequest.h" +#import "PPOTCheckoutBrowserSwitchRequest.h" +#import "PPOTConfiguration.h" +#import "PPOTDevice.h" +#import "PPOTMacros.h" + +#pragma mark - PPOTCheckoutRequest implementation + +@implementation PPOTCheckoutRequest + +- (instancetype)initWithApprovalURL:(NSURL *)approvalURL + pairingId:(NSString *)pairingId + clientID:(NSString *)clientID environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme { + if (!approvalURL + || ([environment isEqualToString:PPRequestEnvironmentProduction] + && ![approvalURL.absoluteString hasPrefix:@"https://"])) { + PPSDKLog(@"invalid approval URL, or scheme is not https:"); + return nil; + } + + NSDictionary *queryDictionary = [PPOTAppSwitchUtil parseQueryString:[approvalURL query]]; + NSString *hermesToken = queryDictionary[kPPOTAppSwitchHermesTokenKey]; + if (!hermesToken) { + hermesToken = queryDictionary[kPPOTAppSwitchHermesBATokenKey]; + } + + if (!hermesToken) { + PPSDKLog(@"approval URL lacks a Hermes token"); + return nil; + } + + self = [super initWithClientID:clientID environment:environment callbackURLScheme:callbackURLScheme]; + if (self) { + _approvalURL = approvalURL; + + _pairingId = pairingId; + } + return self; +} + ++ (instancetype)requestWithApprovalURL:(NSURL *)approvalURL + clientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme { + return [PPOTCheckoutRequest requestWithApprovalURL:approvalURL pairingId:nil clientID:clientID environment:environment callbackURLScheme:callbackURLScheme]; +} + ++ (instancetype)requestWithApprovalURL:(NSURL *)approvalURL + pairingId:(NSString *)pairingId + clientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme { + PPOTCheckoutRequest *request = [[[self class] alloc] initWithApprovalURL:approvalURL + pairingId:pairingId + clientID:clientID + environment:environment + callbackURLScheme:callbackURLScheme]; + return request; +} + +#pragma mark - add subclass-specific info to appSwitchRequest + +- (PPOTSwitchRequest *)getAppSwitchRequestForConfigurationRecipe:(PPOTConfigurationRecipe *)configurationRecipe { + + PPOTCheckoutSwitchRequest *appSwitchRequest = nil; + + switch (configurationRecipe.target) { + case PPOTRequestTargetOnDeviceApplication: { + appSwitchRequest = [[PPOTCheckoutAppSwitchRequest alloc] initWithProtocolVersion:configurationRecipe.protocolVersion + appGuid:[PPOTDevice appropriateIdentifier] + clientID:self.clientID + environment:self.environment + callbackURLScheme:self.callbackURLScheme + pairingId:self.pairingId]; + break; + } + case PPOTRequestTargetBrowser: { + PPOTCheckoutBrowserSwitchRequest *browserSwitchRequest = + [[PPOTCheckoutBrowserSwitchRequest alloc] initWithProtocolVersion:configurationRecipe.protocolVersion + appGuid:[PPOTDevice appropriateIdentifier] + clientID:self.clientID + environment:self.environment + callbackURLScheme:self.callbackURLScheme + pairingId:self.pairingId]; + appSwitchRequest = browserSwitchRequest; + break; + } + default: { + break; + } + } + + if (appSwitchRequest) { + appSwitchRequest.targetAppURLScheme = configurationRecipe.targetAppURLScheme; + appSwitchRequest.responseType = PPAppSwitchResponseTypeWeb; + appSwitchRequest.approvalURL = [self.approvalURL absoluteString]; + } + + return appSwitchRequest; +} + +#pragma mark - configuration methods + +- (void)getAppropriateConfigurationRecipe:(void (^)(PPOTConfigurationRecipe *configurationRecipe))completionBlock { + PPAssert(completionBlock, @"getAppropriateConfigurationRecipe: completionBlock is required"); + + PPOTConfiguration *currentConfiguration = [PPOTConfiguration getCurrentConfiguration]; + PPOTConfigurationCheckoutRecipe *bestConfigurationRecipe = nil; + for (PPOTConfigurationCheckoutRecipe *configurationRecipe in currentConfiguration.prioritizedCheckoutRecipes) { + if (![self isConfigurationRecipeTargetSupported:configurationRecipe] || + ![self isConfigurationRecipeLocaleSupported:configurationRecipe]) { + continue; + } + bestConfigurationRecipe = configurationRecipe; + break; + } + + completionBlock(bestConfigurationRecipe); +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutRequest_Internal.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutRequest_Internal.h new file mode 100644 index 0000000..59a1d96 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutRequest_Internal.h @@ -0,0 +1,42 @@ +// +// PPOTCheckoutRequest_Internal.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTRequest.h" + +@interface PPOTCheckoutRequest () + +/** + @brief Factory method. Non-empty values for all parameters MUST be provided. + + @param approvalURL Client has already created a payment on PayPal server; this is the resulting HATEOS ApprovalURL + @param clientID The app's Client ID, as obtained from developer.paypal.com + @param environment PayPalEnvironmentProduction, PayPalEnvironmentMock, or PayPalEnvironmentSandbox; + or else a stage indicated as `base-url:port` + @param callbackURLScheme The URL scheme to be used for returning to this app, following an app-switch +*/ ++ (nullable instancetype)requestWithApprovalURL:(nonnull NSURL *)approvalURL + clientID:(nonnull NSString *)clientID + environment:(nonnull NSString *)environment + callbackURLScheme:(nonnull NSString *)callbackURLScheme; + +/** + @brief Factory method. Only pairingId can be nil. + + @param approvalURL Client has already created a payment on PayPal server; this is the resulting HATEOS ApprovalURL + @param pairingId The pairingId for the risk component + @param clientID The app's Client ID, as obtained from developer.paypal.com + @param environment PayPalEnvironmentProduction, PayPalEnvironmentMock, or PayPalEnvironmentSandbox; + or else a stage indicated as `base-url:port` + @param callbackURLScheme The URL scheme to be used for returning to this app, following an app-switch +*/ ++ (nullable instancetype)requestWithApprovalURL:(nonnull NSURL *)approvalURL + pairingId:(nullable NSString *)pairingId + clientID:(nonnull NSString *)clientID + environment:(nonnull NSString *)environment + callbackURLScheme:(nonnull NSString *)callbackURLScheme; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutSwitchRequest.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutSwitchRequest.h new file mode 100644 index 0000000..5231396 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutSwitchRequest.h @@ -0,0 +1,14 @@ +// +// PPOTCheckoutSwitchRequest.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTSwitchRequest.h" + +@interface PPOTCheckoutSwitchRequest : PPOTSwitchRequest + +@property (nonatomic) NSString *approvalURL; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutSwitchRequest.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutSwitchRequest.m new file mode 100644 index 0000000..7fa9053 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCheckoutSwitchRequest.m @@ -0,0 +1,12 @@ +// +// PPOTCheckoutSwitchRequest.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTCheckoutSwitchRequest.h" + +@implementation PPOTCheckoutSwitchRequest + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCore.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCore.m new file mode 100644 index 0000000..d0ec4aa --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCore.m @@ -0,0 +1,143 @@ +// +// PPOTCore.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTCore.h" +#import "PPOTCore_Internal.h" +#import "PPOTResult_Internal.h" +#import "PPOTRequest_Internal.h" +#import "PPOTConfiguration.h" +#import "PPOTDevice.h" +#import "PPOTMacros.h" +#import "PPOTPersistentRequestData.h" +#import "PPDataCollector.h" +#import "PPOTVersion.h" + +// PayPalTouch v1 version +#import "PPOTAppSwitchUtil.h" + +#define kPPOTSafariViewService CARDIO_STR(@"com.apple.safariviewservice") +#define kPPOTSafariSourceApplication CARDIO_STR(@"com.apple.mobilesafari") + +@implementation PPOTCore + ++ (void)initialize { + if (self == [PPOTCore class]) { + [PPOTConfiguration updateCacheAsNecessary]; // called by all public methods + } +} + ++ (BOOL)doesApplicationSupportOneTouchCallbackURLScheme:(NSString *)callbackURLScheme { + [PPOTConfiguration updateCacheAsNecessary]; // called by all public methods + + BOOL doesSupport = NO; + // checks the callbackURLScheme is present and app responds to it. + doesSupport = [PPOTAppSwitchUtil isCallbackURLSchemeValid:callbackURLScheme]; + return doesSupport; +} + ++ (BOOL)isWalletAppInstalled { + [PPOTConfiguration updateCacheAsNecessary]; // called by all public methods + + return NO; +} + ++ (BOOL)canParseURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication { + [PPOTConfiguration updateCacheAsNecessary]; // called by all public methods + + BOOL canHandle = NO; + canHandle = ([PPOTCore isSourceApplicationValid:sourceApplication] + && [PPOTCore isValidURLAction:url]); + return canHandle; +} + ++ (void)parseResponseURL:(NSURL *)url completionBlock:(PPOTCompletionBlock)completionBlock { + [PPOTConfiguration updateCacheAsNecessary]; // called by all public methods + + PPAssert(completionBlock, @"parseOneTouchResponseURL:completionBlock: completionBlock is required"); + + [PPOTResult parseURL:url completionBlock:completionBlock]; +} + ++ (void)redirectURLsForCallbackURLScheme:(NSString *)callbackURLScheme withReturnURL:(NSString * __autoreleasing *)returnURL withCancelURL:(NSString * __autoreleasing *)cancelURL { + [PPOTConfiguration updateCacheAsNecessary]; // called by all public methods + + [PPOTAppSwitchUtil redirectURLsForCallbackURLScheme:callbackURLScheme withReturnURL:returnURL withCancelURL:cancelURL]; +} + ++ (BOOL)isSourceApplicationValid:(NSString *)sourceApplication { + if (!sourceApplication.length) { + return NO; + } + + PPOTPersistentRequestData *persistentRequestData = [PPOTPersistentRequestData fetch]; + PPOTConfigurationRecipe *configurationRecipe = persistentRequestData.configurationRecipe; + if (!configurationRecipe) { + return NO; + } + + sourceApplication = [sourceApplication lowercaseString]; + + for (NSString *bundleID in configurationRecipe.targetAppBundleIDs) { + NSUInteger asteriskLocation = [bundleID rangeOfString:@"*"].location; + NSString *bundleIDMask = asteriskLocation == NSNotFound ? bundleID : [bundleID substringToIndex:asteriskLocation]; + if ([sourceApplication hasPrefix:bundleIDMask]) { + return YES; + } + } + + if ([sourceApplication isEqualToString:kPPOTSafariSourceApplication] || [sourceApplication isEqualToString:kPPOTSafariViewService] ) { + return YES; + } + + return NO; +} + ++ (BOOL)isValidURLAction:(NSURL *)urlAction { + if (![PPOTAppSwitchUtil isValidURLAction:urlAction]) { + return NO; + } + + PPOTPersistentRequestData *persistentRequestData = [PPOTPersistentRequestData fetch]; + PPOTConfigurationRecipe *configurationRecipe = persistentRequestData.configurationRecipe; + NSDictionary *queryDictionary = [PPOTAppSwitchUtil parseQueryString:[urlAction query]]; + + if (!persistentRequestData || !configurationRecipe || !queryDictionary) { + return NO; + } + + if ([configurationRecipe.protocolVersion integerValue] == 0) { + NSString *requestHermesToken = persistentRequestData.requestData[kPPOTRequestDataDataDictionaryHermesTokenKey]; +// NSString *responseHermesToken = queryDictionary[kPPOTAppSwitchHermesBATokenKey]; +// if (responseHermesToken == nil) { +// responseHermesToken = queryDictionary[kPPOTAppSwitchHermesTokenKey]; +// } + if (![requestHermesToken length]) { + return NO; + } + } else { + if (![queryDictionary[kPPOTAppSwitchPayloadKey] length]) { + return NO; + } + + // For now, we only check the value of x-source in the case of Wallet-switch. + // Ultimately, we might want to agree on what x-source should be for a browser-switch (Hermes). + if (configurationRecipe.target == PPOTRequestTargetOnDeviceApplication && + ![self isSourceApplicationValid:queryDictionary[kPPOTAppSwitchXSourceKey]]) { + return NO; + } + } + + return YES; +} + ++ (NSString *)libraryVersion { + [PPOTConfiguration updateCacheAsNecessary]; // called by all public methods + + return PayPalOTVersion(); +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCore_Internal.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCore_Internal.h new file mode 100644 index 0000000..9aa572a --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTCore_Internal.h @@ -0,0 +1,21 @@ +// +// PPOTCore_Internal.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTCore.h" + +// eg PayPalSDK/OneTouchCore-iOS 1.2.1-g1234567-dirty (iOS 8.1; iPhone 6+; DEBUG) +#ifdef DEBUG +#define PP_PRODUCT_STRING [NSString stringWithFormat:@"PayPalSDK/OneTouchCore-iOS %@ (%@; %@; %@)", PayPalOTVersion(), [PPOTDevice deviceName], [PPOTDevice hardwarePlatform], @"DEBUG"] +#else +#define PP_PRODUCT_STRING [NSString stringWithFormat:@"PayPalSDK/OneTouchCore-iOS %@ (%@; %@; %@)", PayPalOTVersion(), [PPOTDevice deviceName], [PPOTDevice hardwarePlatform], @"RELEASE"] +#endif + +@interface PPOTCore () + ++ (BOOL)isValidURLAction:(NSURL *)urlAction; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTError.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTError.h new file mode 100644 index 0000000..e8fff64 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTError.h @@ -0,0 +1,26 @@ +// +// PPOTError.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import +#import "PPOTCore.h" + +@interface PPOTError : NSObject + +/** + @param errorCode the error code to use + @return NSError with the code given +*/ ++ (NSError *)errorWithErrorCode:(PPOTErrorCode)errorCode; + +/** + @param errorCode the error code to use + @param userInfo the error's info dictionary + @return NSError with the code given +*/ ++ (NSError *)errorWithErrorCode:(PPOTErrorCode)errorCode userInfo:(NSDictionary *)userInfo; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTError.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTError.m new file mode 100644 index 0000000..2466a6a --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTError.m @@ -0,0 +1,20 @@ +// +// PPOTError.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTError.h" + +@implementation PPOTError + ++ (NSError *)errorWithErrorCode:(PPOTErrorCode)errorCode { + return [self errorWithErrorCode:errorCode userInfo:nil]; +} + ++ (NSError *)errorWithErrorCode:(PPOTErrorCode)errorCode userInfo:(NSDictionary *)userInfo { + return [NSError errorWithDomain:kPayPalOneTouchErrorDomain code:errorCode userInfo:userInfo]; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2AppSwitchRequest.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2AppSwitchRequest.h new file mode 100644 index 0000000..254093f --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2AppSwitchRequest.h @@ -0,0 +1,12 @@ +// +// PPOTOAuth2AppSwitchRequest.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTOAuth2SwitchRequest.h" + +@interface PPOTOAuth2AppSwitchRequest : PPOTOAuth2SwitchRequest + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2AppSwitchRequest.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2AppSwitchRequest.m new file mode 100644 index 0000000..9c36dc9 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2AppSwitchRequest.m @@ -0,0 +1,22 @@ +// +// PPOTOAuth2AppSwitchRequest.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTOAuth2AppSwitchRequest.h" + +@implementation PPOTOAuth2AppSwitchRequest + +- (NSDictionary *)payloadDictionary { + NSMutableDictionary *payload = [[super payloadDictionary] mutableCopy]; + + if (self.appGuid.length) { + payload[kPPOTAppSwitchAppGuidKey] = self.appGuid; + } + + return payload; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2BrowserSwitchRequest.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2BrowserSwitchRequest.h new file mode 100644 index 0000000..c6a7349 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2BrowserSwitchRequest.h @@ -0,0 +1,41 @@ +// +// PPOTOAuth2BrowserSwitchRequest.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTOAuth2SwitchRequest.h" + +@interface PPOTOAuth2BrowserSwitchRequest : PPOTOAuth2SwitchRequest + +/** + @brief endpoint to which the browser should be directed +*/ +@property (nonatomic) NSString *endpoint; + +/** + @brief the serial number extracted from the X.509 cert, which was used to encrypt the payloadEnc field. +*/ +@property (nonatomic) NSString *keyID; + +/** + @brief a one time unique ID generated for this payment request +*/ +@property (nonatomic, readonly) NSString *msgID; + +/** + @brief hexadecimal representation of 256-bit symmetric AES key +*/ +@property (nonatomic) NSString *encryptionKey; + +/** + @brief additional key/value pairs that OTC will add to the payload + + @discussion (For example, the Braintree client_token, which is required by the temporary Braintree Future Payments consent webpage.) +*/ +@property (nonatomic) NSDictionary *additionalPayloadAttributes; + +@property (nonatomic) NSData *certificate; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2BrowserSwitchRequest.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2BrowserSwitchRequest.m new file mode 100644 index 0000000..5f910e7 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2BrowserSwitchRequest.m @@ -0,0 +1,91 @@ +// +// PPOTOAuth2BrowserSwitchRequest.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTOAuth2BrowserSwitchRequest.h" +#import "PPOTTime.h" +#import "PPOTString.h" +#import "PPOTMacros.h" +#import "PPOTPersistentRequestData.h" +#import "PPOTJSONHelper.h" +#import "PPOTEncryptionHelper.h" + + +@interface PPOTOAuth2BrowserSwitchRequest () +@property (nonatomic, readwrite) NSString *msgID; +@end + +@implementation PPOTOAuth2BrowserSwitchRequest + +- (NSString *)msgID { + if (!_msgID.length) { + _msgID = [PPOTString generateUniquishIdentifier]; + } + return _msgID; +} + +- (NSDictionary *)payloadDictionary { + NSMutableDictionary *payload = [[super payloadDictionary] mutableCopy]; + + payload[kPPOTAppSwitchKeyIDKey] = FORCE_VALUE_OR_NULL(self.keyID); + + if (self.additionalPayloadAttributes.count) { + for (id key in self.additionalPayloadAttributes) { + // avoid overriding defaults + if (![payload objectForKey:key]) { + payload[key] = FORCE_VALUE_OR_NULL(self.additionalPayloadAttributes[key]); + } + } + } + return payload; +} + +- (NSData *)encryptedPayload { + NSMutableDictionary *unencryptedPayload = [NSMutableDictionary dictionaryWithCapacity:6]; + unencryptedPayload[kPPOTAppSwitchTimestampKey] = FORCE_VALUE_OR_NULL([[PPOTTime rfc3339DateFormatter] stringFromDate:[NSDate date]]); + unencryptedPayload[kPPOTAppSwitchMsgGUIDKey] = FORCE_VALUE_OR_NULL(self.msgID); + //unencryptedPayload[kPPOTAppSwitchAppGuidKey] = FORCE_VALUE_OR_NULL(self.appGuid); + unencryptedPayload[kPPOTAppSwitchSymKey] = FORCE_VALUE_OR_NULL(self.encryptionKey); + NSString *currentDeviceName = [[UIDevice currentDevice] name]; + if (currentDeviceName != nil && ![currentDeviceName isEqualToString:@""]) { + unencryptedPayload[kPPOTAppSwitchKeyDeviceName] = FORCE_VALUE_OR_NULL(currentDeviceName); + } + + NSData *data = [NSJSONSerialization dataWithJSONObject:unencryptedPayload options:0 error:nil]; + if (!data) { + return nil; + } + + NSData *cipherData = [PPOTEncryptionHelper encryptRSAData:data certificate:self.certificate]; + return cipherData; +} + +- (NSURL *)encodedURL { + NSDictionary *payload = [self payloadDictionary]; + NSData *encryptedPayload = [self encryptedPayload]; + if (!encryptedPayload) { + return nil; + } + NSURL *url = [PPOTAppSwitchUtil URLAction:self.endpoint callbackURLScheme:self.callbackURLScheme payload:payload]; + // cheat for now and add encrypted payload + NSString *urlString = [url absoluteString]; + NSString *encodedEncryptedPayload = [encryptedPayload base64EncodedStringWithOptions:0]; + encodedEncryptedPayload = [PPOTString stringByURLEncodingAllCharactersInString:encodedEncryptedPayload]; + NSString *urlQuery = [NSString stringWithFormat:@"&%@=%@",kPPOTAppSwitchEncryptedPayloadKey, encodedEncryptedPayload]; + urlString = [urlString stringByAppendingString:urlQuery]; + + url = [NSURL URLWithString:urlString]; + + return url; +} + +- (void)addDataToPersistentRequestDataDictionary:(NSMutableDictionary *)requestDataDictionary { + [super addDataToPersistentRequestDataDictionary:requestDataDictionary]; + requestDataDictionary[kPPOTRequestDataDataDictionaryMsgIdKey] = FORCE_VALUE_OR_NULL(self.msgID); + requestDataDictionary[kPPOTRequestDataDataDictionaryEncryptionKey] = FORCE_VALUE_OR_NULL(self.encryptionKey); +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2SwitchRequest.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2SwitchRequest.h new file mode 100644 index 0000000..067266a --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2SwitchRequest.h @@ -0,0 +1,18 @@ +// +// PPOTOAuth2SwitchRequest.h +// PayPalOneTouch +// +// Copyright © 2014 PayPal, Inc. All rights reserved. +// + +#import +#import "PPOTSwitchRequest.h" + +@interface PPOTOAuth2SwitchRequest : PPOTSwitchRequest + +@property (nonatomic, strong, readwrite) NSArray *scope; +@property (nonatomic, strong, readwrite) NSString *merchantName; +@property (nonatomic, strong, readwrite) NSString *privacyURL; +@property (nonatomic, strong, readwrite) NSString *agreementURL; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2SwitchRequest.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2SwitchRequest.m new file mode 100644 index 0000000..159868f --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTOAuth2SwitchRequest.m @@ -0,0 +1,40 @@ +// +// PPOTOAuth2SwitchRequest.m +// PayPalOneTouch +// +// Copyright © 2014 PayPal, Inc. All rights reserved. +// + +#import "PPOTOAuth2SwitchRequest.h" +#import "PPOTMacros.h" + +@implementation PPOTOAuth2SwitchRequest + +- (NSDictionary *)payloadDictionary { + NSMutableDictionary *payload = [[super payloadDictionary] mutableCopy]; + + if (self.scope.count) { + payload[kPPOTAppSwitchScopesKey] = [self.scope componentsJoinedByString:@" "]; + } + + if (self.customURL.length) { + payload[kPPOTAppSwitchEnvironmentURLKey] = self.customURL; + } + + if (self.privacyURL.length) { + payload[kPPOTAppSwitchPrivacyURLKey] = self.privacyURL; + } + + if (self.agreementURL.length) { + payload[kPPOTAppSwitchAgreementURLKey] = self.agreementURL; + } + + if (self.merchantName.length) { + // update name, the reason it can be localized or maybe more complete and shortcuted for better display + payload[kPPOTAppSwitchAppNameKey] = self.merchantName; + } + + return payload; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTPersistentRequestData.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTPersistentRequestData.h new file mode 100644 index 0000000..72451fc --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTPersistentRequestData.h @@ -0,0 +1,31 @@ +// +// PPOTPersistentRequestData.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import +#import "PPOTMacros.h" + +#define kPPOTRequestDataDataDictionaryMsgIdKey CARDIO_STR(@"msg_id") +#define kPPOTRequestDataDataDictionaryEncryptionKey CARDIO_STR(@"encryption_key") +#define kPPOTRequestDataDataDictionaryHermesTokenKey CARDIO_STR(@"hermes_token") +#define kPPOTRequestDataDataDictionaryEnvironmentKey CARDIO_STR(@"environment") + +@class PPOTSwitchRequest; +@class PPOTConfigurationRecipe; + +@interface PPOTPersistentRequestData : NSObject + +@property (nonatomic, strong, readwrite) PPOTConfigurationRecipe *configurationRecipe; +@property (nonatomic, strong, readwrite) NSString *environment; +@property (nonatomic, strong, readwrite) NSString *clientID; +@property (nonatomic, strong, readwrite) NSMutableDictionary *requestData; + ++ (PPOTPersistentRequestData *)fetch; ++ (void)storeWithConfigurationRecipe:(PPOTConfigurationRecipe *)configurationRecipe + withRequest:(PPOTSwitchRequest *)request; ++ (void)remove; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTPersistentRequestData.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTPersistentRequestData.m new file mode 100644 index 0000000..89498ec --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTPersistentRequestData.m @@ -0,0 +1,76 @@ +// +// PPOTPersistentRequestData.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTPersistentRequestData.h" +#import "PPOTOAuth2SwitchRequest.h" +#import "PPOTConfiguration.h" +#import "PPOTMacros.h" +#import "PPOTSimpleKeychain.h" + +#define kPPOTCoderKeyRequestDataConfigurationRecipe CARDIO_STR(@"configuration_recipe") +#define kPPOTCoderKeyRequestDataEnvironment CARDIO_STR(@"environment") +#define kPPOTCoderKeyRequestDataClientID CARDIO_STR(@"client_id") +#define kPPOTCoderKeyRequestDataDataDictionary CARDIO_STR(@"data_dictionary") + +#define kPPOTKeychainRequestSpecificData CARDIO_STR(@"PayPal_OTC_RequestData") + +@implementation PPOTPersistentRequestData + +#pragma mark - initializer + +- (instancetype)initWithConfigurationRecipe:(PPOTConfigurationRecipe *)configurationRecipe + withRequest:(PPOTSwitchRequest *)request { + if ((self = [super init])) { + _configurationRecipe = configurationRecipe; + _environment = request.environment; + _clientID = request.clientID; + _requestData = [NSMutableDictionary dictionary]; + [request addDataToPersistentRequestDataDictionary:_requestData]; + } + return self; +} + +#pragma mark - NSCoding + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if ((self = [super init])) { + _configurationRecipe = [aDecoder decodeObjectForKey:kPPOTCoderKeyRequestDataConfigurationRecipe]; + _environment = [aDecoder decodeObjectForKey:kPPOTCoderKeyRequestDataEnvironment]; + _clientID = [aDecoder decodeObjectForKey:kPPOTCoderKeyRequestDataClientID]; + _requestData = [aDecoder decodeObjectForKey:kPPOTCoderKeyRequestDataDataDictionary]; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.configurationRecipe forKey:kPPOTCoderKeyRequestDataConfigurationRecipe]; + [aCoder encodeObject:self.environment forKey:kPPOTCoderKeyRequestDataEnvironment]; + [aCoder encodeObject:self.clientID forKey:kPPOTCoderKeyRequestDataClientID]; + [aCoder encodeObject:self.requestData forKey:kPPOTCoderKeyRequestDataDataDictionary]; +} + +#pragma mark - keychain + ++ (PPOTPersistentRequestData *)fetch { + return [PPOTSimpleKeychain unarchiveObjectWithDataForKey:kPPOTKeychainRequestSpecificData]; +} + ++ (void)storeWithConfigurationRecipe:(PPOTConfigurationRecipe *)configurationRecipe + withRequest:(PPOTSwitchRequest *)request { + + PPOTPersistentRequestData *persistentRequestData = [[PPOTPersistentRequestData alloc] + initWithConfigurationRecipe:configurationRecipe withRequest:request]; + + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:persistentRequestData]; + [PPOTSimpleKeychain setData:data forKey:kPPOTKeychainRequestSpecificData]; +} + ++ (void)remove { + [PPOTSimpleKeychain setData:nil forKey:kPPOTKeychainRequestSpecificData]; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTRequest.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTRequest.m new file mode 100644 index 0000000..41fadfc --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTRequest.m @@ -0,0 +1,246 @@ +// +// PPOTRequest.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTRequest_Internal.h" +#import "PPOTAnalyticsDefines.h" +#import "PPOTAppSwitchUtil.h" +#import "PPOTConfiguration.h" +#import "PPOTDevice.h" +#import "PPOTMacros.h" +#import "PPOTOAuth2SwitchRequest.h" +#import "PPOTAnalyticsTracker.h" +#import "PPOTPersistentRequestData.h" +#import "PPOTError.h" + +#import + +NSString *const PayPalEnvironmentProduction = PPRequestEnvironmentProduction; +NSString *const PayPalEnvironmentSandbox = PPRequestEnvironmentSandbox; +NSString *const PayPalEnvironmentMock = PPRequestEnvironmentNoNetwork; + +#define kPPOTAppSwitchSchemeToCheck CARDIO_STR(@"http") + +@implementation PPOTRequest + +#pragma mark - initialization + ++ (void)initialize { + if (self == [PPOTRequest class]) { + [PPOTConfiguration updateCacheAsNecessary]; // called by all public methods + } +} + +- (instancetype)initWithClientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme { + if (!clientID.length) { + PPSDKLog(@"clientID is required."); + return nil; + } + + if (!environment.length) { + PPSDKLog(@"environment is required."); + return nil; + } + + if (![PPOTAppSwitchUtil isCallbackURLSchemeValid:callbackURLScheme]) { + PPSDKLog(@"callbackURLScheme is not configured or nil."); + return nil; + } + + self = [super init]; + if (self) { + _clientID = clientID; + _environment = environment; + _callbackURLScheme = callbackURLScheme; + + [PPOTConfiguration updateCacheAsNecessary]; // called by all public methods + } + + return self; + +} + +#pragma mark - public methods + +- (void)getTargetApp:(PPOTRequestPreflightCompletionBlock)completionBlock { + PPAssert(completionBlock, @"getTargetApp: completionBlock is required"); + + [PPOTConfiguration updateCacheAsNecessary]; // called by all public methods + + [self determineConfigurationRecipe:^{ + NSString *analyticsPage = nil; + switch (self.configurationRecipe.target) { + case PPOTRequestTargetBrowser: + analyticsPage = kAnalyticsAppSwitchPreflightBrowser; + break; + case PPOTRequestTargetOnDeviceApplication: + analyticsPage = kAnalyticsAppSwitchPreflightWallet; + break; + case PPOTRequestTargetNone: + default: + analyticsPage = kAnalyticsAppSwitchPreflightNone; + break; + } + + NSString *protocol = [NSString stringWithFormat:@"v%ld", self.configurationRecipe.protocolVersion.longValue]; + analyticsPage = [analyticsPage stringByAppendingString:protocol]; + + [[PPOTAnalyticsTracker sharedManager] trackPage:analyticsPage + environment:self.environment + clientID:self.clientID + error:nil + hermesToken:nil]; + + completionBlock(self.configurationRecipe.target); + }]; +} + +- (void)performWithAdapterBlock:(PPOTRequestAdapterBlock)adapterBlock { + PPAssert(adapterBlock, @"performWithAdapterBlock: adapterBlock is required"); + + [PPOTConfiguration updateCacheAsNecessary]; // called by all public methods + + [self determineConfigurationRecipe:^{ + BOOL success = YES; + PPOTRequestTarget target = PPOTRequestTargetNone; + NSError *error = nil; + NSString *requestClientMetadataId = nil; + NSURL *appSwitchURL = nil; + if (self.configurationRecipe) { + PPOTSwitchRequest *appSwitchRequest = [self getAppSwitchRequestForConfigurationRecipe:self.configurationRecipe]; + if (appSwitchRequest) { + appSwitchURL = [appSwitchRequest encodedURL]; + requestClientMetadataId = appSwitchRequest.clientMetadataID; + + NSString *analyticsPage = nil; + if ([[appSwitchURL.absoluteString lowercaseString] hasPrefix:kPPOTAppSwitchSchemeToCheck]) { + target = PPOTRequestTargetBrowser; + analyticsPage = kAnalyticsAppSwitchToBrowser; + } + else { + target = PPOTRequestTargetOnDeviceApplication; + analyticsPage = kAnalyticsAppSwitchToWallet; + } + + NSString *protocol = [NSString stringWithFormat:@"v%ld", self.configurationRecipe.protocolVersion.longValue]; + analyticsPage = [analyticsPage stringByAppendingString:protocol]; + + [PPOTPersistentRequestData storeWithConfigurationRecipe:self.configurationRecipe withRequest:appSwitchRequest]; + + + NSString *hermesToken = nil; + if ([self respondsToSelector:@selector(approvalURL)]) { + NSDictionary *queryDictionary = [PPOTAppSwitchUtil parseQueryString:[[self performSelector:@selector(approvalURL)] query]]; + hermesToken = queryDictionary[kPPOTAppSwitchHermesTokenKey]; + } + + [[PPOTAnalyticsTracker sharedManager] trackPage:analyticsPage + environment:self.environment + clientID:self.clientID + error:error + hermesToken:hermesToken]; + } else { + success = NO; + error = [PPOTError errorWithErrorCode:PPOTErrorCodeNoTargetAppFound]; + } + } else { + PPSDKLog(@"No appropriate configuration recipe found"); + success = NO; + error = [PPOTError errorWithErrorCode:PPOTErrorCodeNoTargetAppFound]; + } + adapterBlock(success, appSwitchURL, target, requestClientMetadataId, error); + }]; +} + +#pragma mark - add subclass-specific info to appSwitchRequest + +- (PPOTSwitchRequest *)getAppSwitchRequestForConfigurationRecipe:(__attribute__((unused)) PPOTConfigurationRecipe *)configurationRecipe { + PPAssert(NO, @"getAppSwitchRequestForConfigurationRecipe: subclass of PPOTRequest must override"); + return nil; +} + +#pragma mark - configuration methods + +- (void)determineConfigurationRecipe:(void (^)(void))completionBlock { + PPAssert(completionBlock, @"establishConfigurationRecipe: completionBlock is required"); + + if (self.configurationRecipe) { + completionBlock(); + return; + } + +#if DEBUG + [PPOTConfiguration useHardcodedConfiguration:self.useHardcodedConfiguration]; +#endif + + [self getAppropriateConfigurationRecipe:^(PPOTConfigurationRecipe *configurationRecipe) { + self.configurationRecipe = configurationRecipe; + completionBlock(); + }]; +} + +- (void)getAppropriateConfigurationRecipe:(__attribute__((unused)) void (^)(PPOTConfigurationRecipe *configurationRecipe))completionBlock { + PPAssert(NO, @"subclass must override"); +} + +- (BOOL)isConfigurationRecipeTargetSupported:(PPOTConfigurationRecipe *)configurationRecipe { + // Confirm that the recipe's target is available (Browser is always installed; Wallet may or may not be installed), + // and also that the recipe's target is not rejected by `self.forcedTarget`. + + switch (configurationRecipe.target) { + case PPOTRequestTargetOnDeviceApplication: { + return NO; + } + case PPOTRequestTargetBrowser: { + if (self.forcedTarget.integerValue == PPOTRequestTargetOnDeviceApplication) { + return NO; + } + return YES; + } + default: { + return NO; + } + } +} + +- (BOOL)isConfigurationRecipeLocaleSupported:(PPOTConfigurationRecipe *)configurationRecipe { + if (![configurationRecipe.supportedLocales count]) { + return YES; + } + + return [configurationRecipe.supportedLocales containsObject:[[PPOTDevice complicatedDeviceLocale] uppercaseString]]; +} + +#pragma mark - utility method + +#define kPPOTAppSwitchHermesTokenKey @"token" +#define kPPOTAppSwitchBillingAgreementTokenKey @"ba_token" + ++ (NSString *)tokenFromApprovalURL:(NSURL *)approvalURL { + NSDictionary *queryDictionary = [PPOTRequest parseQueryString:[approvalURL query]]; + return queryDictionary[kPPOTAppSwitchHermesTokenKey] ?: queryDictionary[kPPOTAppSwitchBillingAgreementTokenKey]; +} + ++ (NSDictionary *)parseQueryString:(NSString *)query { + NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:6]; + NSArray *pairs = [query componentsSeparatedByString:@"&"]; + + for (NSString *pair in pairs) { + NSArray *elements = [pair componentsSeparatedByString:@"="]; + if (elements.count > 1) { + NSString *key = [[elements objectAtIndex:0] stringByRemovingPercentEncoding]; + NSString *val = [[elements objectAtIndex:1] stringByRemovingPercentEncoding]; + if (key.length && val.length) { + dict[key] = val; + } + } + } + return dict; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTRequestFactory.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTRequestFactory.m new file mode 100644 index 0000000..2116109 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTRequestFactory.m @@ -0,0 +1,73 @@ +// +// PPOTRequestFactory.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTRequestFactory.h" + +#import "PPOTCheckoutRequest_Internal.h" +#import "PPOTAuthorizationRequest_Internal.h" + +@implementation PPOTRequestFactory + ++ (nullable PPOTCheckoutRequest *)checkoutRequestWithApprovalURL:(nonnull NSURL *)approvalURL + clientID:(nonnull NSString *)clientID + environment:(nonnull NSString *)environment + callbackURLScheme:(nonnull NSString *)callbackURLScheme { + return [PPOTCheckoutRequest requestWithApprovalURL:approvalURL + clientID:clientID + environment:environment + callbackURLScheme:callbackURLScheme]; +} + ++ (nullable PPOTCheckoutRequest *)checkoutRequestWithApprovalURL:(nonnull NSURL *)approvalURL + pairingId:(nullable NSString *)pairingId + clientID:(nonnull NSString *)clientID + environment:(nonnull NSString *)environment + callbackURLScheme:(nonnull NSString *)callbackURLScheme { + return [PPOTCheckoutRequest requestWithApprovalURL:approvalURL + pairingId:pairingId + clientID:clientID + environment:environment + callbackURLScheme:callbackURLScheme]; +} + ++ (nullable PPOTAuthorizationRequest *)authorizationRequestWithScopeValues:(nonnull NSSet *)scopeValues + privacyURL:(nonnull NSURL *)privacyURL + agreementURL:(nonnull NSURL *)agreementURL + clientID:(nonnull NSString *)clientID + environment:(nonnull NSString *)environment + callbackURLScheme:(nonnull NSString *)callbackURLScheme { + return [PPOTAuthorizationRequest requestWithScopeValues:scopeValues + privacyURL:privacyURL + agreementURL:agreementURL + clientID:clientID + environment:environment + callbackURLScheme:callbackURLScheme]; +} + ++ (nullable PPOTBillingAgreementRequest *)billingAgreementRequestWithApprovalURL:(nonnull NSURL *)approvalURL + clientID:(nonnull NSString *)clientID + environment:(nonnull NSString *)environment + callbackURLScheme:(nonnull NSString *)callbackURLScheme { + return [PPOTBillingAgreementRequest requestWithApprovalURL:approvalURL + clientID:clientID + environment:environment + callbackURLScheme:callbackURLScheme]; +} + ++ (nullable PPOTBillingAgreementRequest *)billingAgreementRequestWithApprovalURL:(nonnull NSURL *)approvalURL + pairingId:(nullable NSString *)pairingId + clientID:(nonnull NSString *)clientID + environment:(nonnull NSString *)environment + callbackURLScheme:(nonnull NSString *)callbackURLScheme { + return [PPOTBillingAgreementRequest requestWithApprovalURL:approvalURL + pairingId:pairingId + clientID:clientID + environment:environment + callbackURLScheme:callbackURLScheme]; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTRequest_Internal.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTRequest_Internal.h new file mode 100644 index 0000000..854c025 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTRequest_Internal.h @@ -0,0 +1,62 @@ +// +// PPOTRequest_Internal.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTRequest.h" + +@class PPOTSwitchRequest; +@class PPOTConfigurationRecipe; + +// All requests must have this +@interface PPOTRequest () + +// mandatory fields + +/** + @brief All requests MUST include the app's Client ID, as obtained from developer.paypal.com +*/ +@property (nonatomic, readwrite) NSString *clientID; + +/** + @discussion All requests MUST indicate the environment - PayPalEnvironmentProduction, PayPalEnvironmentMock, or PayPalEnvironmentSandbox; + or else a stage indicated as `base-url:port` +*/ +@property (nonatomic, readwrite) NSString *environment; + +/** + @brief All requests MUST indicate the URL scheme to be used for returning to this app, following an app-switch +*/ +@property (nonatomic, readwrite) NSString *callbackURLScheme; + +/** + @brief If client calls getTargetApp:, then cache the result here for later use by performWithCompletionBlock:. +*/ +@property (nonatomic, readwrite) PPOTConfigurationRecipe *configurationRecipe; + +/** + @brief Recipe behavior override, for debugging purposes only. + + @discussion PPOTRequestTargetBrowser - always switch to browser; i.e., ignore all Wallet recipes + PPOTRequestTargetOnDeviceApplication - always switch to Wallet; i.e., ignore all Browser recipes + PPOTRequestTargetNone or PayPalOneTouchRequestTargetUnknown - obey recipes +*/ +@property (nonatomic, readwrite) NSNumber *forcedTarget; + +- (instancetype)initWithClientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme; + +/** + @brief subclasses must override +*/ +- (PPOTSwitchRequest *)getAppSwitchRequestForConfigurationRecipe:(PPOTConfigurationRecipe *)configurationRecipe; + +- (void)getAppropriateConfigurationRecipe:(void (^)(PPOTConfigurationRecipe *configurationRecipe))completionBlock; +- (BOOL)isConfigurationRecipeTargetSupported:(PPOTConfigurationRecipe *)configurationRecipe; +- (BOOL)isConfigurationRecipeLocaleSupported:(PPOTConfigurationRecipe *)configurationRecipe; + +@end + diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTResult.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTResult.m new file mode 100644 index 0000000..e6fff6e --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTResult.m @@ -0,0 +1,192 @@ +// +// PPOTResult.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import +#import "PPOTResult_Internal.h" +#import "PPOTCore_Internal.h" +#import "PPOTAppSwitchResponse.h" +#import "PPOTConfiguration.h" +#import "PPOTDevice.h" +#import "PPOTError.h" +#import "PPOTMacros.h" +#import "PPOTAnalyticsTracker.h" +#import "PPOTVersion.h" +#import "PPOTPersistentRequestData.h" +#import "PPOTAnalyticsDefines.h" + +#define PP_TIMESTAMP_TIMEOUT 10*60 // 10 minutes + +@implementation PPOTResult + ++ (void)parseURL:(NSURL *)url completionBlock:(PPOTCompletionBlock)completionBlock { + PPAssert(completionBlock, @"parseURL:completionBlock: completionBlock is required"); + PPOTResult *result = nil; + PPOTPersistentRequestData *persistentRequestData = [PPOTPersistentRequestData fetch]; + + NSString *analyticsPage = kAnalyticsAppSwitchCancel; + NSError *analyticsError = nil; + + BOOL valid = [PPOTCore isValidURLAction:url]; + if (valid) { + PPOTConfigurationRecipe *configurationRecipe = persistentRequestData.configurationRecipe; + PPOTAppSwitchResponse *response = nil; + + if ([configurationRecipe.protocolVersion integerValue] == 0) { + // Note: Token (Hermes) validation performed inside of isValidURLAction: + // TODO: consider moving here + response = [[PPOTAppSwitchResponse alloc] initWithHermesURL:url + environment:persistentRequestData.requestData[kPPOTRequestDataDataDictionaryEnvironmentKey]]; + } else { + NSString *encryptionKey = persistentRequestData.requestData[kPPOTRequestDataDataDictionaryEncryptionKey]; + response = [[PPOTAppSwitchResponse alloc] initWithEncodedURL:url encryptionKey:encryptionKey]; + + // TODO: make better + if (response.validResponse && response.version > 2) { + NSString *requestMsgID = persistentRequestData.requestData[kPPOTRequestDataDataDictionaryMsgIdKey]; + NSNumber *protocol = configurationRecipe.protocolVersion; + + if (response.version != [protocol integerValue]) { + valid = NO; + } + + if (![requestMsgID isEqualToString:response.msgID]) { + if (requestMsgID != nil || response.msgID != nil) { + valid = NO; + } + } + + if (valid && + [[response.timeStamp dateByAddingTimeInterval:PP_TIMESTAMP_TIMEOUT] + compare:[NSDate date]] == NSOrderedAscending) { + valid = NO; + } + } + } + + if (valid && response.validResponse && response.action == PPAppSwitchResponseActionSuccess) { + result = [self resultWithSuccess:response]; + analyticsPage = kAnalyticsAppSwitchReturn; + } else if (response.action == PPAppSwitchResponseActionCancel) { + result = [self resultWithCancel:response]; + } else { + result = [self resultWithError]; + analyticsError = result.error; + } + + result.target = configurationRecipe.target; + } else { + if (!persistentRequestData) { + result = [self resultWithPersistedRequestDataFetchError]; + } else { + result = [self resultWithError]; + } + result.target = PPOTRequestTargetUnknown; + analyticsError = result.error; + } + + // Protect parameters against missing persistentRequestData: + [[PPOTAnalyticsTracker sharedManager] trackPage:analyticsPage + environment:persistentRequestData.environment ? persistentRequestData.environment : @"" + clientID:persistentRequestData.clientID ? persistentRequestData.clientID : @"" + error:analyticsError + hermesToken:persistentRequestData.requestData[kPPOTRequestDataDataDictionaryHermesTokenKey]]; + + completionBlock(result); +} + ++ (PPOTResult *)resultWithSuccess:(PPOTAppSwitchResponse *)response { + PPOTResult *result = [PPOTResult new]; + result.type = PPOTResultTypeSuccess; + NSMutableDictionary *resultDictionary = [@{@"client": @{@"platform": @"iOS", + @"paypal_sdk_version": PayPalOTVersion(), + @"environment" : FORCE_VALUE_OR_NULL(response.environment), + @"product_name": PP_PRODUCT_STRING, + }, + } mutableCopy]; + + if (response.responseType == PPAppSwitchResponseTypeAuthorizationCode) { + + [resultDictionary addEntriesFromDictionary:@{@"response_type" : @"authorization_code", + @"response" : @{@"code": FORCE_VALUE_OR_NULL(response.authorizationCode)}, + @"user": @{@"display_string" : FORCE_VALUE_OR_NULL(response.email)}, + }]; + + + } else if (response.responseType == PPAppSwitchResponseTypeWeb) { + + [resultDictionary addEntriesFromDictionary:@{@"response_type" : @"web", + @"response" : @{@"webURL": FORCE_VALUE_OR_NULL(response.webURL)}, + }]; + + + } else { + NSString *error = [NSString stringWithFormat:CARDIO_STR(@"App Switch: Unexpected response type: %@"), @(response.responseType)]; + PPLog(@"%@", error); + result.type = PPOTResultTypeError; + result.error = [self errorUserInfo:@{kPPOTAppSwitchMessageKey: error}]; + } + result.response = resultDictionary; + return result; +} + ++ (PPOTResult *)resultWithCancel:(PPOTAppSwitchResponse *)response { + PPOTResult *result = [PPOTResult new]; + if (response.error.count) { + PPLog(@"App Switch Error: %@", response.error); + result.type = PPOTResultTypeError; + result.error = [self errorUserInfo:response.error]; + } else { + PPLog(@"App Switch Cancelled"); + result.type = PPOTResultTypeCancel; + } + return result; +} + ++ (PPOTResult *)resultWithError { + NSError *error = [self errorUserInfo:@{kPPOTAppSwitchMessageKey:CARDIO_STR(@"App Switch Invalid URL")}]; + return [self resultWithSpecificError:error]; +} + ++ (PPOTResult *)resultWithPersistedRequestDataFetchError { + NSDictionary *userInfo = @{kPPOTAppSwitchMessageKey:CARDIO_STR(@"Could not retrieve persisted request data")}; + NSError *error = [PPOTError errorWithErrorCode:PPOTErrorCodePersistedDataFetchFailed userInfo:userInfo]; + return [self resultWithSpecificError:error]; +} + ++ (PPOTResult *)resultWithSpecificError:(NSError *)error { + PPOTResult *result = [PPOTResult new]; + result.type = PPOTResultTypeError; + result.error = error; + return result; +} + ++ (NSError *)errorUserInfo:(NSDictionary *)dictionary { + return [PPOTError errorWithErrorCode:PPOTErrorCodeParsingFailed userInfo:dictionary]; +} + +- (NSString *)description { + NSMutableString *description = [NSMutableString string]; + + NSString *typeName; + switch (self.type) { + case PPOTResultTypeSuccess: typeName = @"Success"; break; + case PPOTResultTypeCancel: typeName = @"Cancel"; break; + case PPOTResultTypeError: typeName = @"Error"; break; + } + + [description appendFormat:@"PPOTResult (type: %@)\n", typeName]; + if (self.response) { + [description appendFormat:@" Result Dictionary: %@\n", [self.response description]]; + } + if (self.error) { + [description appendFormat:@" Error: %@\n", [self.error description]]; + } + return description; +} + +@end + diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTResult_Internal.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTResult_Internal.h new file mode 100644 index 0000000..1fad5c6 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTResult_Internal.h @@ -0,0 +1,19 @@ +// +// PPOTCore_Internal.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTCore.h" + +@interface PPOTResult () + +@property (nonatomic, readwrite, assign) PPOTResultType type; +@property (nonatomic, readwrite, copy) NSDictionary *response; +@property (nonatomic, readwrite, copy) NSError *error; +@property (nonatomic, readwrite, assign) PPOTRequestTarget target; + ++ (void)parseURL:(NSURL *)url completionBlock:(PPOTCompletionBlock)completionBlock; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTSwitchRequest.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTSwitchRequest.h new file mode 100644 index 0000000..7423873 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTSwitchRequest.h @@ -0,0 +1,43 @@ +// +// PPOTSwitchRequest.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import +#import "PPOTAppSwitchUtil.h" + +@interface PPOTSwitchRequest : NSObject + +@property (nonatomic, readonly) NSNumber *protocolVersion; +@property (nonatomic, readonly) NSString *appGuid; +@property (nonatomic, readonly) NSString *clientID; +@property (nonatomic, readonly) NSString *environment; +@property (nonatomic, readonly) NSString *callbackURLScheme; +@property (nonatomic, readonly) NSString *clientMetadataID; + +@property (nonatomic, strong, readwrite) NSString *targetAppURLScheme; +@property (nonatomic, assign, readwrite) PPAppSwitchResponseType responseType; +@property (nonatomic, strong, readwrite) NSString *customURL; + +- (instancetype)initWithProtocolVersion:(NSNumber *)protocolVersion + appGuid:(NSString *)appGuid + clientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme; + +- (instancetype)initWithProtocolVersion:(NSNumber *)protocolVersion + appGuid:(NSString *)appGuid + clientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme + pairingId:(NSString *)pairingId; + +- (NSDictionary *)payloadDictionary; // used by v1, v2, v3 protocols (but not v0) + +- (NSURL *)encodedURL; + +- (void)addDataToPersistentRequestDataDictionary:(NSMutableDictionary *)requestDataDictionary; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTSwitchRequest.m b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTSwitchRequest.m new file mode 100644 index 0000000..b4adb4d --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Models/PPOTSwitchRequest.m @@ -0,0 +1,104 @@ +// +// PPOTSwitchRequest.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTSwitchRequest.h" +#import "PPOTMacros.h" +#import "PPDataCollector_Internal.h" + +@implementation PPOTSwitchRequest + +- (instancetype)initWithProtocolVersion:(NSNumber *)protocolVersion + appGuid:(NSString *)appGuid + clientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme { + return [self initWithProtocolVersion:protocolVersion appGuid:appGuid clientID:clientID environment:environment callbackURLScheme:callbackURLScheme pairingId:nil]; +} + +- (instancetype)initWithProtocolVersion:(NSNumber *)protocolVersion + appGuid:(NSString *)appGuid + clientID:(NSString *)clientID + environment:(NSString *)environment + callbackURLScheme:(NSString *)callbackURLScheme + pairingId:(NSString *)pairingId { + self = [super init]; + if (self) { + _protocolVersion = protocolVersion; + _appGuid = appGuid; + _clientID = clientID; + _environment = environment; + _responseType = PPAppSwitchResponseTypeUnknown; + _callbackURLScheme = callbackURLScheme; + _clientMetadataID = [PPDataCollector generateClientMetadataID:pairingId]; + } + return self; +} + +- (NSDictionary *)payloadDictionary { + + // mangle with environment for name "custom" + NSString *environment = self.environment; + if (![environment isEqualToString:PPRequestEnvironmentProduction] && ![environment isEqualToString:PPRequestEnvironmentNoNetwork] && + ![environment isEqualToString:PPRequestEnvironmentSandbox]) { + // extract baseURL + NSURL *serviceURL = [NSURL URLWithString:environment]; + if (!serviceURL.host.length) { + serviceURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://%@", environment]]; + } + self.customURL = [NSString stringWithFormat:@"%@://%@:%@", serviceURL.scheme, serviceURL.host, serviceURL.port]; + environment = kPPOTAppSwitchCustomEnvironmentKey; + } + + NSMutableDictionary *payload = [NSMutableDictionary dictionaryWithCapacity:11]; + + payload[kPPOTAppSwitchProtocolVersionKey] = self.protocolVersion; + payload[kPPOTAppSwitchClientIdKey] = [self.clientID copy]; + // use environment or custom + payload[kPPOTAppSwitchEnvironmentKey] = [environment copy]; + payload[kPPOTAppSwitchAppNameKey] = FORCE_VALUE_OR_NULL([PPOTAppSwitchUtil bundleName]); + + switch (self.responseType) { + case PPAppSwitchResponseTypeToken: + payload[kPPOTAppSwitchResponseTypeKey] = kPPOTAppSwitchResponseTypeToken; + break; + case PPAppSwitchResponseTypeAuthorizationCode: + payload[kPPOTAppSwitchResponseTypeKey] = kPPOTAppSwitchResponseTypeCode; + break; + case PPAppSwitchResponseTypeWeb: + payload[kPPOTAppSwitchResponseTypeKey] = kPPOTAppSwitchResponseTypeWeb; + break; + default: + PPAssert(YES, @"Response type unsupported"); + break; + } + + if (self.customURL.length) { + payload[kPPOTAppSwitchEnvironmentURLKey] = self.customURL; + } + + // dyson pairing id + payload[kPPOTAppSwitchMetadataClientIDKey] = FORCE_VALUE_OR_NULL(self.clientMetadataID); + + return payload; +} + +// default version of encodedURL (for v1, v2, and v3) +- (NSURL *)encodedURL { + NSDictionary *payload = [self payloadDictionary]; + + NSURL *url = [PPOTAppSwitchUtil URLAction:kPPOTAppSwitchAuthenticateAction + targetAppURLScheme:self.targetAppURLScheme + callbackURLScheme:self.callbackURLScheme + payload:payload]; + return url; +} + +- (void)addDataToPersistentRequestDataDictionary:(__attribute__((unused)) NSMutableDictionary *)requestDataDictionary { + // subclasses each call [super] add then add their own relevant data, if any, to be retrieved when the response comes back to us +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Public/PPOTCore.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Public/PPOTCore.h new file mode 100644 index 0000000..bd42989 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Public/PPOTCore.h @@ -0,0 +1,85 @@ +// +// PPOTCore.h +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +// Required Frameworks for the library. Additionally, make sure to set OTHER_LDFLAGS = -ObjC +#import +#import +#import + +#import +#import "PPOTResult.h" + +/** + @brief Completion block for receiving the result of performing a request +*/ +typedef void (^PPOTCompletionBlock)(PPOTResult * _Nonnull result); + +@interface PPOTCore : NSObject + +/** + @brief Check if the application is configured correctly to handle responses for One Touch flow. + + @param callbackURLScheme The URL scheme which the app has registered for One Touch responses. + @return `YES` iff the application is correctly configured. +*/ ++ (BOOL)doesApplicationSupportOneTouchCallbackURLScheme:(nonnull NSString *)callbackURLScheme; + +/** + @brief Check whether the PayPal Wallet app is installed on this device (iOS <= 8). + + @discussion Universal links are used in iOS >=9 so the check is not performed + + @return `YES` if the wallet app is installed +*/ ++ (BOOL)isWalletAppInstalled; + +/** + @brief Check whether the URL and source application are recognized and valid for One Touch. + + @discussion Usually called as a result of the `UIApplicationDelegate`'s + `- (BOOL)application:openURL:sourceApplication:annotation:` method + to determine if the URL is intended for the One Touch library. + + (To then actually process the URL, call `+ (void)parseOneTouchURL:completionBlock`.) + + @param url The URL of the app switch request + @param sourceApplication The bundle ID of the source application + + @return `YES` iff the URL and sending app are both valid. +*/ ++ (BOOL)canParseURL:(nonnull NSURL *)url sourceApplication:(nullable NSString *)sourceApplication; + +/** + @brief Process a URL response. + + @param url The URL to process + @param completionBlock completion block for receiving the result of performing a request +*/ ++ (void)parseResponseURL:(nonnull NSURL *)url completionBlock:(nonnull PPOTCompletionBlock)completionBlock; + +/** + @brief URLs to return control from the browser/wallet to the app containing the One Touch library. + + @discussion For payment processing, the client's server will first create a payment on the PayPal server. + Creating that payment requires, among many other things, a `redirect_urls` object containing two strings: + `return_url` and `cancel_url`. + + @note Both return values will be `nil` if [PPOTCore doesApplicationSupportOneTouchCallbackURLScheme:callbackURLScheme] is not true. + + @param callbackURLScheme The URL scheme which the app has registered for One Touch responses. + @param returnURL A string containing the `return_url`. + @param cancelURL A string containing the `cancel_url`. +*/ ++ (void)redirectURLsForCallbackURLScheme:(nonnull NSString *)callbackURLScheme withReturnURL:(NSString * _Nonnull * _Nonnull)returnURL withCancelURL:(NSString * _Nonnull * _Nonnull)cancelURL; + +/** + @brief The version of the SDK library in use. Version numbering follows http://semver.org/. + + @note Please be sure to include this library version in tech support requests. +*/ ++ (nonnull NSString *)libraryVersion; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Public/PPOTRequest.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Public/PPOTRequest.h new file mode 100644 index 0000000..310194c --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Public/PPOTRequest.h @@ -0,0 +1,146 @@ +// +// PPOTRequest.h +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import +#import "PPOTResult.h" + +/** + @brief Completion block for receiving the result of preflighting a request +*/ +typedef void (^PPOTRequestPreflightCompletionBlock) (PPOTRequestTarget target); + +/** + @brief Adapter block for app switching. +*/ +typedef void (^PPOTRequestAdapterBlock) (BOOL success, NSURL * _Nonnull url, PPOTRequestTarget target, NSString * _Nullable clientMetadataId, NSError * _Nullable error); + +/** + @brief This environment MUST be used for App Store submissions. +*/ +extern NSString * _Nonnull const PayPalEnvironmentProduction; + +/** + @brief Sandbox: Uses the PayPal sandbox for transactions. Useful for development. +*/ +extern NSString * _Nonnull const PayPalEnvironmentSandbox; + +/** + @brief Mock: Mock mode. Does not submit transactions to PayPal. Fakes successful responses. Useful for unit tests. +*/ +extern NSString * _Nonnull const PayPalEnvironmentMock; + +/** + @brief Base class for all One Touch requests +*/ +@interface PPOTRequest : NSObject + +/** + @brief Optional preflight method, to determine in advance to which app we will switch when this request's `performWithCompletionBlock:` method is called. + + @note As currently implemented, `completionBlock` will be called synchronously. + We use a completion block here to allow for future changes in implementation that might cause + delays (such as time-consuming cryptographic operations, or server interactions). +*/ +- (void)getTargetApp:(nullable PPOTRequestPreflightCompletionBlock)completionBlock; + +/** + @brief Ask the One Touch library to carry out a request. + + @discussion Will app switch to the PayPal Wallet app if present, or to the mobile browser otherwise. + + @param adapterBlock Block that makes the URL request. + + @note The adapter block is responsible for determining which app to app switch to (Wallet, browser, or neither). + The `completionBlock` is called synchronously. + We use a completion block here to allow for future changes in implementation that might cause + delays (such as time-consuming cryptographic operations, or server interactions). +*/ +- (void)performWithAdapterBlock:(nullable PPOTRequestAdapterBlock)adapterBlock; + +/** + @brief Get token from approval URL +*/ ++ (nullable NSString *)tokenFromApprovalURL:(nonnull NSURL *)approvalURL; + +/** + @brief All requests MUST include the app's Client ID, as obtained from developer.paypal.com +*/ +@property (nonnull, nonatomic, readonly) NSString *clientID; + +/** + @discussion All requests MUST indicate the environment - + `PayPalEnvironmentProduction`, `PayPalEnvironmentMock`, or `PayPalEnvironmentSandbox`; + or else a stage indicated as `base-url:port` +*/ +@property (nonnull, nonatomic, readonly) NSString *environment; + +/** + @brief All requests MUST indicate the URL scheme to be used for returning to this app, following an app switch +*/ +@property (nonnull, nonatomic, readonly) NSString *callbackURLScheme; + +/** + @brief Requests MAY include additional key/value pairs that One Touch will add to the payload + @discussion (For example, the Braintree client_token, which is required by the temporary Braintree Future Payments consent webpage.) +*/ +@property (nonnull, nonatomic, strong) NSDictionary *additionalPayloadAttributes; + +#if DEBUG +/** + @brief DEBUG-only: don't use downloaded configuration file; defaults to NO +*/ +@property (nonatomic, assign, readwrite) BOOL useHardcodedConfiguration; +#endif + +@end + + +/** + @brief Request consent for Profile Sharing (e.g., for Future Payments) +*/ +@interface PPOTAuthorizationRequest : PPOTRequest + +/** + @brief Set of requested scope-values. + + @discussion Available scope-values are listed at https://developer.paypal.com/webapps/developer/docs/integration/direct/identity/attributes/ +*/ +@property (nonnull, nonatomic, readonly) NSSet *scopeValues; + +/** + @brief The URL of the merchant's privacy policy +*/ +@property (nonnull, nonatomic, readonly) NSURL *privacyURL; + +/** + @brief The URL of the merchant's user agreement +*/ +@property (nonnull, nonatomic, readonly) NSURL *agreementURL; + +@end + + +/** + @brief Request approval of a payment +*/ +@interface PPOTCheckoutRequest : PPOTRequest + +@property (nonnull, nonatomic, strong) NSString *pairingId; + +/** + @brief Client has already created a payment on PayPal server; this is the resulting HATEOS ApprovalURL +*/ +@property (nonnull, nonatomic, readonly) NSURL *approvalURL; + +@end + +/** + @brief Request approval of a Billing Agreement +*/ +@interface PPOTBillingAgreementRequest : PPOTCheckoutRequest + +@end + diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Public/PPOTRequestFactory.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Public/PPOTRequestFactory.h new file mode 100644 index 0000000..f6750d7 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Public/PPOTRequestFactory.h @@ -0,0 +1,92 @@ +// +// PPOTRequestFactory.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import +#import "PPOTRequest.h" + +@interface PPOTRequestFactory : NSObject + +/** + @brief Factory method. Non-empty values for all parameters MUST be provided. + + @param approvalURL Client has already created a payment on PayPal server; this is the resulting HATEOS ApprovalURL + @param clientID The app's Client ID, as obtained from developer.paypal.com + @param environment `PayPalEnvironmentProduction`, `PayPalEnvironmentMock`, or `PayPalEnvironmentSandbox`; + or else a stage indicated as `base-url:port` + @param callbackURLScheme The URL scheme to be used for returning to this app, following an app-switch +*/ ++ (nullable PPOTCheckoutRequest *)checkoutRequestWithApprovalURL:(nonnull NSURL *)approvalURL + clientID:(nonnull NSString *)clientID + environment:(nonnull NSString *)environment + callbackURLScheme:(nonnull NSString *)callbackURLScheme; + +/** + @brief Factory method. Only `pairingId` can be nil. + + @param approvalURL Client has already created a payment on PayPal server; this is the resulting HATEOS ApprovalURL + @param pairingId The pairing ID for the risk component. Optional. + @param clientID The app's Client ID, as obtained from developer.paypal.com + @param environment `PayPalEnvironmentProduction`, `PayPalEnvironmentMock`, or `PayPalEnvironmentSandbox`; + or else a stage indicated as `base-url:port` + @param callbackURLScheme The URL scheme to be used for returning to this app, following an app-switch +*/ ++ (nullable PPOTCheckoutRequest *)checkoutRequestWithApprovalURL:(nonnull NSURL *)approvalURL + pairingId:(nullable NSString *)pairingId + clientID:(nonnull NSString *)clientID + environment:(nonnull NSString *)environment + callbackURLScheme:(nonnull NSString *)callbackURLScheme; + +/** + @brief Factory method. Non-empty values for all parameters MUST be provided. + + @param scopeValues Set of requested scope-values. + Available scope-values are listed at https://developer.paypal.com/webapps/developer/docs/integration/direct/identity/attributes/ + @param privacyURL The URL of the merchant's privacy policy + @param agreementURL The URL of the merchant's user agreement + @param clientID The app's Client ID, as obtained from developer.paypal.com + @param environment `PayPalEnvironmentProduction`, `PayPalEnvironmentMock`, or `PayPalEnvironmentSandbox`; + or else a stage indicated as `base-url:port` + @param callbackURLScheme The URL scheme to be used for returning to this app, following an app-switch +*/ ++ (nullable PPOTAuthorizationRequest *)authorizationRequestWithScopeValues:(nonnull NSSet *)scopeValues + privacyURL:(nonnull NSURL *)privacyURL + agreementURL:(nonnull NSURL *)agreementURL + clientID:(nonnull NSString *)clientID + environment:(nonnull NSString *)environment + callbackURLScheme:(nonnull NSString *)callbackURLScheme; + +/** + @brief Factory method. Non-empty values for all parameters MUST be provided. + + @param approvalURL Client has already created a payment on PayPal server; this is the resulting HATEOS ApprovalURL + @param clientID The app's Client ID, as obtained from developer.paypal.com + @param environment `PayPalEnvironmentProduction`, `PayPalEnvironmentMock`, or `PayPalEnvironmentSandbox`; + or else a stage indicated as `base-url:port` + @param callbackURLScheme The URL scheme to be used for returning to this app, following an app-switch +*/ ++ (nullable PPOTBillingAgreementRequest *)billingAgreementRequestWithApprovalURL:(nonnull NSURL *)approvalURL + clientID:(nonnull NSString *)clientID + environment:(nonnull NSString *)environment + callbackURLScheme:(nonnull NSString *)callbackURLScheme; + +/** + @brief Factory method. Only pairingId can be nil. + + @param approvalURL Client has already created a payment on PayPal server; this is the resulting HATEOS ApprovalURL + @param pairingId The pairing ID for the risk component. Optional. + @param clientID The app's Client ID, as obtained from developer.paypal.com + @param environment `PayPalEnvironmentProduction`, `PayPalEnvironmentMock`, or `PayPalEnvironmentSandbox`; + or else a stage indicated as `base-url:port` + @param callbackURLScheme The URL scheme to be used for returning to this app, following an app-switch +*/ ++ (nullable PPOTBillingAgreementRequest *)billingAgreementRequestWithApprovalURL:(nonnull NSURL *)approvalURL + pairingId:(nullable NSString *)pairingId + clientID:(nonnull NSString *)clientID + environment:(nonnull NSString *)environment + callbackURLScheme:(nonnull NSString *)callbackURLScheme; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Public/PPOTResult.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Public/PPOTResult.h new file mode 100644 index 0000000..d7d9a2f --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Public/PPOTResult.h @@ -0,0 +1,60 @@ +// +// PPOTResult.h +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +typedef NS_ENUM(NSInteger, PPOTRequestTarget) { + // No app switch will occur + PPOTRequestTargetNone, + // App switch to/from browser + PPOTRequestTargetBrowser, + // App switch to/from PayPal Consumer App + PPOTRequestTargetOnDeviceApplication, + // Response url was invalid; can't confirm source app's identity + PPOTRequestTargetUnknown, +}; + +#define kPayPalOneTouchErrorDomain @"com.paypal.onetouch.error" + +typedef NS_ENUM(NSInteger, PPOTErrorCode) { + PPOTErrorCodeUnknown = -1000, + PPOTErrorCodeParsingFailed = -1001, + PPOTErrorCodeNoTargetAppFound = -1002, + PPOTErrorCodeOpenURLFailed = -1003, + PPOTErrorCodePersistedDataFetchFailed = -1004, +}; + +typedef NS_ENUM(NSInteger, PPOTResultType) { + PPOTResultTypeError, + PPOTResultTypeCancel, + PPOTResultTypeSuccess, +}; + +/** + @brief The result of parsing the One Touch return URL +*/ +@interface PPOTResult : NSObject + +/** + @brief The status of the app switch +*/ +@property (nonatomic, readonly, assign) PPOTResultType type; + +/** + @brief When One Touch is successful, the response dictionary containing information that your server will need to process. +*/ +@property (nullable, nonatomic, readonly, copy) NSDictionary *response; + +/** + @brief When One Touch encounters an error, it is reported here. Otherwise this property will be `nil`. +*/ +@property (nullable, nonatomic, readonly, copy) NSError *error; + +/** + @brief The target app that is now switching back. +*/ +@property (nonatomic, readonly, assign) PPOTRequestTarget target; + +@end + diff --git a/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Public/PayPalOneTouch.h b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Public/PayPalOneTouch.h new file mode 100644 index 0000000..34b15eb --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalOneTouch/Public/PayPalOneTouch.h @@ -0,0 +1,18 @@ +// +// PayPalOneTouch.h +// PayPalOneTouch +// +// + +#import + +//! Project version number for PayPalOneTouch. +FOUNDATION_EXPORT double PayPalOneTouchVersionNumber; + +//! Project version string for PayPalOneTouch. +FOUNDATION_EXPORT const unsigned char PayPalOneTouchVersionString[]; + +#include "PPOTCore.h" +#include "PPOTResult.h" +#include "PPOTRequest.h" +#include "PPOTRequestFactory.h" diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTDevice.m b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTDevice.m new file mode 100644 index 0000000..99b9c34 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTDevice.m @@ -0,0 +1,114 @@ +// +// PPOTDevice.m +// Copyright © 2009 PayPal, Inc. All rights reserved. +// + +#import "PPOTDevice.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#import "PPOTSimpleKeychain.h" +#import "PPOTString.h" + +#define kKeychainDeviceIdentifier @"PayPal_MPL_DeviceGUID" +#define kPPOTOTDeviceFallbackCountryISOCode @"US" +#define kPPOTOTDeviceFallbackCountryDialingCode @"1" + +@implementation PPOTDevice + ++ (NSString *)hardwarePlatform { + size_t size; + sysctlbyname("hw.machine", NULL, &size, NULL, 0); + char *machine = malloc(size); + sysctlbyname("hw.machine", machine, &size, NULL, 0); + NSString *platform = [NSString stringWithUTF8String:machine]; + free(machine); + return platform; +} + ++ (NSString *)deviceName { + NSString *model = [[UIDevice currentDevice] model]; + NSString *deviceName = [NSString stringWithFormat:@"%@ (%@)", model, [PPOTDevice hardwarePlatform]]; + return deviceName; +} + + ++ (NSString *)complicatedDeviceLocale { + // Start with the device's current language: + NSString *deviceLocale = [NSLocale preferredLanguages][0]; + + // Treat dialect, if present, as region (except for Chinese, where it's a bit more than just a dialect): + // For example, "en-GB" ("British English", as of iOS 7) -> "en_GB"; and "en-GB_HK" -> "en_GB". + if (![deviceLocale hasPrefix:@"zh"]) { + if ([deviceLocale rangeOfString:@"-"].location != NSNotFound) { + NSUInteger underscoreLocation = [deviceLocale rangeOfString:@"_"].location; + if (underscoreLocation != NSNotFound) { + deviceLocale = [deviceLocale substringToIndex:underscoreLocation]; + } + deviceLocale = [deviceLocale stringByReplacingOccurrencesOfString:@"-" withString:@"_"]; + } + } + + // If no region is specified, then use the device's current locale (if the language matches): + if ([deviceLocale rangeOfString:@"_"].location == NSNotFound) { + NSString *deviceLanguage = [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]; + NSString *deviceRegion = [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode]; + if (!deviceRegion) { + // NSLocaleCountryCode can return nil if device's Region is set to English, Esperanto, etc. + deviceRegion = @""; + } + NSString *calculatedDeviceLocale; + if ([deviceRegion length]) { + calculatedDeviceLocale = [NSString stringWithFormat:@"%@_%@", deviceLanguage, deviceRegion]; + } else { + calculatedDeviceLocale = deviceLanguage; + } + + if ([deviceLanguage hasPrefix:deviceLocale]) { + deviceLocale = calculatedDeviceLocale; + } + else if ([deviceRegion length]) { + // For language-matching here, treat missing device dialect as wildcard; e.g, "zh" matches either "zh-Hans" or "zh-Hant": + NSUInteger targetHyphenLocation = [deviceLocale rangeOfString:@"-"].location; + if (targetHyphenLocation != NSNotFound) { + NSString *targetLanguage = [deviceLocale substringToIndex:targetHyphenLocation]; + if ([deviceLanguage hasPrefix:targetLanguage]) { + deviceLocale = [NSString stringWithFormat:@"%@_%@", deviceLocale, deviceRegion]; + } else if ([deviceLocale caseInsensitiveCompare:@"zh-Hant"] == NSOrderedSame && + ([deviceRegion isEqualToString:@"HK"] || [deviceRegion isEqualToString:@"TW"])) { + // Very special case: target language is zh-Hant, and device region is either xx_HK or xx_TW, + // for *any* "xx" (because device region could be en_HK or en_TW): + deviceLocale = [NSString stringWithFormat:@"%@_%@", deviceLocale, deviceRegion]; + } + } + } + } + + return deviceLocale; +} + ++ (NSString *)appropriateIdentifier { + // see if we already have one + NSString *appropriateId = [[NSString alloc] initWithData:[PPOTSimpleKeychain dataForKey:kKeychainDeviceIdentifier] + encoding:NSUTF8StringEncoding]; + // if not generate a new one and save + if (!appropriateId.length) { + appropriateId = [[NSUUID UUID] UUIDString]; + [PPOTSimpleKeychain setData:[appropriateId dataUsingEncoding:NSUTF8StringEncoding] forKey:kKeychainDeviceIdentifier]; + } + return appropriateId; +} + ++ (void)clearIdentifier { + [PPOTSimpleKeychain setData:nil forKey:kKeychainDeviceIdentifier]; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTEncryptionHelper.m b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTEncryptionHelper.m new file mode 100644 index 0000000..695ead1 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTEncryptionHelper.m @@ -0,0 +1,249 @@ +// +// PPOTEncryptionHelper.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTEncryptionHelper.h" +#import +#import +#import "PPOTMacros.h" + +@implementation PPOTEncryptionHelper + ++ (BOOL)compareSignatureData:(NSData *)data1 withData:(NSData *)data2 { + if (data1.length != data2.length) { + return NO; + } + + NSInteger result = 0; + uint8_t const *data1Ptr = [data1 bytes]; + uint8_t const *data2Ptr = [data2 bytes]; + for (unsigned int i = 0; i < data1.length; i++) { + result |= data1Ptr[i] ^ data2Ptr[i]; + } + return (result == 0); +} + ++ (NSData *)randomData:(NSUInteger)length { + NSMutableData *randomKey = [NSMutableData dataWithLength:length]; + int error = SecRandomCopyBytes(kSecRandomDefault, length, [randomKey mutableBytes]); + return (error == 0) ? randomKey : nil; +} + ++ (NSData *)generate256BitKey { + return [PPOTEncryptionHelper randomData:kCCKeySizeAES256]; +} + +// HMACSHA256 ++ (NSData *)dataDigest:(NSData *)data encryptionKey:(NSData *)encryptionKey { + NSMutableData* hash = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH]; + CCHmac(kCCHmacAlgSHA256, encryptionKey.bytes, encryptionKey.length, data.bytes, data.length, hash.mutableBytes); + return hash; +} + +#pragma mark - AES CTR ++ (NSData *)encryptAESCTRData:(NSData *)plainData encryptionKey:(NSData *)key { + if (key.length != kCCKeySizeAES256) { + // wrong key + PPSDKLog(@"encryptAESCTRData: Supplied key is not %@ bytes", @(kCCKeySizeAES256)); + return nil; + } + + NSData *nonce = [PPOTEncryptionHelper randomData:kCCKeySizeAES128]; + NSData *encryptionKey = [key subdataWithRange:NSMakeRange(0, kCCKeySizeAES128)]; + NSData *digestKey = [key subdataWithRange:NSMakeRange(16, kCCKeySizeAES128)]; + + // Init cryptor + CCCryptorRef cryptor = NULL; + CCCryptorStatus status = CCCryptorCreateWithMode(kCCEncrypt, + kCCModeCTR, + kCCAlgorithmAES, + ccNoPadding, + [nonce bytes], + [encryptionKey bytes], + encryptionKey.length, + 0, + 0, + 0, + kCCModeOptionCTR_BE,// deprecated and no longer used + &cryptor); + if (status != kCCSuccess) { + PPSDKLog(@"encryptAESCTRData: createWithMode error: %@", @(status)); + return nil; + } + + + size_t cipherDataSize = plainData.length + kCCKeySizeAES128 +1; // null terminator + uint8_t *cipherData = malloc(cipherDataSize); + memset(cipherData, 0, cipherDataSize); + + + size_t dataMoved; + // now re-use buffer to do decryption + status = CCCryptorUpdate(cryptor, [plainData bytes], [plainData length], cipherData, cipherDataSize, &dataMoved); + // note: there is no need to call CCCryptorFinal when no padding is used. + CCCryptorRelease(cryptor); + + // add logging + if (status != kCCSuccess) { + PPSDKLog(@"encryptAESCTRData: encryption error: %@", @(status)); + free(cipherData); + cipherData = NULL; + return nil; + } + + // concat nonce and cipher for signing + NSData *encryptedBlob = [NSData dataWithBytes:cipherData length:dataMoved]; + free(cipherData); + cipherData = NULL; + NSMutableData *signData = [NSMutableData dataWithCapacity:encryptedBlob.length + nonce.length]; + [signData appendData:nonce]; + [signData appendData:encryptedBlob]; + + // sign + NSData *digest = [PPOTEncryptionHelper dataDigest:signData encryptionKey:digestKey]; + + // construct encrypted payload = signature + nonce + encrypted blob + NSMutableData *payload = [NSMutableData dataWithCapacity:signData.length + digest.length]; + [payload appendData:digest]; + [payload appendData:signData]; + + return payload; +} + ++ (NSData *)decryptAESCTRData:(NSData *)cipherData encryptionKey:(NSData *)key { + if (key.length != kCCKeySizeAES256) { + // wrong key + PPSDKLog(@"decryptAESCTRData: Supplied key is not %@ bytes", @(kCCKeySizeAES256)); + return nil; + } + + if (cipherData.length < CC_SHA256_DIGEST_LENGTH + kCCKeySizeAES128) { + // we won't be able to decrypt, data sample too small + PPSDKLog(@"decryptAESCTRData: data is too small to decrypt"); + return nil; + } + + NSData *resultData = nil; + + NSData *encryptionKey = [key subdataWithRange:NSMakeRange(0, kCCKeySizeAES128)]; + NSData *digestKey = [key subdataWithRange:NSMakeRange(16, kCCKeySizeAES128)]; + + NSData *signature = [cipherData subdataWithRange:NSMakeRange(0, CC_SHA256_DIGEST_LENGTH)]; + NSData *digest = [PPOTEncryptionHelper dataDigest:[cipherData subdataWithRange:NSMakeRange(CC_SHA256_DIGEST_LENGTH, cipherData.length-CC_SHA256_DIGEST_LENGTH)] + encryptionKey:digestKey]; + + + if (![self compareSignatureData:signature withData:digest]) { + PPSDKLog(@"decryptAESCTRData: signature doesn't match"); + return nil; + } + + NSData *nonce = [cipherData subdataWithRange:NSMakeRange(CC_SHA256_DIGEST_LENGTH, kCCKeySizeAES128)]; + + // Init cryptor + CCCryptorRef cryptor = NULL; + CCCryptorStatus status = CCCryptorCreateWithMode(kCCDecrypt, + kCCModeCTR, + kCCAlgorithmAES, + ccNoPadding, + [nonce bytes], + [encryptionKey bytes], + encryptionKey.length, + 0, + 0, + 0, + kCCModeOptionCTR_BE, + &cryptor); + if (status != kCCSuccess) { + PPSDKLog(@"decryptAESCTRData: createWithMode error: %@", @(status)); + return nil; + } + + uint8_t *plainText = malloc(cipherData.length); // that's big enough + memset(plainText, 0, cipherData.length); + + const uint8_t *encryptionBlockPtr = [cipherData bytes] + CC_SHA256_DIGEST_LENGTH + kCCKeySizeAES128; // adjust pointer + size_t encryptionBlockSize = cipherData.length - CC_SHA256_DIGEST_LENGTH - kCCKeySizeAES128; // minus signature, minus nonce + + // now re-use buffer to do decryption + size_t dataMoved; + status = CCCryptorUpdate(cryptor, encryptionBlockPtr, encryptionBlockSize, plainText, cipherData.length, &dataMoved); + // note: there is no need to call CCCryptorFinal when no padding is used. + CCCryptorRelease(cryptor); + + if (status != kCCSuccess) { + PPSDKLog(@"decryptAESCTRData: encryption error: %@", @(status)); + free(plainText); + plainText = NULL; + return nil; + } + resultData = [NSData dataWithBytes:plainText length:dataMoved]; + free(plainText); + plainText = NULL; + return resultData; +} + + +#pragma mark - AES Public Key + ++ (SecKeyRef)createPublicKeyUsingCertificate:(NSData *)certificateData { + SecCertificateRef certificate = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certificateData); + if (certificate == NULL) { + PPSDKLog(@"createPublicKeyUsingData: failed to create public key"); + return NULL; + } + SecPolicyRef policy = SecPolicyCreateBasicX509(); + SecTrustRef trustRef = NULL; + SecKeyRef keyRef = NULL; + OSStatus status = SecTrustCreateWithCertificates(certificate, policy, &trustRef); + if (status == errSecSuccess) { + keyRef = SecTrustCopyPublicKey(trustRef); + } else { + PPSDKLog(@"createPublicKeyUsingData: create certificate failed with error %@", @(status)); + } + CFRelease(trustRef); + CFRelease(policy); + CFRelease(certificate); + + return keyRef; +} + ++ (NSData *)encryptRSAData:(NSData *)plainData certificate:(NSData *)certificate { + if (![certificate length]) { + PPSDKLog(@"encryptRSAData: no certificate provided"); + return nil; + } + + SecKeyRef publicKeyRef = [self createPublicKeyUsingCertificate:certificate]; + if (!publicKeyRef) { + // logging is done above + return nil; + } + size_t keyBlockSize = SecKeyGetBlockSize(publicKeyRef); + if (plainData.length > keyBlockSize) { + PPSDKLog(@"encryptRSAData: data too big to encrypt"); + CFRelease(publicKeyRef); + return nil; + } + size_t cipherTextLen = keyBlockSize; + uint8_t *cipherText = malloc(keyBlockSize); + memset(cipherText, 0, keyBlockSize); + + OSStatus status = SecKeyEncrypt(publicKeyRef, kSecPaddingOAEP, [plainData bytes], [plainData length], cipherText, &cipherTextLen); + CFRelease(publicKeyRef); + if (status != errSecSuccess) { + PPSDKLog(@"encryptRSAData: encryption failed with error %@", @(status)); + free(cipherText); + return nil; + } + + NSData *resultData = [NSData dataWithBytes:cipherText length:cipherTextLen]; + free(cipherText); + cipherText = NULL; + return resultData; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTJSONHelper.m b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTJSONHelper.m new file mode 100644 index 0000000..2561efa --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTJSONHelper.m @@ -0,0 +1,90 @@ +// +// PPOTJSONHelper.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTJSONHelper.h" +#import "PPOTString.h" + +@implementation PPOTJSONHelper + ++ (NSString *)stringFromDictionary:(NSDictionary *)dictionary withKey:(NSString *)key { + NSString *string = nil; + if ([dictionary[key] isKindOfClass:[NSString class]]) { + string = dictionary[key]; + } + return string; +} + ++ (NSDictionary *)dictionaryFromDictionary:(NSDictionary *)dictionary withKey:(NSString *)key { + NSDictionary *dict = nil; + if ([dictionary[key] isKindOfClass:[NSDictionary class]]) { + dict = dictionary[key]; + } + return dict; +} + ++ (NSArray *)arrayFromDictionary:(NSDictionary *)dictionary withKey:(NSString *)key { + NSArray *array = nil; + if ([dictionary[key] isKindOfClass:[NSArray class]]) { + array = dictionary[key]; + } + return array; +} + ++ (NSArray *)stringArrayFromDictionary:(NSDictionary *)dictionary withKey:(NSString *)key { + NSArray *array = [PPOTJSONHelper arrayFromDictionary:dictionary withKey:key]; + for (id item in array) { + if (![item isKindOfClass:[NSString class]]) { + return nil; + } + } + return array; +} + ++ (NSArray *)dictionaryArrayFromDictionary:(NSDictionary *)dictionary withKey:(NSString *)key { + NSArray *array = [PPOTJSONHelper arrayFromDictionary:dictionary withKey:key]; + for (id item in array) { + if (![item isKindOfClass:[NSDictionary class]]) { + return nil; + } + } + return array; +} + ++ (NSString *)base64EncodedJSONStringWithDictionary:(NSDictionary*)dictionary { + NSData *json = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil]; + if ([json length]) { + return [PPOTString stringByBase64EncodingData:json]; + } + else { + return @""; + } +} ++ (NSDictionary *)dictionaryWithBase64EncodedJSONString:(NSString*)base64String { + NSData *data = [PPOTString decodeBase64WithString:base64String]; + if ([data length]) { + return [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; + } + else { + return @{}; + } +} + ++ (NSNumber *)numberFromDictionary:(NSDictionary *)dictionary withKey:(NSString *)key { + NSNumber *number = nil; + if ([dictionary[key] isKindOfClass:[NSNumber class]]) { + number = dictionary[key]; + } else { + NSString *stringNumber = [self stringFromDictionary:dictionary withKey:key]; + if (stringNumber.length) { + NSNumberFormatter *formatter = [NSNumberFormatter new]; + number = [formatter numberFromString:stringNumber]; + } + } + return number; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTMacros.m b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTMacros.m new file mode 100644 index 0000000..3b7bb56 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTMacros.m @@ -0,0 +1,20 @@ +// +// PPOTMacros.m +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTMacros.h" +#import + +@implementation PPOTMacros + ++ (NSUInteger)deviceSystemMajorVersion { + static NSUInteger _deviceSystemMajorVersion = -1; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _deviceSystemMajorVersion = [[[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."] objectAtIndex:0] intValue]; + }); + return _deviceSystemMajorVersion; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTPinnedCertificates.m b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTPinnedCertificates.m new file mode 100644 index 0000000..2d7de1b --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTPinnedCertificates.m @@ -0,0 +1,350 @@ +// +// PPOTPinnedCertificates.m +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTPinnedCertificates.h" + +@implementation PPOTPinnedCertificates + ++ (NSArray *)trustedCertificates { + NSMutableArray *trustedCertificates = [NSMutableArray array]; + { + /* subject= /C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5 */ + /* issuer= /C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2006 VeriSign, Inc. - For authorized use only/CN=VeriSign Class 3 Public Primary Certification Authority - G5 */ + unsigned char XXX_certificate[1239]={ + 0x30,0x82,0x04,0xd3,0x30,0x82,0x03,0xbb,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x18, + 0xda,0xd1,0x9e,0x26,0x7d,0xe8,0xbb,0x4a,0x21,0x58,0xcd,0xcc,0x6b,0x3b,0x4a,0x30, + 0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x81, + 0xca,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17, + 0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67, + 0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b, + 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73,0x74, + 0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,0x31,0x3a,0x30,0x38,0x06,0x03,0x55,0x04, + 0x0b,0x13,0x31,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x56,0x65,0x72,0x69, + 0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x20,0x2d,0x20,0x46,0x6f,0x72, + 0x20,0x61,0x75,0x74,0x68,0x6f,0x72,0x69,0x7a,0x65,0x64,0x20,0x75,0x73,0x65,0x20, + 0x6f,0x6e,0x6c,0x79,0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3c,0x56, + 0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20, + 0x50,0x75,0x62,0x6c,0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x43, + 0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74, + 0x68,0x6f,0x72,0x69,0x74,0x79,0x20,0x2d,0x20,0x47,0x35,0x30,0x1e,0x17,0x0d,0x30, + 0x36,0x31,0x31,0x30,0x38,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x33,0x36, + 0x30,0x37,0x31,0x36,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81,0xca,0x31,0x0b, + 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17,0x30,0x15,0x06, + 0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,0x20, + 0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b,0x13,0x16,0x56, + 0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73,0x74,0x20,0x4e,0x65, + 0x74,0x77,0x6f,0x72,0x6b,0x31,0x3a,0x30,0x38,0x06,0x03,0x55,0x04,0x0b,0x13,0x31, + 0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x36,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67, + 0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x20,0x2d,0x20,0x46,0x6f,0x72,0x20,0x61,0x75, + 0x74,0x68,0x6f,0x72,0x69,0x7a,0x65,0x64,0x20,0x75,0x73,0x65,0x20,0x6f,0x6e,0x6c, + 0x79,0x31,0x45,0x30,0x43,0x06,0x03,0x55,0x04,0x03,0x13,0x3c,0x56,0x65,0x72,0x69, + 0x53,0x69,0x67,0x6e,0x20,0x43,0x6c,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62, + 0x6c,0x69,0x63,0x20,0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74, + 0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,0x72, + 0x69,0x74,0x79,0x20,0x2d,0x20,0x47,0x35,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09, + 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00, + 0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xaf,0x24,0x08,0x08,0x29,0x7a,0x35, + 0x9e,0x60,0x0c,0xaa,0xe7,0x4b,0x3b,0x4e,0xdc,0x7c,0xbc,0x3c,0x45,0x1c,0xbb,0x2b, + 0xe0,0xfe,0x29,0x02,0xf9,0x57,0x08,0xa3,0x64,0x85,0x15,0x27,0xf5,0xf1,0xad,0xc8, + 0x31,0x89,0x5d,0x22,0xe8,0x2a,0xaa,0xa6,0x42,0xb3,0x8f,0xf8,0xb9,0x55,0xb7,0xb1, + 0xb7,0x4b,0xb3,0xfe,0x8f,0x7e,0x07,0x57,0xec,0xef,0x43,0xdb,0x66,0x62,0x15,0x61, + 0xcf,0x60,0x0d,0xa4,0xd8,0xde,0xf8,0xe0,0xc3,0x62,0x08,0x3d,0x54,0x13,0xeb,0x49, + 0xca,0x59,0x54,0x85,0x26,0xe5,0x2b,0x8f,0x1b,0x9f,0xeb,0xf5,0xa1,0x91,0xc2,0x33, + 0x49,0xd8,0x43,0x63,0x6a,0x52,0x4b,0xd2,0x8f,0xe8,0x70,0x51,0x4d,0xd1,0x89,0x69, + 0x7b,0xc7,0x70,0xf6,0xb3,0xdc,0x12,0x74,0xdb,0x7b,0x5d,0x4b,0x56,0xd3,0x96,0xbf, + 0x15,0x77,0xa1,0xb0,0xf4,0xa2,0x25,0xf2,0xaf,0x1c,0x92,0x67,0x18,0xe5,0xf4,0x06, + 0x04,0xef,0x90,0xb9,0xe4,0x00,0xe4,0xdd,0x3a,0xb5,0x19,0xff,0x02,0xba,0xf4,0x3c, + 0xee,0xe0,0x8b,0xeb,0x37,0x8b,0xec,0xf4,0xd7,0xac,0xf2,0xf6,0xf0,0x3d,0xaf,0xdd, + 0x75,0x91,0x33,0x19,0x1d,0x1c,0x40,0xcb,0x74,0x24,0x19,0x21,0x93,0xd9,0x14,0xfe, + 0xac,0x2a,0x52,0xc7,0x8f,0xd5,0x04,0x49,0xe4,0x8d,0x63,0x47,0x88,0x3c,0x69,0x83, + 0xcb,0xfe,0x47,0xbd,0x2b,0x7e,0x4f,0xc5,0x95,0xae,0x0e,0x9d,0xd4,0xd1,0x43,0xc0, + 0x67,0x73,0xe3,0x14,0x08,0x7e,0xe5,0x3f,0x9f,0x73,0xb8,0x33,0x0a,0xcf,0x5d,0x3f, + 0x34,0x87,0x96,0x8a,0xee,0x53,0xe8,0x25,0x15,0x02,0x03,0x01,0x00,0x01,0xa3,0x81, + 0xb2,0x30,0x81,0xaf,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x05, + 0x30,0x03,0x01,0x01,0xff,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04, + 0x04,0x03,0x02,0x01,0x06,0x30,0x6d,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x01, + 0x0c,0x04,0x61,0x30,0x5f,0xa1,0x5d,0xa0,0x5b,0x30,0x59,0x30,0x57,0x30,0x55,0x16, + 0x09,0x69,0x6d,0x61,0x67,0x65,0x2f,0x67,0x69,0x66,0x30,0x21,0x30,0x1f,0x30,0x07, + 0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x04,0x14,0x8f,0xe5,0xd3,0x1a,0x86,0xac,0x8d, + 0x8e,0x6b,0xc3,0xcf,0x80,0x6a,0xd4,0x48,0x18,0x2c,0x7b,0x19,0x2e,0x30,0x25,0x16, + 0x23,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6c,0x6f,0x67,0x6f,0x2e,0x76,0x65,0x72, + 0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x76,0x73,0x6c,0x6f,0x67,0x6f, + 0x2e,0x67,0x69,0x66,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,0x16,0x04,0x14,0x7f, + 0xd3,0x65,0xa7,0xc2,0xdd,0xec,0xbb,0xf0,0x30,0x09,0xf3,0x43,0x39,0xfa,0x02,0xaf, + 0x33,0x31,0x33,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05, + 0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x93,0x24,0x4a,0x30,0x5f,0x62,0xcf,0xd8,0x1a, + 0x98,0x2f,0x3d,0xea,0xdc,0x99,0x2d,0xbd,0x77,0xf6,0xa5,0x79,0x22,0x38,0xec,0xc4, + 0xa7,0xa0,0x78,0x12,0xad,0x62,0x0e,0x45,0x70,0x64,0xc5,0xe7,0x97,0x66,0x2d,0x98, + 0x09,0x7e,0x5f,0xaf,0xd6,0xcc,0x28,0x65,0xf2,0x01,0xaa,0x08,0x1a,0x47,0xde,0xf9, + 0xf9,0x7c,0x92,0x5a,0x08,0x69,0x20,0x0d,0xd9,0x3e,0x6d,0x6e,0x3c,0x0d,0x6e,0xd8, + 0xe6,0x06,0x91,0x40,0x18,0xb9,0xf8,0xc1,0xed,0xdf,0xdb,0x41,0xaa,0xe0,0x96,0x20, + 0xc9,0xcd,0x64,0x15,0x38,0x81,0xc9,0x94,0xee,0xa2,0x84,0x29,0x0b,0x13,0x6f,0x8e, + 0xdb,0x0c,0xdd,0x25,0x02,0xdb,0xa4,0x8b,0x19,0x44,0xd2,0x41,0x7a,0x05,0x69,0x4a, + 0x58,0x4f,0x60,0xca,0x7e,0x82,0x6a,0x0b,0x02,0xaa,0x25,0x17,0x39,0xb5,0xdb,0x7f, + 0xe7,0x84,0x65,0x2a,0x95,0x8a,0xbd,0x86,0xde,0x5e,0x81,0x16,0x83,0x2d,0x10,0xcc, + 0xde,0xfd,0xa8,0x82,0x2a,0x6d,0x28,0x1f,0x0d,0x0b,0xc4,0xe5,0xe7,0x1a,0x26,0x19, + 0xe1,0xf4,0x11,0x6f,0x10,0xb5,0x95,0xfc,0xe7,0x42,0x05,0x32,0xdb,0xce,0x9d,0x51, + 0x5e,0x28,0xb6,0x9e,0x85,0xd3,0x5b,0xef,0xa5,0x7d,0x45,0x40,0x72,0x8e,0xb7,0x0e, + 0x6b,0x0e,0x06,0xfb,0x33,0x35,0x48,0x71,0xb8,0x9d,0x27,0x8b,0xc4,0x65,0x5f,0x0d, + 0x86,0x76,0x9c,0x44,0x7a,0xf6,0x95,0x5c,0xf6,0x5d,0x32,0x08,0x33,0xa4,0x54,0xb6, + 0x18,0x3f,0x68,0x5c,0xf2,0x42,0x4a,0x85,0x38,0x54,0x83,0x5f,0xd1,0xe8,0x2c,0xf2, + 0xac,0x11,0xd6,0xa8,0xed,0x63,0x6a, + }; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { + /* subject= /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA */ + /* issuer= /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA */ + unsigned char XXX_certificate[969]={ + 0x30,0x82,0x03,0xc5,0x30,0x82,0x02,0xad,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x02, + 0xac,0x5c,0x26,0x6a,0x0b,0x40,0x9b,0x8f,0x0b,0x79,0xf2,0xae,0x46,0x25,0x77,0x30, + 0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x6c, + 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30, + 0x13,0x06,0x03,0x55,0x04,0x0a,0x13,0x0c,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, + 0x20,0x49,0x6e,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0b,0x13,0x10,0x77, + 0x77,0x77,0x2e,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2e,0x63,0x6f,0x6d,0x31, + 0x2b,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x44,0x69,0x67,0x69,0x43,0x65, + 0x72,0x74,0x20,0x48,0x69,0x67,0x68,0x20,0x41,0x73,0x73,0x75,0x72,0x61,0x6e,0x63, + 0x65,0x20,0x45,0x56,0x20,0x52,0x6f,0x6f,0x74,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d, + 0x30,0x36,0x31,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x33, + 0x31,0x31,0x31,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x6c,0x31,0x0b, + 0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30,0x13,0x06, + 0x03,0x55,0x04,0x0a,0x13,0x0c,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x20,0x49, + 0x6e,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0b,0x13,0x10,0x77,0x77,0x77, + 0x2e,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2e,0x63,0x6f,0x6d,0x31,0x2b,0x30, + 0x29,0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, + 0x20,0x48,0x69,0x67,0x68,0x20,0x41,0x73,0x73,0x75,0x72,0x61,0x6e,0x63,0x65,0x20, + 0x45,0x56,0x20,0x52,0x6f,0x6f,0x74,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0d, + 0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01, + 0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xc6,0xcc,0xe5,0x73,0xe6, + 0xfb,0xd4,0xbb,0xe5,0x2d,0x2d,0x32,0xa6,0xdf,0xe5,0x81,0x3f,0xc9,0xcd,0x25,0x49, + 0xb6,0x71,0x2a,0xc3,0xd5,0x94,0x34,0x67,0xa2,0x0a,0x1c,0xb0,0x5f,0x69,0xa6,0x40, + 0xb1,0xc4,0xb7,0xb2,0x8f,0xd0,0x98,0xa4,0xa9,0x41,0x59,0x3a,0xd3,0xdc,0x94,0xd6, + 0x3c,0xdb,0x74,0x38,0xa4,0x4a,0xcc,0x4d,0x25,0x82,0xf7,0x4a,0xa5,0x53,0x12,0x38, + 0xee,0xf3,0x49,0x6d,0x71,0x91,0x7e,0x63,0xb6,0xab,0xa6,0x5f,0xc3,0xa4,0x84,0xf8, + 0x4f,0x62,0x51,0xbe,0xf8,0xc5,0xec,0xdb,0x38,0x92,0xe3,0x06,0xe5,0x08,0x91,0x0c, + 0xc4,0x28,0x41,0x55,0xfb,0xcb,0x5a,0x89,0x15,0x7e,0x71,0xe8,0x35,0xbf,0x4d,0x72, + 0x09,0x3d,0xbe,0x3a,0x38,0x50,0x5b,0x77,0x31,0x1b,0x8d,0xb3,0xc7,0x24,0x45,0x9a, + 0xa7,0xac,0x6d,0x00,0x14,0x5a,0x04,0xb7,0xba,0x13,0xeb,0x51,0x0a,0x98,0x41,0x41, + 0x22,0x4e,0x65,0x61,0x87,0x81,0x41,0x50,0xa6,0x79,0x5c,0x89,0xde,0x19,0x4a,0x57, + 0xd5,0x2e,0xe6,0x5d,0x1c,0x53,0x2c,0x7e,0x98,0xcd,0x1a,0x06,0x16,0xa4,0x68,0x73, + 0xd0,0x34,0x04,0x13,0x5c,0xa1,0x71,0xd3,0x5a,0x7c,0x55,0xdb,0x5e,0x64,0xe1,0x37, + 0x87,0x30,0x56,0x04,0xe5,0x11,0xb4,0x29,0x80,0x12,0xf1,0x79,0x39,0x88,0xa2,0x02, + 0x11,0x7c,0x27,0x66,0xb7,0x88,0xb7,0x78,0xf2,0xca,0x0a,0xa8,0x38,0xab,0x0a,0x64, + 0xc2,0xbf,0x66,0x5d,0x95,0x84,0xc1,0xa1,0x25,0x1e,0x87,0x5d,0x1a,0x50,0x0b,0x20, + 0x12,0xcc,0x41,0xbb,0x6e,0x0b,0x51,0x38,0xb8,0x4b,0xcb,0x02,0x03,0x01,0x00,0x01, + 0xa3,0x63,0x30,0x61,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04, + 0x03,0x02,0x01,0x86,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x05, + 0x30,0x03,0x01,0x01,0xff,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,0x16,0x04,0x14, + 0xb1,0x3e,0xc3,0x69,0x03,0xf8,0xbf,0x47,0x01,0xd4,0x98,0x26,0x1a,0x08,0x02,0xef, + 0x63,0x64,0x2b,0xc3,0x30,0x1f,0x06,0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80, + 0x14,0xb1,0x3e,0xc3,0x69,0x03,0xf8,0xbf,0x47,0x01,0xd4,0x98,0x26,0x1a,0x08,0x02, + 0xef,0x63,0x64,0x2b,0xc3,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01, + 0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x1c,0x1a,0x06,0x97,0xdc,0xd7,0x9c, + 0x9f,0x3c,0x88,0x66,0x06,0x08,0x57,0x21,0xdb,0x21,0x47,0xf8,0x2a,0x67,0xaa,0xbf, + 0x18,0x32,0x76,0x40,0x10,0x57,0xc1,0x8a,0xf3,0x7a,0xd9,0x11,0x65,0x8e,0x35,0xfa, + 0x9e,0xfc,0x45,0xb5,0x9e,0xd9,0x4c,0x31,0x4b,0xb8,0x91,0xe8,0x43,0x2c,0x8e,0xb3, + 0x78,0xce,0xdb,0xe3,0x53,0x79,0x71,0xd6,0xe5,0x21,0x94,0x01,0xda,0x55,0x87,0x9a, + 0x24,0x64,0xf6,0x8a,0x66,0xcc,0xde,0x9c,0x37,0xcd,0xa8,0x34,0xb1,0x69,0x9b,0x23, + 0xc8,0x9e,0x78,0x22,0x2b,0x70,0x43,0xe3,0x55,0x47,0x31,0x61,0x19,0xef,0x58,0xc5, + 0x85,0x2f,0x4e,0x30,0xf6,0xa0,0x31,0x16,0x23,0xc8,0xe7,0xe2,0x65,0x16,0x33,0xcb, + 0xbf,0x1a,0x1b,0xa0,0x3d,0xf8,0xca,0x5e,0x8b,0x31,0x8b,0x60,0x08,0x89,0x2d,0x0c, + 0x06,0x5c,0x52,0xb7,0xc4,0xf9,0x0a,0x98,0xd1,0x15,0x5f,0x9f,0x12,0xbe,0x7c,0x36, + 0x63,0x38,0xbd,0x44,0xa4,0x7f,0xe4,0x26,0x2b,0x0a,0xc4,0x97,0x69,0x0d,0xe9,0x8c, + 0xe2,0xc0,0x10,0x57,0xb8,0xc8,0x76,0x12,0x91,0x55,0xf2,0x48,0x69,0xd8,0xbc,0x2a, + 0x02,0x5b,0x0f,0x44,0xd4,0x20,0x31,0xdb,0xf4,0xba,0x70,0x26,0x5d,0x90,0x60,0x9e, + 0xbc,0x4b,0x17,0x09,0x2f,0xb4,0xcb,0x1e,0x43,0x68,0xc9,0x07,0x27,0xc1,0xd2,0x5c, + 0xf7,0xea,0x21,0xb9,0x68,0x12,0x9c,0x3c,0x9c,0xbf,0x9e,0xfc,0x80,0x5c,0x9b,0x63, + 0xcd,0xec,0x47,0xaa,0x25,0x27,0x67,0xa0,0x37,0xf3,0x00,0x82,0x7d,0x54,0xd7,0xa9, + 0xf8,0xe9,0x2e,0x13,0xa3,0x77,0xe8,0x1f,0x4a, + }; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { + /* subject= /C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2008 VeriSign, Inc. - For authorized use only/CN=VeriSign Universal Root Certification Authority */ + /* issuer= /C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=(c) 2008 VeriSign, Inc. - For authorized use only/CN=VeriSign Universal Root Certification Authority */ + unsigned char XXX_certificate[1213]={ + 0x30,0x82,0x04,0xb9,0x30,0x82,0x03,0xa1,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x40, + 0x1a,0xc4,0x64,0x21,0xb3,0x13,0x21,0x03,0x0e,0xbb,0xe4,0x12,0x1a,0xc5,0x1d,0x30, + 0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0b,0x05,0x00,0x30,0x81, + 0xbd,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17, + 0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67, + 0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b, + 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73,0x74, + 0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,0x31,0x3a,0x30,0x38,0x06,0x03,0x55,0x04, + 0x0b,0x13,0x31,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x38,0x20,0x56,0x65,0x72,0x69, + 0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x20,0x2d,0x20,0x46,0x6f,0x72, + 0x20,0x61,0x75,0x74,0x68,0x6f,0x72,0x69,0x7a,0x65,0x64,0x20,0x75,0x73,0x65,0x20, + 0x6f,0x6e,0x6c,0x79,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x03,0x13,0x2f,0x56, + 0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x55,0x6e,0x69,0x76,0x65,0x72,0x73,0x61, + 0x6c,0x20,0x52,0x6f,0x6f,0x74,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61, + 0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x1e, + 0x17,0x0d,0x30,0x38,0x30,0x34,0x30,0x32,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17, + 0x0d,0x33,0x37,0x31,0x32,0x30,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x81, + 0xbd,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x17, + 0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,0x69,0x67, + 0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0b, + 0x13,0x16,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x54,0x72,0x75,0x73,0x74, + 0x20,0x4e,0x65,0x74,0x77,0x6f,0x72,0x6b,0x31,0x3a,0x30,0x38,0x06,0x03,0x55,0x04, + 0x0b,0x13,0x31,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x38,0x20,0x56,0x65,0x72,0x69, + 0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x20,0x2d,0x20,0x46,0x6f,0x72, + 0x20,0x61,0x75,0x74,0x68,0x6f,0x72,0x69,0x7a,0x65,0x64,0x20,0x75,0x73,0x65,0x20, + 0x6f,0x6e,0x6c,0x79,0x31,0x38,0x30,0x36,0x06,0x03,0x55,0x04,0x03,0x13,0x2f,0x56, + 0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x55,0x6e,0x69,0x76,0x65,0x72,0x73,0x61, + 0x6c,0x20,0x52,0x6f,0x6f,0x74,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61, + 0x74,0x69,0x6f,0x6e,0x20,0x41,0x75,0x74,0x68,0x6f,0x72,0x69,0x74,0x79,0x30,0x82, + 0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05, + 0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xc7, + 0x61,0x37,0x5e,0xb1,0x01,0x34,0xdb,0x62,0xd7,0x15,0x9b,0xff,0x58,0x5a,0x8c,0x23, + 0x23,0xd6,0x60,0x8e,0x91,0xd7,0x90,0x98,0x83,0x7a,0xe6,0x58,0x19,0x38,0x8c,0xc5, + 0xf6,0xe5,0x64,0x85,0xb4,0xa2,0x71,0xfb,0xed,0xbd,0xb9,0xda,0xcd,0x4d,0x00,0xb4, + 0xc8,0x2d,0x73,0xa5,0xc7,0x69,0x71,0x95,0x1f,0x39,0x3c,0xb2,0x44,0x07,0x9c,0xe8, + 0x0e,0xfa,0x4d,0x4a,0xc4,0x21,0xdf,0x29,0x61,0x8f,0x32,0x22,0x61,0x82,0xc5,0x87, + 0x1f,0x6e,0x8c,0x7c,0x5f,0x16,0x20,0x51,0x44,0xd1,0x70,0x4f,0x57,0xea,0xe3,0x1c, + 0xe3,0xcc,0x79,0xee,0x58,0xd8,0x0e,0xc2,0xb3,0x45,0x93,0xc0,0x2c,0xe7,0x9a,0x17, + 0x2b,0x7b,0x00,0x37,0x7a,0x41,0x33,0x78,0xe1,0x33,0xe2,0xf3,0x10,0x1a,0x7f,0x87, + 0x2c,0xbe,0xf6,0xf5,0xf7,0x42,0xe2,0xe5,0xbf,0x87,0x62,0x89,0x5f,0x00,0x4b,0xdf, + 0xc5,0xdd,0xe4,0x75,0x44,0x32,0x41,0x3a,0x1e,0x71,0x6e,0x69,0xcb,0x0b,0x75,0x46, + 0x08,0xd1,0xca,0xd2,0x2b,0x95,0xd0,0xcf,0xfb,0xb9,0x40,0x6b,0x64,0x8c,0x57,0x4d, + 0xfc,0x13,0x11,0x79,0x84,0xed,0x5e,0x54,0xf6,0x34,0x9f,0x08,0x01,0xf3,0x10,0x25, + 0x06,0x17,0x4a,0xda,0xf1,0x1d,0x7a,0x66,0x6b,0x98,0x60,0x66,0xa4,0xd9,0xef,0xd2, + 0x2e,0x82,0xf1,0xf0,0xef,0x09,0xea,0x44,0xc9,0x15,0x6a,0xe2,0x03,0x6e,0x33,0xd3, + 0xac,0x9f,0x55,0x00,0xc7,0xf6,0x08,0x6a,0x94,0xb9,0x5f,0xdc,0xe0,0x33,0xf1,0x84, + 0x60,0xf9,0x5b,0x27,0x11,0xb4,0xfc,0x16,0xf2,0xbb,0x56,0x6a,0x80,0x25,0x8d,0x02, + 0x03,0x01,0x00,0x01,0xa3,0x81,0xb2,0x30,0x81,0xaf,0x30,0x0f,0x06,0x03,0x55,0x1d, + 0x13,0x01,0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x0e,0x06,0x03,0x55, + 0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x6d,0x06,0x08,0x2b, + 0x06,0x01,0x05,0x05,0x07,0x01,0x0c,0x04,0x61,0x30,0x5f,0xa1,0x5d,0xa0,0x5b,0x30, + 0x59,0x30,0x57,0x30,0x55,0x16,0x09,0x69,0x6d,0x61,0x67,0x65,0x2f,0x67,0x69,0x66, + 0x30,0x21,0x30,0x1f,0x30,0x07,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x04,0x14,0x8f, + 0xe5,0xd3,0x1a,0x86,0xac,0x8d,0x8e,0x6b,0xc3,0xcf,0x80,0x6a,0xd4,0x48,0x18,0x2c, + 0x7b,0x19,0x2e,0x30,0x25,0x16,0x23,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6c,0x6f, + 0x67,0x6f,0x2e,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f, + 0x76,0x73,0x6c,0x6f,0x67,0x6f,0x2e,0x67,0x69,0x66,0x30,0x1d,0x06,0x03,0x55,0x1d, + 0x0e,0x04,0x16,0x04,0x14,0xb6,0x77,0xfa,0x69,0x48,0x47,0x9f,0x53,0x12,0xd5,0xc2, + 0xea,0x07,0x32,0x76,0x07,0xd1,0x97,0x07,0x19,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, + 0x86,0xf7,0x0d,0x01,0x01,0x0b,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x4a,0xf8,0xf8, + 0xb0,0x03,0xe6,0x2c,0x67,0x7b,0xe4,0x94,0x77,0x63,0xcc,0x6e,0x4c,0xf9,0x7d,0x0e, + 0x0d,0xdc,0xc8,0xb9,0x35,0xb9,0x70,0x4f,0x63,0xfa,0x24,0xfa,0x6c,0x83,0x8c,0x47, + 0x9d,0x3b,0x63,0xf3,0x9a,0xf9,0x76,0x32,0x95,0x91,0xb1,0x77,0xbc,0xac,0x9a,0xbe, + 0xb1,0xe4,0x31,0x21,0xc6,0x81,0x95,0x56,0x5a,0x0e,0xb1,0xc2,0xd4,0xb1,0xa6,0x59, + 0xac,0xf1,0x63,0xcb,0xb8,0x4c,0x1d,0x59,0x90,0x4a,0xef,0x90,0x16,0x28,0x1f,0x5a, + 0xae,0x10,0xfb,0x81,0x50,0x38,0x0c,0x6c,0xcc,0xf1,0x3d,0xc3,0xf5,0x63,0xe3,0xb3, + 0xe3,0x21,0xc9,0x24,0x39,0xe9,0xfd,0x15,0x66,0x46,0xf4,0x1b,0x11,0xd0,0x4d,0x73, + 0xa3,0x7d,0x46,0xf9,0x3d,0xed,0xa8,0x5f,0x62,0xd4,0xf1,0x3f,0xf8,0xe0,0x74,0x57, + 0x2b,0x18,0x9d,0x81,0xb4,0xc4,0x28,0xda,0x94,0x97,0xa5,0x70,0xeb,0xac,0x1d,0xbe, + 0x07,0x11,0xf0,0xd5,0xdb,0xdd,0xe5,0x8c,0xf0,0xd5,0x32,0xb0,0x83,0xe6,0x57,0xe2, + 0x8f,0xbf,0xbe,0xa1,0xaa,0xbf,0x3d,0x1d,0xb5,0xd4,0x38,0xea,0xd7,0xb0,0x5c,0x3a, + 0x4f,0x6a,0x3f,0x8f,0xc0,0x66,0x6c,0x63,0xaa,0xe9,0xd9,0xa4,0x16,0xf4,0x81,0xd1, + 0x95,0x14,0x0e,0x7d,0xcd,0x95,0x34,0xd9,0xd2,0x8f,0x70,0x73,0x81,0x7b,0x9c,0x7e, + 0xbd,0x98,0x61,0xd8,0x45,0x87,0x98,0x90,0xc5,0xeb,0x86,0x30,0xc6,0x35,0xbf,0xf0, + 0xff,0xc3,0x55,0x88,0x83,0x4b,0xef,0x05,0x92,0x06,0x71,0xf2,0xb8,0x98,0x93,0xb7, + 0xec,0xcd,0x82,0x61,0xf1,0x38,0xe6,0x4f,0x97,0x98,0x2a,0x5a,0x8d, + }; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + { + /* subject= /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Trusted Root G4 */ + /* issuer= /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Trusted Root G4 */ + unsigned char XXX_certificate[1428]={ + 0x30,0x82,0x05,0x90,0x30,0x82,0x03,0x78,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x05, + 0x9b,0x1b,0x57,0x9e,0x8e,0x21,0x32,0xe2,0x39,0x07,0xbd,0xa7,0x77,0x75,0x5c,0x30, + 0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0c,0x05,0x00,0x30,0x62, + 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x15,0x30, + 0x13,0x06,0x03,0x55,0x04,0x0a,0x13,0x0c,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, + 0x20,0x49,0x6e,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x0b,0x13,0x10,0x77, + 0x77,0x77,0x2e,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2e,0x63,0x6f,0x6d,0x31, + 0x21,0x30,0x1f,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x44,0x69,0x67,0x69,0x43,0x65, + 0x72,0x74,0x20,0x54,0x72,0x75,0x73,0x74,0x65,0x64,0x20,0x52,0x6f,0x6f,0x74,0x20, + 0x47,0x34,0x30,0x1e,0x17,0x0d,0x31,0x33,0x30,0x38,0x30,0x31,0x31,0x32,0x30,0x30, + 0x30,0x30,0x5a,0x17,0x0d,0x33,0x38,0x30,0x31,0x31,0x35,0x31,0x32,0x30,0x30,0x30, + 0x30,0x5a,0x30,0x62,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, + 0x53,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0a,0x13,0x0c,0x44,0x69,0x67,0x69, + 0x43,0x65,0x72,0x74,0x20,0x49,0x6e,0x63,0x31,0x19,0x30,0x17,0x06,0x03,0x55,0x04, + 0x0b,0x13,0x10,0x77,0x77,0x77,0x2e,0x64,0x69,0x67,0x69,0x63,0x65,0x72,0x74,0x2e, + 0x63,0x6f,0x6d,0x31,0x21,0x30,0x1f,0x06,0x03,0x55,0x04,0x03,0x13,0x18,0x44,0x69, + 0x67,0x69,0x43,0x65,0x72,0x74,0x20,0x54,0x72,0x75,0x73,0x74,0x65,0x64,0x20,0x52, + 0x6f,0x6f,0x74,0x20,0x47,0x34,0x30,0x82,0x02,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86, + 0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x02,0x0f,0x00,0x30,0x82, + 0x02,0x0a,0x02,0x82,0x02,0x01,0x00,0xbf,0xe6,0x90,0x73,0x68,0xde,0xbb,0xe4,0x5d, + 0x4a,0x3c,0x30,0x22,0x30,0x69,0x33,0xec,0xc2,0xa7,0x25,0x2e,0xc9,0x21,0x3d,0xf2, + 0x8a,0xd8,0x59,0xc2,0xe1,0x29,0xa7,0x3d,0x58,0xab,0x76,0x9a,0xcd,0xae,0x7b,0x1b, + 0x84,0x0d,0xc4,0x30,0x1f,0xf3,0x1b,0xa4,0x38,0x16,0xeb,0x56,0xc6,0x97,0x6d,0x1d, + 0xab,0xb2,0x79,0xf2,0xca,0x11,0xd2,0xe4,0x5f,0xd6,0x05,0x3c,0x52,0x0f,0x52,0x1f, + 0xc6,0x9e,0x15,0xa5,0x7e,0xbe,0x9f,0xa9,0x57,0x16,0x59,0x55,0x72,0xaf,0x68,0x93, + 0x70,0xc2,0xb2,0xba,0x75,0x99,0x6a,0x73,0x32,0x94,0xd1,0x10,0x44,0x10,0x2e,0xdf, + 0x82,0xf3,0x07,0x84,0xe6,0x74,0x3b,0x6d,0x71,0xe2,0x2d,0x0c,0x1b,0xee,0x20,0xd5, + 0xc9,0x20,0x1d,0x63,0x29,0x2d,0xce,0xec,0x5e,0x4e,0xc8,0x93,0xf8,0x21,0x61,0x9b, + 0x34,0xeb,0x05,0xc6,0x5e,0xec,0x5b,0x1a,0xbc,0xeb,0xc9,0xcf,0xcd,0xac,0x34,0x40, + 0x5f,0xb1,0x7a,0x66,0xee,0x77,0xc8,0x48,0xa8,0x66,0x57,0x57,0x9f,0x54,0x58,0x8e, + 0x0c,0x2b,0xb7,0x4f,0xa7,0x30,0xd9,0x56,0xee,0xca,0x7b,0x5d,0xe3,0xad,0xc9,0x4f, + 0x5e,0xe5,0x35,0xe7,0x31,0xcb,0xda,0x93,0x5e,0xdc,0x8e,0x8f,0x80,0xda,0xb6,0x91, + 0x98,0x40,0x90,0x79,0xc3,0x78,0xc7,0xb6,0xb1,0xc4,0xb5,0x6a,0x18,0x38,0x03,0x10, + 0x8d,0xd8,0xd4,0x37,0xa4,0x2e,0x05,0x7d,0x88,0xf5,0x82,0x3e,0x10,0x91,0x70,0xab, + 0x55,0x82,0x41,0x32,0xd7,0xdb,0x04,0x73,0x2a,0x6e,0x91,0x01,0x7c,0x21,0x4c,0xd4, + 0xbc,0xae,0x1b,0x03,0x75,0x5d,0x78,0x66,0xd9,0x3a,0x31,0x44,0x9a,0x33,0x40,0xbf, + 0x08,0xd7,0x5a,0x49,0xa4,0xc2,0xe6,0xa9,0xa0,0x67,0xdd,0xa4,0x27,0xbc,0xa1,0x4f, + 0x39,0xb5,0x11,0x58,0x17,0xf7,0x24,0x5c,0x46,0x8f,0x64,0xf7,0xc1,0x69,0x88,0x76, + 0x98,0x76,0x3d,0x59,0x5d,0x42,0x76,0x87,0x89,0x97,0x69,0x7a,0x48,0xf0,0xe0,0xa2, + 0x12,0x1b,0x66,0x9a,0x74,0xca,0xde,0x4b,0x1e,0xe7,0x0e,0x63,0xae,0xe6,0xd4,0xef, + 0x92,0x92,0x3a,0x9e,0x3d,0xdc,0x00,0xe4,0x45,0x25,0x89,0xb6,0x9a,0x44,0x19,0x2b, + 0x7e,0xc0,0x94,0xb4,0xd2,0x61,0x6d,0xeb,0x33,0xd9,0xc5,0xdf,0x4b,0x04,0x00,0xcc, + 0x7d,0x1c,0x95,0xc3,0x8f,0xf7,0x21,0xb2,0xb2,0x11,0xb7,0xbb,0x7f,0xf2,0xd5,0x8c, + 0x70,0x2c,0x41,0x60,0xaa,0xb1,0x63,0x18,0x44,0x95,0x1a,0x76,0x62,0x7e,0xf6,0x80, + 0xb0,0xfb,0xe8,0x64,0xa6,0x33,0xd1,0x89,0x07,0xe1,0xbd,0xb7,0xe6,0x43,0xa4,0x18, + 0xb8,0xa6,0x77,0x01,0xe1,0x0f,0x94,0x0c,0x21,0x1d,0xb2,0x54,0x29,0x25,0x89,0x6c, + 0xe5,0x0e,0x52,0x51,0x47,0x74,0xbe,0x26,0xac,0xb6,0x41,0x75,0xde,0x7a,0xac,0x5f, + 0x8d,0x3f,0xc9,0xbc,0xd3,0x41,0x11,0x12,0x5b,0xe5,0x10,0x50,0xeb,0x31,0xc5,0xca, + 0x72,0x16,0x22,0x09,0xdf,0x7c,0x4c,0x75,0x3f,0x63,0xec,0x21,0x5f,0xc4,0x20,0x51, + 0x6b,0x6f,0xb1,0xab,0x86,0x8b,0x4f,0xc2,0xd6,0x45,0x5f,0x9d,0x20,0xfc,0xa1,0x1e, + 0xc5,0xc0,0x8f,0xa2,0xb1,0x7e,0x0a,0x26,0x99,0xf5,0xe4,0x69,0x2f,0x98,0x1d,0x2d, + 0xf5,0xd9,0xa9,0xb2,0x1d,0xe5,0x1b,0x02,0x03,0x01,0x00,0x01,0xa3,0x42,0x30,0x40, + 0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01, + 0xff,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x01, + 0x86,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,0x16,0x04,0x14,0xec,0xd7,0xe3,0x82, + 0xd2,0x71,0x5d,0x64,0x4c,0xdf,0x2e,0x67,0x3f,0xe7,0xba,0x98,0xae,0x1c,0x0f,0x4f, + 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0c,0x05,0x00,0x03, + 0x82,0x02,0x01,0x00,0xbb,0x61,0xd9,0x7d,0xa9,0x6c,0xbe,0x17,0xc4,0x91,0x1b,0xc3, + 0xa1,0xa2,0x00,0x8d,0xe3,0x64,0x68,0x0f,0x56,0xcf,0x77,0xae,0x70,0xf9,0xfd,0x9a, + 0x4a,0x99,0xb9,0xc9,0x78,0x5c,0x0c,0x0c,0x5f,0xe4,0xe6,0x14,0x29,0x56,0x0b,0x36, + 0x49,0x5d,0x44,0x63,0xe0,0xad,0x9c,0x96,0x18,0x66,0x1b,0x23,0x0d,0x3d,0x79,0xe9, + 0x6d,0x6b,0xd6,0x54,0xf8,0xd2,0x3c,0xc1,0x43,0x40,0xae,0x1d,0x50,0xf5,0x52,0xfc, + 0x90,0x3b,0xbb,0x98,0x99,0x69,0x6b,0xc7,0xc1,0xa7,0xa8,0x68,0xa4,0x27,0xdc,0x9d, + 0xf9,0x27,0xae,0x30,0x85,0xb9,0xf6,0x67,0x4d,0x3a,0x3e,0x8f,0x59,0x39,0x22,0x53, + 0x44,0xeb,0xc8,0x5d,0x03,0xca,0xed,0x50,0x7a,0x7d,0x62,0x21,0x0a,0x80,0xc8,0x73, + 0x66,0xd1,0xa0,0x05,0x60,0x5f,0xe8,0xa5,0xb4,0xa7,0xaf,0xa8,0xf7,0x6d,0x35,0x9c, + 0x7c,0x5a,0x8a,0xd6,0xa2,0x38,0x99,0xf3,0x78,0x8b,0xf4,0x4d,0xd2,0x20,0x0b,0xde, + 0x04,0xee,0x8c,0x9b,0x47,0x81,0x72,0x0d,0xc0,0x14,0x32,0xef,0x30,0x59,0x2e,0xae, + 0xe0,0x71,0xf2,0x56,0xe4,0x6a,0x97,0x6f,0x92,0x50,0x6d,0x96,0x8d,0x68,0x7a,0x9a, + 0xb2,0x36,0x14,0x7a,0x06,0xf2,0x24,0xb9,0x09,0x11,0x50,0xd7,0x08,0xb1,0xb8,0x89, + 0x7a,0x84,0x23,0x61,0x42,0x29,0xe5,0xa3,0xcd,0xa2,0x20,0x41,0xd7,0xd1,0x9c,0x64, + 0xd9,0xea,0x26,0xa1,0x8b,0x14,0xd7,0x4c,0x19,0xb2,0x50,0x41,0x71,0x3d,0x3f,0x4d, + 0x70,0x23,0x86,0x0c,0x4a,0xdc,0x81,0xd2,0xcc,0x32,0x94,0x84,0x0d,0x08,0x09,0x97, + 0x1c,0x4f,0xc0,0xee,0x6b,0x20,0x74,0x30,0xd2,0xe0,0x39,0x34,0x10,0x85,0x21,0x15, + 0x01,0x08,0xe8,0x55,0x32,0xde,0x71,0x49,0xd9,0x28,0x17,0x50,0x4d,0xe6,0xbe,0x4d, + 0xd1,0x75,0xac,0xd0,0xca,0xfb,0x41,0xb8,0x43,0xa5,0xaa,0xd3,0xc3,0x05,0x44,0x4f, + 0x2c,0x36,0x9b,0xe2,0xfa,0xe2,0x45,0xb8,0x23,0x53,0x6c,0x06,0x6f,0x67,0x55,0x7f, + 0x46,0xb5,0x4c,0x3f,0x6e,0x28,0x5a,0x79,0x26,0xd2,0xa4,0xa8,0x62,0x97,0xd2,0x1e, + 0xe2,0xed,0x4a,0x8b,0xbc,0x1b,0xfd,0x47,0x4a,0x0d,0xdf,0x67,0x66,0x7e,0xb2,0x5b, + 0x41,0xd0,0x3b,0xe4,0xf4,0x3b,0xf4,0x04,0x63,0xe9,0xef,0xc2,0x54,0x00,0x51,0xa0, + 0x8a,0x2a,0xc9,0xce,0x78,0xcc,0xd5,0xea,0x87,0x04,0x18,0xb3,0xce,0xaf,0x49,0x88, + 0xaf,0xf3,0x92,0x99,0xb6,0xb3,0xe6,0x61,0x0f,0xd2,0x85,0x00,0xe7,0x50,0x1a,0xe4, + 0x1b,0x95,0x9d,0x19,0xa1,0xb9,0x9c,0xb1,0x9b,0xb1,0x00,0x1e,0xef,0xd0,0x0f,0x4f, + 0x42,0x6c,0xc9,0x0a,0xbc,0xee,0x43,0xfa,0x3a,0x71,0xa5,0xc8,0x4d,0x26,0xa5,0x35, + 0xfd,0x89,0x5d,0xbc,0x85,0x62,0x1d,0x32,0xd2,0xa0,0x2b,0x54,0xed,0x9a,0x57,0xc1, + 0xdb,0xfa,0x10,0xcf,0x19,0xb7,0x8b,0x4a,0x1b,0x8f,0x01,0xb6,0x27,0x95,0x53,0xe8, + 0xb6,0x89,0x6d,0x5b,0xbc,0x68,0xd4,0x23,0xe8,0x8b,0x51,0xa2,0x56,0xf9,0xf0,0xa6, + 0x80,0xa0,0xd6,0x1e,0xb3,0xbc,0x0f,0x0f,0x53,0x75,0x29,0xaa,0xea,0x13,0x77,0xe4, + 0xde,0x8c,0x81,0x21,0xad,0x07,0x10,0x47,0x11,0xad,0x87,0x3d,0x07,0xd1,0x75,0xbc, + 0xcf,0xf3,0x66,0x7e, + }; + [trustedCertificates addObject:[NSData dataWithBytes:XXX_certificate length:sizeof(XXX_certificate)]]; + } + return [NSArray arrayWithArray:trustedCertificates]; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTSimpleKeychain.m b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTSimpleKeychain.m new file mode 100644 index 0000000..a4a8dc2 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTSimpleKeychain.m @@ -0,0 +1,128 @@ +// adapted from https://raw.github.com/rackspace/rackspace-ios/master/Classes/Keychain.m + +// +// PPOTSimpleKeychain.m +// OpenStack +// +// Based on CardIOKeychain +// Based on KeychainWrapper in BadassVNC by Dylan Barrie +// +// Created by Mike Mayo on 10/1/10. +// The OpenStack project is provided under the Apache 2.0 license. +// + +#import "PPOTSimpleKeychain.h" +#import "PPOTMacros.h" +#import +#import + +@implementation PPOTSimpleKeychain + ++ (NSString *)keychainKeyForKey:(NSString *)key { + // WARNING: don't change this line unless you know what you doing + // If the app upgraded from mSDK (PayPal Touch) to OTC, we want to re-use app GUID; + // therefore we are using the same keychain key. + return [NSString stringWithFormat:CARDIO_STR(@"card.io - %@"), key]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key { + if (!key) { + return NO; + } + + BOOL success = YES; + + key = [self keychainKeyForKey:key]; + +#if TARGET_IPHONE_SIMULATOR + // since keychain sometimes is not available when running unit tests from the terminal + // we decided to simply use user defaults + [[NSUserDefaults standardUserDefaults] setValue:data ? data : [NSData data] forKey:key]; + [[NSUserDefaults standardUserDefaults] synchronize]; + return success; +#else + + // First check if it already exists, by creating a search dictionary and requesting that + // nothing be returned, and performing the search anyway. + NSMutableDictionary *existsQueryDictionary = [NSMutableDictionary dictionary]; + + [existsQueryDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; + + // Add the keys to the search dict + [existsQueryDictionary setObject:CARDIO_STR(@"service") forKey:(__bridge id)kSecAttrService]; + [existsQueryDictionary setObject:key forKey:(__bridge id)kSecAttrAccount]; + + OSStatus res = SecItemCopyMatching((__bridge CFDictionaryRef)existsQueryDictionary, NULL); + if (res == errSecItemNotFound) { + if (data) { + NSMutableDictionary *addDict = existsQueryDictionary; + [addDict setObject:data forKey:(__bridge id)kSecValueData]; + [addDict setObject:(__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly forKey:(__bridge id)kSecAttrAccessible]; + + res = SecItemAdd((__bridge CFDictionaryRef)addDict, NULL); + if (res != errSecSuccess) { + success = NO; + } + } + } else if (res == errSecSuccess) { + if(data) { + // Modify an existing one + // Actually pull it now off the keychain at this point. + NSDictionary *attributeDict = [NSDictionary dictionaryWithObject:data forKey:(__bridge id)kSecValueData]; + + res = SecItemUpdate((__bridge CFDictionaryRef)existsQueryDictionary, (__bridge CFDictionaryRef)attributeDict); + if (res != errSecSuccess) { + success = NO; + } + } else { + SecItemDelete((__bridge CFDictionaryRef)existsQueryDictionary); + } + } else { + success = NO; + } + + return success; +#endif +} + ++ (NSData *)dataForKey:(NSString *)key { + + key = [self keychainKeyForKey:key]; + +#if TARGET_IPHONE_SIMULATOR + return [[NSUserDefaults standardUserDefaults] valueForKey:key]; +#else + + NSMutableDictionary *existsQueryDictionary = [NSMutableDictionary dictionary]; + + [existsQueryDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; + + // Add the keys to the search dict + [existsQueryDictionary setObject:CARDIO_STR(@"service") forKey:(__bridge id)kSecAttrService]; + [existsQueryDictionary setObject:key forKey:(__bridge id)kSecAttrAccount]; + + // We want the data back! + [existsQueryDictionary setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData]; + + CFTypeRef cfData = NULL; + OSStatus res = SecItemCopyMatching((__bridge CFDictionaryRef)existsQueryDictionary, &cfData); + NSData *data = (id)CFBridgingRelease(cfData); + if (res == errSecSuccess) { + return data; + } + + return nil; +#endif +} + ++ (id)unarchiveObjectWithDataForKey:(NSString *)key { + NSData *data = [PPOTSimpleKeychain dataForKey:key]; + if ([data length]) { + return [NSKeyedUnarchiver unarchiveObjectWithData:data]; + } + else { + return nil; + } +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTString.m b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTString.m new file mode 100644 index 0000000..8c01095 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTString.m @@ -0,0 +1,237 @@ +// +// PPOTString.m +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTString.h" +#import "PPOTMacros.h" +#import + +static const short _base64DecodingTable[256] = { + -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -1, -1, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2, + -2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2, + -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2 +}; + +@implementation PPOTString + ++ (NSString *)stringByURLEncodingAllCharactersInString:(NSString *)aString { + NSString *reservedCharacters = @"&()<>@,;:\\\"/[]?=+$|^~`{}"; + + NSMutableCharacterSet *URLQueryPartAllowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy]; + [URLQueryPartAllowedCharacterSet removeCharactersInString:reservedCharacters]; + + return [aString stringByAddingPercentEncodingWithAllowedCharacters:URLQueryPartAllowedCharacterSet]; +} + +// This base 64 encoding adapted from Colloquy's BSD-licensed Chat Core library + +static char base64encodingTable[64] = { + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', + 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', + 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', + 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' +}; + ++ (NSString *)stringByBase64EncodingData:(NSData *)data { + return [self stringByBase64EncodingData:data lineLength:0]; +} + ++ (NSString *)stringByBase64EncodingData:(NSData *)data lineLength:(NSUInteger)lineLength { + const unsigned char *bytes = [data bytes]; + NSMutableString *result = [NSMutableString stringWithCapacity:[data length]]; + unsigned long ixtext = 0; + unsigned long lentext = [data length]; + long ctremaining = 0; + unsigned char inbuf[3], outbuf[4]; + unsigned short i = 0; + unsigned short charsonline = 0, ctcopy = 0; + unsigned long ix = 0; + + while( YES ) { + ctremaining = lentext - ixtext; + if( ctremaining <= 0 ) break; + + for( i = 0; i < 3; i++ ) { + ix = ixtext + i; + if( ix < lentext ) inbuf[i] = bytes[ix]; + else inbuf [i] = 0; + } + + outbuf [0] = (unsigned char)((inbuf [0] & 0xFC) >> 2); + outbuf [1] = (unsigned char)(((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4)); + outbuf [2] = (unsigned char)(((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6)); + outbuf [3] = inbuf [2] & 0x3F; + ctcopy = 4; + + switch( ctremaining ) { + case 1: + ctcopy = 2; + break; + case 2: + ctcopy = 3; + break; + } + + for( i = 0; i < ctcopy; i++ ) + [result appendFormat:@"%c", base64encodingTable[outbuf[i]]]; + + for( i = ctcopy; i < 4; i++ ) + [result appendString:@"="]; + + ixtext += 3; + charsonline += 4; + + if( lineLength > 0 ) { + if( charsonline >= lineLength ) { + charsonline = 0; + [result appendString:@"\n"]; + } + } + } + + return [NSString stringWithString:result]; +} + + ++ (NSData *)decodeBase64WithString:(NSString *)strBase64 { + const char * objPointer = [strBase64 cStringUsingEncoding:NSASCIIStringEncoding]; + if (objPointer == NULL) return nil; + size_t intLength = strlen(objPointer); + int intCurrent; + int i = 0, j = 0, k; + + unsigned char * objResult; + objResult = calloc(intLength, sizeof(unsigned char)); + + // Run through the whole string, converting as we go + while ( ((intCurrent = *objPointer++) != '\0') && (intLength-- > 0) ) { + if (intCurrent == '=') { + if (*objPointer != '=' && ((i % 4) == 1)) {// || (intLength > 0)) { + // the padding character is invalid at this point -- so this entire string is invalid + free(objResult); + return nil; + } + continue; + } + + intCurrent = _base64DecodingTable[intCurrent]; + if (intCurrent == -1) { + // we're at a whitespace -- simply skip over + continue; + } else if (intCurrent == -2) { + // we're at an invalid character + free(objResult); + return nil; + } + + switch (i % 4) { + case 0: + objResult[j] = (unsigned char)(intCurrent << 2); + break; + + case 1: + objResult[j++] |= (unsigned char)(intCurrent >> 4); + objResult[j] = (unsigned char)((intCurrent & 0x0f) << 4); + break; + + case 2: + objResult[j++] |= (unsigned char)(intCurrent >>2); + objResult[j] = (unsigned char)((intCurrent & 0x03) << 6); + break; + + case 3: + objResult[j++] |= (unsigned char)intCurrent; + break; + } + i++; + } + + // mop things up if we ended on a boundary + k = j; + if (intCurrent == '=') { + switch (i % 4) { + case 1: + // Invalid state + free(objResult); + return nil; + + case 2: + k++; + // flow through + case 3: + objResult[k] = 0; + } + } + + // Cleanup and setup the return NSData + return [[NSData alloc] initWithBytesNoCopy:objResult length:j freeWhenDone:YES]; +} + ++ (NSUInteger)numberOfLinesInString:(NSString *)str { + // probably not the most efficient implementation (see e.g. https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/TextLayout/Tasks/CountLines.html) + // ...but very obviously correct :) + __block NSUInteger nLines = 0; + [str enumerateLinesUsingBlock:^(__attribute__((unused)) NSString *line, BOOL *stop) { + nLines++; + *stop = NO; + }]; + return nLines; +} + ++ (NSString *)generateUniquishIdentifier { + CFUUIDRef uuid = CFUUIDCreate(NULL); + CFStringRef uuidStr = CFUUIDCreateString(NULL, uuid); + CFRelease(uuid); + NSString *result = (__bridge_transfer NSString *)uuidStr; + return result; +} + +#pragma mark - Hex String + ++ (NSString *)hexStringFromData:(NSData *)data { + NSMutableString *hexString = [NSMutableString string]; + const char* bytes = [data bytes]; + for (NSUInteger index = 0; index < data.length; index++) { + [hexString appendFormat:@"%02hhX", bytes[index]]; + } + return hexString; +} + ++ (NSData *)dataWithHexString:(NSString *)hexString { + // + // NSData+HexString.m + // libsecurity_transform + // + // Copyright (c) 2011 Apple, Inc. All rights reserved. + // + char buf[3]; + buf[2] = '\0'; + NSAssert(0 == [hexString length] % 2, @"Hex strings should have an even number of digits (%@)", hexString); + unsigned char *bytes = malloc([hexString length]/2); + unsigned char *bp = bytes; + for (NSUInteger i = 0; i < [hexString length]; i += 2) { + buf[0] = [hexString characterAtIndex:i]; + buf[1] = [hexString characterAtIndex:i+1]; + char *b2 = NULL; + *bp++ = strtol(buf, &b2, 16); + //NSAssert(b2 == buf + 2, @"String should be all hex digits: %@ (bad digit around %ld)", hexString, i); + } + + return [NSData dataWithBytesNoCopy:bytes length:[hexString length]/2 freeWhenDone:YES]; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTTime.m b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTTime.m new file mode 100644 index 0000000..b84a7a3 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTTime.m @@ -0,0 +1,63 @@ +// +// PPOTTime.m +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import "PPOTMacros.h" +#import "PPOTTime.h" + +@implementation PPOTTime + ++ (NSDateFormatter *)rfc3339DateFormatter { + /* + Adapted from the Apple docs someplace... + + Note that this does not handle all possible + RFC 3339 date time strings, just one of the most common styles. + */ + static NSDateFormatter *rfc3339DateFormatter; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + rfc3339DateFormatter = [[NSDateFormatter alloc] init]; + NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; + + [rfc3339DateFormatter setLocale:enUSPOSIXLocale]; + [rfc3339DateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"]; + [rfc3339DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; + }); + + return rfc3339DateFormatter; +} + ++ (NSDateFormatter *)rfc3339MillisecondDateFormatter { + static NSDateFormatter* rfc3339millisecondDateFormatter; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + rfc3339millisecondDateFormatter = [[PPOTTime rfc3339DateFormatter] copy]; + [rfc3339millisecondDateFormatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSS'Z'"]; + }); + + return rfc3339millisecondDateFormatter; +} + +// sometimes the server supplied date has a millisecond component. Sometimes not. Easier to just deal with it. ++ (NSDate *)dateFromRFC3339LikeString:(NSString *)dateStr { + if (dateStr == nil) { + return nil; + } + + NSDate* result = [[PPOTTime rfc3339DateFormatter] dateFromString:dateStr]; + if (!result) { + result = [[PPOTTime rfc3339MillisecondDateFormatter] dateFromString:dateStr]; + + if (!result) { + PPLog(@"WARNING - could not parse '%@' into date!", dateStr); + } + } + + return result; +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTURLSession.m b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTURLSession.m new file mode 100644 index 0000000..7fde084 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/PPOTURLSession.m @@ -0,0 +1,134 @@ +// +// PPOTSimpleURLConnection.m +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import + +#import "PPOTURLSession.h" + +#import "PPOTMacros.h" +#import "PPOTPinnedCertificates.h" + +#import "PPOTDevice.h" +#import "PPOTVersion.h" + +#define STATUS_IS_FAIL(x) (x < 200 || x >= 300) + +@interface PPOTURLSession () + +/// An optional array of pinned certificates, each an NSData instance +/// consisting of DER encoded x509 certificates +@property (nonatomic, nullable, strong) NSArray *pinnedCertificates; + +@property (nonatomic, strong, readwrite) NSURLSession *session; +@property (nonatomic, strong, readwrite) NSURLSessionConfiguration *sessionConfig; + +@end + +@implementation PPOTURLSession + ++ (PPOTURLSession *)session { + return [PPOTURLSession sessionWithTimeoutIntervalForRequest:0]; +} + ++ (PPOTURLSession *)sessionWithTimeoutIntervalForRequest:(NSTimeInterval)timeoutIntervalForRequest { + PPOTURLSession *session = [[PPOTURLSession alloc] initWithTimeoutIntervalForRequest:timeoutIntervalForRequest]; + return session; +} + +- (nonnull instancetype)initWithTimeoutIntervalForRequest:(NSTimeInterval)timeoutIntervalForRequest { + self = [super init]; + if (self) { + self.sessionConfig = [NSURLSessionConfiguration ephemeralSessionConfiguration]; + self.sessionConfig.requestCachePolicy = NSURLRequestReloadIgnoringCacheData; + self.sessionConfig.HTTPShouldUsePipelining = YES; + self.sessionConfig.HTTPAdditionalHeaders = @{ @"User-Agent": [PPOTURLSession computeUserAgent] }; + if (timeoutIntervalForRequest > 0) { + self.sessionConfig.timeoutIntervalForRequest = timeoutIntervalForRequest; + } + self.session = [NSURLSession sessionWithConfiguration:self.sessionConfig + delegate:self + delegateQueue:nil]; + + self.pinnedCertificates = [PPOTPinnedCertificates trustedCertificates]; + } + + return self; +} + +- (void)sendRequest:(nonnull NSURLRequest *)request completionBlock:(nullable PPOTURLSessionCompletionBlock)completionBlock { + NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request + completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { + completionBlock(data, (NSHTTPURLResponse *)response, error); + }]; + [task resume]; +} + +- (void)finishTasksAndInvalidate { + [self.session finishTasksAndInvalidate]; +} + ++ (NSString *)computeUserAgent { + NSLocale *currentLocale = [NSLocale currentLocale]; + NSString *countryCode = [currentLocale objectForKey:NSLocaleCountryCode]; + NSString *language = [currentLocale objectForKey:NSLocaleLanguageCode]; + +#ifdef DEBUG + NSString *releaseMode = @"DEBUG"; +#else + NSString *releaseMode = @"RELEASE"; +#endif + + // PayPalSDK/OneTouchCore-iOS 3.2.2-11-g8b1c0e3 (iPhone; CPU iPhone OS 8_4_1; en-US; iPhone (iPhone5,1); iPhone5,1; DEBUG) + return [NSString stringWithFormat:@"PayPalSDK/OneTouchCore-iOS %@ (%@; CPU %@ %@; %@-%@; %@; %@; %@)", + PayPalOTVersion(), + [UIDevice currentDevice].model, + [UIDevice currentDevice].systemName, + [[UIDevice currentDevice].systemVersion stringByReplacingOccurrencesOfString:@"." withString:@"_"], + language, + countryCode, + [PPOTDevice deviceName], + [PPOTDevice hardwarePlatform], + releaseMode + ]; +} + + +#pragma mark - NSURLSessionDelegate methods + +- (NSArray *)pinnedCertificateData { + NSMutableArray *pinnedCertificates = [NSMutableArray array]; + for (NSData *certificateData in self.pinnedCertificates) { + [pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)]; + } + return pinnedCertificates; +} + +- (void)URLSession:(__unused NSURLSession *)session +didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge + completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler { + if ([[[challenge protectionSpace] authenticationMethod] isEqualToString:NSURLAuthenticationMethodServerTrust]) { + NSString *domain = challenge.protectionSpace.host; + SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust]; + + NSArray *policies = @[(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)]; + SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies); + SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)self.pinnedCertificateData); + SecTrustResultType result; + + OSStatus errorCode = SecTrustEvaluate(serverTrust, &result); + + BOOL evaluatesAsTrusted = (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed); + if (errorCode == errSecSuccess && evaluatesAsTrusted) { + NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust]; + completionHandler(NSURLSessionAuthChallengeUseCredential, credential); + } else { + completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, NULL); + } + } else { + completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, NULL); + } +} + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTDevice.h b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTDevice.h new file mode 100644 index 0000000..8ced0c9 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTDevice.h @@ -0,0 +1,37 @@ +// +// PPOTDevice.h +// Copyright © 2009 PayPal, Inc. All rights reserved. +// + +#import + +@interface PPOTDevice : NSObject + +/** + @return the hardware platform used +*/ ++ (nonnull NSString *)hardwarePlatform; + +/** + @return the name of the device +*/ ++ (nonnull NSString *)deviceName; + +/** + @return the device's locale +*/ ++ (nonnull NSString *)complicatedDeviceLocale; + +/** + @brief Generates a device identifier and stores it. + + @return a generated device identifier +*/ ++ (nonnull NSString *)appropriateIdentifier; + +/** + @brief Clears any stored device identifier. +*/ ++ (void)clearIdentifier; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTEncryptionHelper.h b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTEncryptionHelper.h new file mode 100644 index 0000000..827d387 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTEncryptionHelper.h @@ -0,0 +1,46 @@ +// +// PPOTEncryptionHelper.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import + +@interface PPOTEncryptionHelper : NSObject + +/** + @brief Generates a random 256-bit key to encrypt data with + + @return a 256-bit encryption key +*/ ++ (nonnull NSData *)generate256BitKey; + +/** + @brief Encrypt the data using the encryption key. + + @param plainData the data to encrypt + @param key the encryption key to use + @return the encrypted data +*/ ++ (nullable NSData *)encryptAESCTRData:(nonnull NSData *)plainData encryptionKey:(nonnull NSData *)key; + +/** + @brief Decrypt the data using the encryption key. + + @param cipherData the encrypted data + @param key the encryption key used + @return the decrypted data +*/ ++ (nullable NSData *)decryptAESCTRData:(nonnull NSData *)cipherData encryptionKey:(nonnull NSData *)key; + +/** + @brief Encrypts data using the given certificate + + @param plainData the data to encrypt + @param certificate the certificate to use + @return the encrypted data +*/ ++ (nullable NSData *)encryptRSAData:(nonnull NSData *)plainData certificate:(nonnull NSData *)certificate; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTJSONHelper.h b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTJSONHelper.h new file mode 100644 index 0000000..180989a --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTJSONHelper.h @@ -0,0 +1,24 @@ +// +// PPOTJSONHelper.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import + +@interface PPOTJSONHelper : NSObject + ++ (nullable NSString *)stringFromDictionary:(nonnull NSDictionary *)dictionary withKey:(nonnull NSString *)key; ++ (nullable NSDictionary *)dictionaryFromDictionary:(nonnull NSDictionary *)dictionary withKey:(nonnull NSString *)key; + ++ (nullable NSArray *)arrayFromDictionary:(nonnull NSDictionary *)dictionary withKey:(nonnull NSString *)key; ++ (nullable NSArray *)stringArrayFromDictionary:(nonnull NSDictionary *)dictionary withKey:(nonnull NSString *)key; ++ (nullable NSArray *)dictionaryArrayFromDictionary:(nonnull NSDictionary *)dictionary withKey:(nonnull NSString *)key; + ++ (nullable NSString *)base64EncodedJSONStringWithDictionary:(nonnull NSDictionary *)dictionary; ++ (nullable NSDictionary *)dictionaryWithBase64EncodedJSONString:(nonnull NSString *)base64String; + ++ (nullable NSNumber *)numberFromDictionary:(nonnull NSDictionary *)dictionary withKey:(nonnull NSString *)key; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTMacros.h b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTMacros.h new file mode 100644 index 0000000..f102591 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTMacros.h @@ -0,0 +1,68 @@ +// +// PPOTMacros.h +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import + +#define PPSDKLog(format, args...) NSLog(@"%@", [NSString stringWithFormat:@"PayPal OneTouchCoreSDK: %@", [NSString stringWithFormat:format, ## args]]) + +// PPLog is a replacement for NSLog that logs iff DEBUG is set. +#if DEBUG +#define PPLog(format, args...) NSLog(format, ## args) +#else +#define PPLog(format, args...) +#endif + +// PPAssert* are replacements for NSAssert, NSAssert1, etc. +// Whether the latter are enabled or disabled depends upon NS_BLOCK_ASSERTIONS; +// we set NS_BLOCK_ASSERTIONS inside our .pch files based upon DEBUG. +// Those #defines are a little bit fragile, and could easily accidentally get broken in the future. +// So PPAssert* depend explicitly on DEBUG, just to be a bit more safe. +#if DEBUG + #define PPAssert(condition, desc...) NSAssert(condition, desc) + #define PPAssert1(condition, desc, arg1) NSAssert1(condition, desc, arg1) + #define PPAssert2(condition, desc, arg1, arg2) NSAssert2(condition, desc, arg1, arg2) + #define PPAssert3(condition, desc, arg1, arg2, arg3) NSAssert3(condition, desc, arg1, arg2, arg3) + #define PPAssert4(condition, desc, arg1, arg2, arg3, arg4) NSAssert4(condition, desc, arg1, arg2, arg3, arg4) + #define PPAssert5(condition, desc, arg1, arg2, arg3, arg4, arg5) NSAssert5(condition, desc, arg1, arg2, arg3, arg4, arg5) + #define PPParameterAssert(condition) NSParameterAssert(condition) +#else + #define PPAssert(condition, desc, ...) + #define PPAssert1(condition, desc, arg1) + #define PPAssert2(condition, desc, arg1, arg2) + #define PPAssert3(condition, desc, arg1, arg2, arg3) + #define PPAssert4(condition, desc, arg1, arg2, arg3, arg4) + #define PPAssert5(condition, desc, arg1, arg2, arg3, arg4, arg5) + #define PPParameterAssert(condition) +#endif + +@interface PPOTMacros : NSObject + +/** + @return the iOS major version number +*/ ++ (NSUInteger)deviceSystemMajorVersion; + +@end + +#define iOS_MAJOR_VERSION [PPOTMacros deviceSystemMajorVersion] +#define iOS_9_PLUS ([PPOTMacros deviceSystemMajorVersion] >= 9) +#define iOS_8_PLUS ([PPOTMacros deviceSystemMajorVersion] >= 8) +#define iOS_7_PLUS ([PPOTMacros deviceSystemMajorVersion] >= 7) +#define iOS_6_PLUS ([PPOTMacros deviceSystemMajorVersion] >= 6) +#define iOS_6 ([PPOTMacros deviceSystemMajorVersion] == 6) +#define iOS_5 ([PPOTMacros deviceSystemMajorVersion] == 5) + +#define FORCE_VALUE_OR_NULL(x) (x ? x : [NSNull null]) + +// Use the CARDIO_STR() macro around sensitive string literals. +// E.g., `CARDIO_STR(@"http://top_secret_url.paypal.com")`. +// For release builds, uses of this macro get preprocessed by fabfile.py to obfuscate the string. +// PLEASE do not include any whitespace on either side of the string inside the parentheses; +// i.e., between `CARDIO_STR(` and `@"abc"`, or between `@"abc"` and the closing `)`. +#define CARDIO_STR(string) string + +#define PPRGBAUIColor(RR, GG, BB, AA) ([UIColor colorWithRed:(RR)/255.0f green:(GG)/255.0f blue:(BB)/255.0f alpha:(AA)/255.0f]) + + diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTPinnedCertificates.h b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTPinnedCertificates.h new file mode 100644 index 0000000..1d3f6ae --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTPinnedCertificates.h @@ -0,0 +1,19 @@ +// +// PPOTPinnedCertificates.h +// PayPalOneTouch +// +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import + +@interface PPOTPinnedCertificates : NSObject + +/** + @brief Returns the set of trusted root certificates + + @return An array of trusted certificates encoded in the DER format, encapsulated in NSData objects. +*/ ++ (NSArray *)trustedCertificates; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTSimpleKeychain.h b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTSimpleKeychain.h new file mode 100644 index 0000000..901da31 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTSimpleKeychain.h @@ -0,0 +1,47 @@ +// adapted from https://raw.github.com/rackspace/rackspace-ios/master/Classes/Keychain.h + +// +// PPOTSimpleKeychain.h +// OpenStack +// +// Based on CardIOKeychain +// Based on KeychainWrapper in BadassVNC by Dylan Barrie +// +// Created by Mike Mayo on 10/1/10. +// The OpenStack project is provided under the Apache 2.0 license. +// + +#import + +/** + @brief Wrapper to help deal with Keychain-related things such as storing API keys and passwords. + @discussion The key used in the methods may not be the actual key used in the keychain +*/ +@interface PPOTSimpleKeychain : NSObject + +/** + @brief Sets the given data for the given key + + @param data the data to set, null if any data associated with the key should be deleted + @param key the key to use + @return YES if successful, NO if not +*/ ++ (BOOL)setData:(nullable NSData *)data forKey:(nonnull NSString *)key; + +/** + @brief Retrieves the data associated with the given key + + @param key the key to use + @return any data associated with the key +*/ ++ (nullable NSData *)dataForKey:(nonnull NSString *)key; + +/** + @brief Retrieves the unarchived object with the given key + + @param key the key to use + @return the unarchived object associated with the given key +*/ ++ (nullable id)unarchiveObjectWithDataForKey:(nonnull NSString *)key; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTString.h b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTString.h new file mode 100644 index 0000000..515db15 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTString.h @@ -0,0 +1,58 @@ +// +// PPOTString.m +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import +#import + +@interface PPOTString : NSObject + +/** + @brief URL encodes all characters in a given string including &, %, ?, =, and other URL "safe" characters + + @param aString the string to encode + @return the encoded string +*/ ++ (nonnull NSString *)stringByURLEncodingAllCharactersInString:(nonnull NSString *)aString; + +/** + @brief Base64 encoded version of the data + + @param data Data to base64 encode + @return the base64 encoded data as a string +*/ ++ (nonnull NSString *)stringByBase64EncodingData:(nonnull NSData *)data; + +/** + @brief Decoded a base64 string back into data + + @param strBase64 the string base64 encoded + @return the decoded data +*/ ++ (nullable NSData *)decodeBase64WithString:(nonnull NSString *)strBase64; + +/** + @brief Generates a random identifier + + @return a uniquish identifier +*/ ++ (nonnull NSString *)generateUniquishIdentifier; + +/** + @brief Converts a NSData to a hexadecimal NSString + + @param data the data to convert + @return a hexadecimal string from given byte data +*/ ++ (nonnull NSString *)hexStringFromData:(nonnull NSData *)data; + +/** + @brief Converts a hexadecimal string into a NSData representation + + @param hexString the string to convert + @return the converted value representation of the hexadecimal string +*/ ++ (nonnull NSData *)dataWithHexString:(nonnull NSString *)hexString; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTTime.h b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTTime.h new file mode 100644 index 0000000..1d662c1 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTTime.h @@ -0,0 +1,25 @@ +// +// PPOTTime.h +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import + +/** + @brief Collection of time utility methods +*/ +@interface PPOTTime : NSObject + +/** + @return A RFC 3339 ( 2012-08-10T14:22:56.864-07:00 ) date formatter. +*/ ++ (nonnull NSDateFormatter *)rfc3339DateFormatter; + +/** + @brief Parses a string for an RFC 3339 like date string. Tries a few different options for misbehaving servers. + + @return Date from RFC339-like string +*/ ++ (nullable NSDate *)dateFromRFC3339LikeString:(nullable NSString *)dateStr; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTURLSession.h b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTURLSession.h new file mode 100644 index 0000000..3b8d5f0 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTURLSession.h @@ -0,0 +1,42 @@ +// +// PPOTURLSession.h +// Copyright © 2015 PayPal, Inc. All rights reserved. +// + +#import + +/** + @brief Request completion callback type +*/ +typedef void(^PPOTURLSessionCompletionBlock)(NSData * _Nullable data, NSHTTPURLResponse * _Nullable response, NSError * _Nullable error); + +/** + @brief A URL session to manage network connections +*/ +@interface PPOTURLSession: NSObject + +/** + @return a session to send requests +*/ ++ (nonnull PPOTURLSession *)session; + +/** + @return a session to send requests with a specific timeout for requests +*/ ++ (nonnull PPOTURLSession *)sessionWithTimeoutIntervalForRequest:(NSTimeInterval)timeoutIntervalForRequest; + +/** + @brief Sends a URL request + + @param request the request to send + @param completionBlock the completion block invoked for the response +*/ +- (void)sendRequest:(nonnull NSURLRequest *)request + completionBlock:(nullable PPOTURLSessionCompletionBlock)completionBlock; + +/** + @brief Attempts to stop the session from accepting any future requests +*/ +- (void)finishTasksAndInvalidate; + +@end diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTVersion.h b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTVersion.h new file mode 100644 index 0000000..b927185 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PPOTVersion.h @@ -0,0 +1,11 @@ +// +// PPOTVersion.h +// + + +#ifndef PPOTVersion_h +#define PPOTVersion_h + +#define PayPalOTVersion() @"4.9.6" + +#endif diff --git a/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PayPalUtils.h b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PayPalUtils.h new file mode 100644 index 0000000..8e49f4d --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/PayPalUtils/Public/PayPalUtils.h @@ -0,0 +1,18 @@ +#import + +//! Project version number for PayPalUtils. +FOUNDATION_EXPORT double PayPalUtilsVersionNumber; + +//! Project version string for PayPalUtils. +FOUNDATION_EXPORT const unsigned char PayPalUtilsVersionString[]; + +#import "PPOTDevice.h" +#import "PPOTEncryptionHelper.h" +#import "PPOTJSONHelper.h" +#import "PPOTMacros.h" +#import "PPOTPinnedCertificates.h" +#import "PPOTSimpleKeychain.h" +#import "PPOTString.h" +#import "PPOTTime.h" +#import "PPOTURLSession.h" +#import "PPOTVersion.h" diff --git a/Pods/Braintree/BraintreePayPal/Public/BTConfiguration+PayPal.h b/Pods/Braintree/BraintreePayPal/Public/BTConfiguration+PayPal.h new file mode 100644 index 0000000..9e4016a --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/Public/BTConfiguration+PayPal.h @@ -0,0 +1,15 @@ +#if __has_include("BraintreeCore.h") +#import "BTConfiguration.h" +#else +#import +#endif + +@interface BTConfiguration (PayPal) + +/** + @brief Indicates whether PayPal is enabled for the merchant account. +*/ +@property (nonatomic, readonly, assign) BOOL isPayPalEnabled; +@property (nonatomic, readonly, assign) BOOL isBillingAgreementsEnabled; + +@end diff --git a/Pods/Braintree/BraintreePayPal/Public/BTPayPalAccountNonce.h b/Pods/Braintree/BraintreePayPal/Public/BTPayPalAccountNonce.h new file mode 100644 index 0000000..555833d --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/Public/BTPayPalAccountNonce.h @@ -0,0 +1,60 @@ +#import +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif +#import "BTPayPalCreditFinancing.h" + +@interface BTPayPalAccountNonce : BTPaymentMethodNonce + +/** + @brief Payer's email address +*/ +@property (nonatomic, nullable, readonly, copy) NSString *email; + +/** + @brief Payer's first name. +*/ +@property (nonatomic, nullable, readonly, copy) NSString *firstName; + +/** + @brief Payer's last name. +*/ +@property (nonatomic, nullable, readonly, copy) NSString *lastName; + +/** + @brief Payer's phone number. +*/ +@property (nonatomic, nullable, readonly, copy) NSString *phone; + +/** + @brief The billing address. +*/ +@property (nonatomic, nullable, readonly, strong) BTPostalAddress *billingAddress; + +/** + @brief The shipping address. +*/ +@property (nonatomic, nullable, readonly, strong) BTPostalAddress *shippingAddress; + +/** + @brief Client Metadata Id associated with this transaction. +*/ +@property (nonatomic, nullable, readonly, copy) NSString *clientMetadataId; + +/** + @brief Optional. Payer Id associated with this transaction. + + @discussion Will be provided for Billing Agreement and Checkout. +*/ +@property (nonatomic, nullable, readonly, copy) NSString *payerId; + +/** + @brief Optional. Credit financing details if the customer pays with PayPal Credit. + + @discussion Will be provided for Billing Agreement and Checkout. + */ +@property (nonatomic, nullable, readonly, strong) BTPayPalCreditFinancing *creditFinancing; + +@end diff --git a/Pods/Braintree/BraintreePayPal/Public/BTPayPalCreditFinancing.h b/Pods/Braintree/BraintreePayPal/Public/BTPayPalCreditFinancing.h new file mode 100644 index 0000000..1148c55 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/Public/BTPayPalCreditFinancing.h @@ -0,0 +1,54 @@ +#import +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif + +@interface BTPayPalCreditFinancingAmount: NSObject + +/** + @brief 3 letter currency code as defined by ISO 4217. + */ +@property (nonatomic, nullable, readonly, copy) NSString *currency; + +/** + @brief An amount defined by ISO 4217 for the given currency. + */ +@property (nonatomic, nullable, readonly, copy) NSString *value; + +@end + +@interface BTPayPalCreditFinancing: NSObject + +/** + @brief Indicates whether the card amount is editable after payer's acceptance on PayPal side. + */ +@property (nonatomic, readonly) BOOL cardAmountImmutable; + +/** + @brief Estimated amount per month that the customer will need to pay including fees and interest. + */ +@property (nonatomic, nullable, readonly, strong) BTPayPalCreditFinancingAmount *monthlyPayment; + +/** + @brief Status of whether the customer ultimately was approved for and chose to make the payment using the approved installment credit. + */ +@property (nonatomic, readonly) BOOL payerAcceptance; + +/** + @brief Length of financing terms in months. + */ +@property (nonatomic, readonly) NSInteger term; + +/** + @brief Estimated total payment amount including interest and fees the user will pay during the lifetime of the loan. + */ +@property (nonatomic, nullable, readonly, strong) BTPayPalCreditFinancingAmount *totalCost; + +/** + @brief Estimated interest or fees amount the payer will have to pay during the lifetime of the loan. + */ +@property (nonatomic, nullable, readonly, strong) BTPayPalCreditFinancingAmount *totalInterest; + +@end diff --git a/Pods/Braintree/BraintreePayPal/Public/BTPayPalDriver.h b/Pods/Braintree/BraintreePayPal/Public/BTPayPalDriver.h new file mode 100644 index 0000000..c4bd969 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/Public/BTPayPalDriver.h @@ -0,0 +1,254 @@ +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif +#import "BTPayPalAccountNonce.h" +#import "BTPayPalRequest.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +@class PPOTRequest; + +extern NSString *const BTPayPalDriverErrorDomain; + +typedef NS_ENUM(NSInteger, BTPayPalDriverErrorType) { + BTPayPalDriverErrorTypeUnknown = 0, + + /// PayPal is disabled in configuration + BTPayPalDriverErrorTypeDisabled, + + /// App switch is not configured appropriately. You must specify a + /// valid returnURLScheme via BTAppSwitch before attempting an app switch + BTPayPalDriverErrorTypeIntegrationReturnURLScheme, + + /// UIApplication failed to switch despite it being available. + /// `[UIApplication openURL:]` returned `NO` when `YES` was expected + BTPayPalDriverErrorTypeAppSwitchFailed, + + /// Invalid configuration, e.g. bad CFBundleDisplayName + BTPayPalDriverErrorTypeInvalidConfiguration, + + /// Invalid request, e.g. missing PayPal request + BTPayPalDriverErrorTypeInvalidRequest, + + /// Braintree SDK is integrated incorrectly + BTPayPalDriverErrorTypeIntegration, +}; + +/** + @brief Protocol to handle custom PayPal Approval via BTPayPalApprovalHandler +*/ +@protocol BTPayPalApprovalDelegate +/** + @brief Use when custom approval has completed with success or error +*/ +- (void)onApprovalComplete:(NSURL *) url; + +/** + @brief Use when custom approval was canceled +*/ +- (void)onApprovalCancel; +@end + +/** + @brief Protocol for custom authentication and authorization of PayPal. +*/ +@protocol BTPayPalApprovalHandler + +/** + @brief Handle approval request for PayPal and carry out custom authentication and authorization. + + @discussion Use the delegate to handle success/error/cancel flows. + On completion or error use BTPayPalApprovalDelegate:onApprovalComplete + On cancel use BTPayPalApprovalDelegate:onApprovalCancel + + @param request PayPal request object. + @param delegate The BTPayPalApprovalDelegate to handle response. +*/ +- (void)handleApproval:(PPOTRequest*)request paypalApprovalDelegate:(id)delegate; +@end + +/** + @brief BTPayPalDriver enables you to obtain permission to charge your customers' PayPal accounts via app switch to the PayPal app and the browser. + + @note To make PayPal available, you must ensure that PayPal is enabled in your Braintree control panel. + See our [online documentation](https://developers.braintreepayments.com/ios+ruby/guides/paypal) for + details. + + @discussion This class supports two basic use-cases: Vault and Checkout. Each of these involves variations on the + user experience as well as variations on the capabilities granted to you by this authorization. + + The *Vault* option uses PayPal's future payments authorization, which allows your merchant account to + charge this customer arbitrary amounts for a long period of time into the future (unless the user + manually revokes this permission in their PayPal control panel.) This authorization flow includes + a screen with legal language that directs the user to agree to the terms of Future Payments. + Unfortunately, it is not currently possible to collect shipping information in the Vault flow. + + The *Checkout* option creates a one-time use PayPal payment on your behalf. As a result, you must + specify the checkout details up-front, so that they can be shown to the user during the PayPal flow. + With this flow, you must specify the estimated transaction amount, and you can collect shipping + details. While this flow omits the Future Payments agreement, the resulting payment method cannot be + stored in the vault. It is only possible to create one Braintree transaction with this form of user + approval. + + Both of these flows are available to all users on any iOS device. If the PayPal app is installed on the + device, the PayPal login flow will take place there via an app switch. Otherwise, PayPal login takes + place in the Safari browser. + + Regardless of the type or target, all of these user experiences take full advantage of One Touch. This + means that users may bypass the username/password entry screen when they are already logged in. + + Upon successful completion, you will receive a `BTPayPalAccountNonce`, which includes user-facing + details and a payment method nonce, which you must pass to your server in order to create a transaction + or save the authorization in the Braintree vault (not possible with Checkout). + + ## User Experience Details + + To keep your UI in sync during app switch authentication, you may set a delegate, which will receive + notifications as the PayPal driver progresses through the various steps necessary for user + authentication. + + ## App Switching Details + + This class will handle switching out of your app to the PayPal app or the browser (including the call to + `-[UIApplication openURL:]`). +*/ +@interface BTPayPalDriver : NSObject + + +/** + @brief Initialize a new PayPal driver instance. + + @param apiClient The API client +*/ +- (instancetype)initWithAPIClient:(BTAPIClient *)apiClient; + + +- (instancetype)init __attribute__((unavailable("Please use initWithAPIClient:"))); + +/** + @brief Authorize a PayPal user for saving their account in the Vault via app switch to the PayPal App or the browser. + + @discussion On success, you will receive an instance of `BTPayPalAccountNonce`; on failure, an error; on user cancellation, + you will receive `nil` for both parameters. + + @note During the app switch authorization, the user may switch back to your app manually. In this case, the caller + will not receive a cancellation via the completionBlock. Rather, it is the caller's responsibility to observe + `UIApplicationDidBecomeActiveNotification` and `UIApplicationWillResignActiveNotification` using `NSNotificationCenter` + if necessary. + + @param completionBlock This completion will be invoked exactly once when authorization is complete or an error occurs. +*/ +- (void)authorizeAccountWithCompletion:(void (^)(BTPayPalAccountNonce * _Nullable tokenizedPayPalAccount, NSError * _Nullable error))completionBlock; + + +/** + @brief Authorize a PayPal user for saving their account in the Vault via app switch to the PayPal App or the browser with additional scopes (e.g. address). + + @discussion On success, you will receive an instance of `BTPayPalAccountNonce`; on failure, an error; on user cancellation, + you will receive `nil` for both parameters. + + @note During the app switch authorization, the user may switch back to your app manually. In this case, the caller + will not receive a cancellation via the completionBlock. Rather, it is the caller's responsibility to observe + `UIApplicationDidBecomeActiveNotification` and `UIApplicationWillResignActiveNotification` using `NSNotificationCenter` + if necessary. + + @param additionalScopes An `NSSet` of requested scope-values as `NSString`s. Available scope-values are listed at + https://developer.paypal.com/webapps/developer/docs/integration/direct/identity/attributes/ + @param completionBlock This completion will be invoked exactly once when authorization is complete or an error occurs. +*/ +- (void)authorizeAccountWithAdditionalScopes:(NSSet *)additionalScopes + completion:(void (^)(BTPayPalAccountNonce * _Nullable tokenizedPayPalAccount, NSError * _Nullable error))completionBlock; + +/** + @brief Check out with PayPal to create a single-use PayPal payment method nonce. + + @discussion You can use this as the final step in your order/checkout flow. If you want, you may create a transaction from your + server when this method completes without any additional user interaction. + + On success, you will receive an instance of `BTPayPalAccountNonce`; on failure, an error; on user cancellation, + you will receive `nil` for both parameters. + + @note This method is mutually exclusive with `authorizeAccountWithCompletion:`. In both cases, you need to create a + Braintree transaction from your server in order to actually move money! + + @param request A PayPal request + @param completionBlock This completion will be invoked exactly once when checkout is complete or an error occurs. + */ +- (void)requestOneTimePayment:(BTPayPalRequest *)request + completion:(void (^)(BTPayPalAccountNonce * _Nullable tokenizedPayPalAccount, NSError * _Nullable error))completionBlock; + + +/** + @brief Check out with PayPal to create a single-use PayPal payment method nonce. + + @discussion You can use this as the final step in your order/checkout flow. If you want, you may create a transaction from your + server when this method completes without any additional user interaction. + + On success, you will receive an instance of `BTPayPalAccountNonce`; on failure, an error; on user cancellation, + you will receive `nil` for both parameters. + + @note This method is mutually exclusive with `authorizeAccountWithCompletion:`. In both cases, you need to create a + Braintree transaction from your server in order to actually move money! + + @param request A PayPal request + @param handler A BTPayPalApprovalHandler for custom authorizatin and approval + @param completionBlock This completion will be invoked exactly once when checkout is complete or an error occurs. + */ +- (void)requestOneTimePayment:(BTPayPalRequest *)request handler:(id)handler + completion:(void (^)(BTPayPalAccountNonce * _Nullable tokenizedPayPalAccount, NSError * _Nullable error))completionBlock; + +/** + @brief Create a PayPal Billing Agreement for repeat purchases. + + @discussion You can use this as the final step in your order/checkout flow. If you want, you may create a transaction from your + server when this method completes without any additional user interaction. + + On success, you will receive an instance of `BTPayPalAccountNonce`; on failure, an error; on user cancellation, + you will receive `nil` for both parameters. + + @note This method is mutually exclusive with `authorizeAccountWithCompletion:`. In both cases, you need to create a + Braintree transaction from your server in order to actually move money! + + @param request A PayPal request + @param completionBlock This completion will be invoked exactly once when checkout is complete or an error occurs. +*/ +- (void)requestBillingAgreement:(BTPayPalRequest *)request + completion:(void (^)(BTPayPalAccountNonce * _Nullable tokenizedPayPalAccount, NSError * _Nullable error))completionBlock; + +/** + @brief Create a PayPal Billing Agreement for repeat purchases. + + @discussion You can use this as the final step in your order/checkout flow. If you want, you may create a transaction from your + server when this method completes without any additional user interaction. + + On success, you will receive an instance of `BTPayPalAccountNonce`; on failure, an error; on user cancellation, + you will receive `nil` for both parameters. + + @note This method is mutually exclusive with `authorizeAccountWithCompletion:`. In both cases, you need to create a + Braintree transaction from your server in order to actually move money! + + @param request A PayPal request + @param handler A BTPayPalApprovalHandler for custom authorization and approval + @param completionBlock This completion will be invoked exactly once when checkout is complete or an error occurs. + */ +- (void)requestBillingAgreement:(BTPayPalRequest *)request handler:(id)handler + completion:(void (^)(BTPayPalAccountNonce * _Nullable tokenizedPayPalAccount, NSError * _Nullable error))completionBlock; + +#pragma mark - Delegate + +/** + @brief An optional delegate for receiving notifications about the lifecycle of a PayPal app switch for updating your UI +*/ +@property (nonatomic, weak, nullable) id appSwitchDelegate; + +/** + @brief A required delegate to control the presentation and dismissal of view controllers +*/ +@property (nonatomic, weak, nullable) id viewControllerPresentingDelegate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreePayPal/Public/BTPayPalRequest.h b/Pods/Braintree/BraintreePayPal/Public/BTPayPalRequest.h new file mode 100644 index 0000000..86921e7 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/Public/BTPayPalRequest.h @@ -0,0 +1,154 @@ +#import +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif + +NS_ASSUME_NONNULL_BEGIN + +/** + @brief Payment intent. + + @discussion Must be set to sale for immediate payment, authorize to authorize a payment for capture later, or order to create an order. Defaults to authorize. Only works in the Single Payment flow. + + @see https://developer.paypal.com/docs/integration/direct/payments/capture-payment/ Capture payments later + @see https://developer.paypal.com/docs/integration/direct/payments/create-process-order/ Create and process orders +*/ +typedef NS_ENUM(NSInteger, BTPayPalRequestIntent) { + BTPayPalRequestIntentAuthorize = 1, + BTPayPalRequestIntentSale, + BTPayPalRequestIntentOrder, +}; + +/** + @brief Use this option to specify the PayPal page to display when a user lands on the PayPal site to complete the payment. +*/ +typedef NS_ENUM(NSInteger, BTPayPalRequestLandingPageType) { + BTPayPalRequestLandingPageTypeDefault = 1, + BTPayPalRequestLandingPageTypeLogin, + BTPayPalRequestLandingPageTypeBilling, +}; + +/** + @brief The call-to-action in the PayPal one-time payment checkout flow. + + @discussion By default the final button will show the localized word for "Continue" and implies that the final amount billed is not yet known. + Setting the BTPayPalRequest's userAction to `BTPayPalRequestUserActionCommit` changes the button text to "Pay Now", conveying to + the user that billing will take place immediately. +*/ +typedef NS_ENUM(NSInteger, BTPayPalRequestUserAction) { + BTPayPalRequestUserActionDefault = 1, + BTPayPalRequestUserActionCommit, +}; + +/** + @brief A PayPal request specifies options that control the PayPal flow. + + @discussion For a one-time payment, the request must specify a transaction amount. + + @see BTPayPalDriver +*/ +@interface BTPayPalRequest : NSObject + +/** + @brief Initialize a PayPal request with an amount for a one-time payment. + + @param amount Used for a one-time payment. Amount must be greater than or equal to zero, may optionally contain exactly 2 decimal places separated by '.', optional thousands separator ',', and is limited to 7 digits before the decimal point. + @return A PayPal request. +*/ +- (instancetype)initWithAmount:(NSString *)amount; + +/** + @brief Used for a one-time payment. + + @discussion Amount must be greater than or equal to zero, may optionally contain exactly 2 decimal places separated by '.', optional thousands separator ',', and is limited to 7 digits before the decimal point. +*/ +@property (nonatomic, readonly, strong) NSString *amount; + +/** + @brief Defaults to false. When set to true, the shipping address selector will be displayed. +*/ +@property (nonatomic, getter=isShippingAddressRequired) BOOL shippingAddressRequired; + +/** + @brief Optional: A valid ISO currency code to use for the transaction. Defaults to merchant currency code if not set. + @note This is only used for one-time payments. +*/ +@property (nonatomic, nullable, copy) NSString *currencyCode; + +/** + @brief Optional: A locale code to use for the transaction. + + @discussion Supported locales are: + + `da_DK`, + `de_DE`, + `en_AU`, + `en_GB`, + `en_US`, + `es_ES`, + `es_XC`, + `fr_CA`, + `fr_FR`, + `fr_XC`, + `id_ID`, + `it_IT`, + `ja_JP`, + `ko_KR`, + `nl_NL`, + `no_NO`, + `pl_PL`, + `pt_BR`, + `pt_PT`, + `ru_RU`, + `sv_SE`, + `th_TH`, + `tr_TR`, + `zh_CN`, + `zh_HK`, + `zh_TW`, + `zh_XC`. +*/ +@property (nonatomic, nullable, copy) NSString *localeCode; + +/** + @brief Optional: A valid shipping address to be displayed in the transaction flow. An error will occur if this address is not valid. +*/ +@property (nonatomic, nullable, strong) BTPostalAddress *shippingAddressOverride; + +/** + @brief Optional: Display a custom description to the user for a billing agreement. +*/ +@property (nonatomic, nullable, copy) NSString *billingAgreementDescription; + +/** + @brief Optional: Payment intent. Only applies when using checkout flow. Defaults to `BTPayPalRequestIntentAuthorize`. +*/ +@property (nonatomic) BTPayPalRequestIntent intent; + +/** + @brief Optional: Changes the call-to-action in the PayPal flow. This option works for both checkout and vault flows. Defaults to `BTPayPalRequestUserActionDefault`. +*/ +@property (nonatomic) BTPayPalRequestUserAction userAction; + +/** + @brief Optional: Landing page type. Defaults to `BTPayPalRequestLandingPageTypeDefault`. + + @discussion Setting the BTPayPalRequest's landingPageType changes the PayPal page to display when a user lands on the PayPal site to complete the payment. BTPayPalRequestLandingPageTypeLogin specifies a PayPal account login page is used. BTPayPalRequestLandingPageTypeBilling specifies a non-PayPal account landing page is used. + */ +@property (nonatomic) BTPayPalRequestLandingPageType landingPageType; + +/** + @brief Optional: The merchant name displayed inside of the PayPal flow; defaults to the company name on your Braintree account +*/ +@property (nonatomic, nullable, copy) NSString *displayName; + +/** + @brief Optional: Offers PayPal Credit if the customer qualifies. Defaults to false. Only available with PayPal Checkout and PayPal Billing Agreement. + */ +@property (nonatomic) BOOL offerCredit; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreePayPal/Public/BraintreePayPal.h b/Pods/Braintree/BraintreePayPal/Public/BraintreePayPal.h new file mode 100644 index 0000000..bbdc644 --- /dev/null +++ b/Pods/Braintree/BraintreePayPal/Public/BraintreePayPal.h @@ -0,0 +1,18 @@ +#import + +//! Project version number for BraintreePayPal. +FOUNDATION_EXPORT double BraintreePayPalVersionNumber; + +//! Project version string for BraintreePayPal. +FOUNDATION_EXPORT const unsigned char BraintreePayPalVersionString[]; + +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif +#import "BTConfiguration+PayPal.h" +#import "BTPayPalRequest.h" +#import "BTPayPalDriver.h" +#import "BTPayPalAccountNonce.h" +#import "BTPayPalCreditFinancing.h" diff --git a/Pods/Braintree/BraintreeUI/Drop-In/BTDropInContentView.h b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInContentView.h new file mode 100644 index 0000000..f0737aa --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInContentView.h @@ -0,0 +1,51 @@ +#import "BTUIThemedView.h" + +#import "BraintreeUI.h" + +#import "BTPaymentButton.h" + +typedef NS_ENUM(NSUInteger, BTDropInContentViewStateType) { + BTDropInContentViewStateForm = 0, + BTDropInContentViewStatePaymentMethodsOnFile, + BTDropInContentViewStateActivity +}; + +/** + @brief A thin view layer that manages Drop In subviews and their layout. +*/ +@interface BTDropInContentView : BTUIThemedView + +@property (nonatomic, strong) BTUISummaryView *summaryView; +@property (nonatomic, strong) BTUICTAControl *ctaControl; +@property (nonatomic, strong) BTPaymentButton *paymentButton; +@property (nonatomic, strong) UILabel *cardFormSectionHeader; +@property (nonatomic, strong) BTUICardFormView *cardForm; + +@property (nonatomic, strong) BTUIPaymentMethodView *selectedPaymentMethodView; +@property (nonatomic, strong) UIButton *changeSelectedPaymentMethodButton; + +/** + @brief Whether to hide the call to action +*/ +@property (nonatomic, assign) BOOL hideCTA; + +/** + @brief Whether to hide the summary banner view +*/ +@property (nonatomic, assign) BOOL hideSummary; + +/** + @brief The current state +*/ +@property (nonatomic, assign) BTDropInContentViewStateType state; + +/** + @brief Whether the paymentButton control is hidden +*/ +@property (nonatomic, assign) BOOL hidePaymentButton; + +- (void)setState:(BTDropInContentViewStateType)newState animate:(BOOL)animate; + +- (void)setState:(BTDropInContentViewStateType)newState animate:(BOOL)animate completion:(void(^)(void))completionBlock; + +@end diff --git a/Pods/Braintree/BraintreeUI/Drop-In/BTDropInContentView.m b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInContentView.m new file mode 100644 index 0000000..b156d86 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInContentView.m @@ -0,0 +1,325 @@ +#import "BTDropInContentView.h" +#import "BTDropInLocalizedString.h" +#import "BTTokenizationService.h" + +@interface BTDropInContentView () +@property (nonatomic, strong) NSArray *verticalLayoutConstraints; +/// An array of `NSLayoutConstraint` horizontal constraints on the payment button. +/// These constraints may need to be updated when +@property (nonatomic, strong) NSArray *paymentButtonConstraints; +@property (nonatomic, strong) UIActivityIndicatorView *activityView; +@property (nonatomic, strong) NSLayoutConstraint *heightConstraint; +@end + +@implementation BTDropInContentView + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + // Initialize Subviews + + self.activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + self.activityView.translatesAutoresizingMaskIntoConstraints = NO; + self.activityView.hidden = YES; + [self addSubview:self.activityView]; + [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]]; + + self.summaryView = [[BTUISummaryView alloc] init]; + + UIView *summaryBorderBottom = [[UIView alloc] init]; + summaryBorderBottom.backgroundColor = self.theme.borderColor; + summaryBorderBottom.translatesAutoresizingMaskIntoConstraints = NO; + [self.summaryView addSubview:summaryBorderBottom]; + [self.summaryView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[border]|" + options:0 + metrics:nil + views:@{@"border": summaryBorderBottom}]]; + [self.summaryView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[border(==borderWidth)]|" + options:0 + metrics:@{@"borderWidth": @(self.theme.borderWidth)} + views:@{@"border": summaryBorderBottom}]]; + + self.cardFormSectionHeader = [[UILabel alloc] init]; + + self.cardForm = [[BTUICardFormView alloc] init]; + [self.cardForm setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical]; + + self.selectedPaymentMethodView = [[BTUIPaymentMethodView alloc] init]; + + self.changeSelectedPaymentMethodButton = [UIButton buttonWithType:UIButtonTypeSystem]; + [self.changeSelectedPaymentMethodButton setTitle:BTDropInLocalizedString(DROP_IN_CHANGE_PAYMENT_METHOD_BUTTON_TEXT) + forState:UIControlStateNormal]; + + self.ctaControl = [[BTUICTAControl alloc] init]; + + // Add Constraints & Subviews + + // Full-Width Views + for (UIView *view in @[self.selectedPaymentMethodView, self.summaryView, self.ctaControl, self.cardForm]) { + [self addSubview:view withHorizontalMargins:NO]; + } + + // Not quite full-width views + for (UIView *view in @[self.cardFormSectionHeader, self.changeSelectedPaymentMethodButton]) { + [self addSubview:view withHorizontalMargins:YES]; + } + + self.paymentButton = [[BTPaymentButton alloc] init]; + // The payment button horizontal constraints may be updated to add a margin to the button *after* + // fetching the configuration, so keep a reference to them to update them in updateConstraints + self.paymentButtonConstraints = [self addSubview:self.paymentButton withHorizontalMargins:NO]; + + self.state = BTDropInContentViewStateForm; + + // Keyboard dismissal when tapping outside text field + UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped)]; + tapGesture.delegate = self; + [self addGestureRecognizer:tapGesture]; + + } + return self; +} + +/// Adds a subview, and returns an array of constraints applied to the subview +- (NSArray *)addSubview:(UIView *)view withHorizontalMargins:(BOOL)useHorizontalMargins { + [self addSubview:view]; + view.translatesAutoresizingMaskIntoConstraints = NO; + NSDictionary *metrics = useHorizontalMargins ? @{@"horizontalMargin": @(self.theme.horizontalMargin)} : @{@"horizontalMargin": @(0)}; + NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(horizontalMargin)-[view]-(horizontalMargin)-|" + options:0 + metrics:metrics + views:@{@"view": view}]; + [self addConstraints:constraints]; + return constraints; +} + +- (void)updateConstraints { + + if (self.verticalLayoutConstraints != nil) { + [self removeConstraints:self.verticalLayoutConstraints]; + } + + CGFloat paymentButtonMargin; + if ([self.paymentButton.enabledPaymentOptions isEqualToOrderedSet:[NSOrderedSet orderedSetWithArray:@[@"PayPal"]]]) { + paymentButtonMargin = self.theme.horizontalMargin; + } else { + paymentButtonMargin = 0; + } + for (NSLayoutConstraint *constraint in self.paymentButtonConstraints) { + constraint.constant = paymentButtonMargin; + } + [self.paymentButton setNeedsLayout]; + [self.paymentButton layoutIfNeeded]; + + NSDictionary *viewBindings = @{ + @"activityView": self.activityView, + @"summaryView": self.summaryView, + @"paymentButton": self.paymentButton, + @"cardFormSectionHeader": self.cardFormSectionHeader, + @"cardForm": self.cardForm, + @"ctaControl": self.ctaControl, + @"selectedPaymentMethodView": self.selectedPaymentMethodView, + @"changeSelectedPaymentMethodButton": self.changeSelectedPaymentMethodButton + }; + + NSMutableArray *newConstraints = [NSMutableArray array]; + for (NSString *visualFormat in [self evaluateVisualFormat]) { + [newConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:visualFormat + options:0 + metrics:nil + views:viewBindings]]; + } + + if(self.heightConstraint != nil) { + [self.superview removeConstraint:self.heightConstraint]; + } + + if (self.state != BTDropInContentViewStateForm) { + + self.heightConstraint = [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeHeight + relatedBy:NSLayoutRelationGreaterThanOrEqual + toItem:self.superview + attribute:NSLayoutAttributeHeight + multiplier:1.0f + constant:0]; + [self.superview addConstraint:self.heightConstraint]; + } + [self.superview setNeedsLayout]; + + [self addConstraints:newConstraints]; + self.verticalLayoutConstraints = newConstraints; + + [super updateConstraints]; + +} +- (void)setHideSummary:(BOOL)hideSummary { + _hideSummary = hideSummary; + [self updateContentView]; +} + +- (void)setHideCTA:(BOOL)hideCTA { + _hideCTA = hideCTA; + [self updateContentView]; +} + +- (void)setState:(BTDropInContentViewStateType)state { + _state = state; + [self updateContentView]; +} + +- (void)setState:(BTDropInContentViewStateType)newState animate:(BOOL)animate completion:(void(^)(void))completionBlock { + if (!animate) { + [self setState:newState]; + } else { + BTDropInContentViewStateType oldState = self.state; + CGFloat duration = 0.2f; + if (oldState == BTDropInContentViewStateActivity) { + if (newState == BTDropInContentViewStateForm) { + [UIView animateWithDuration:duration animations:^{ + self.activityView.alpha = 0.0f; + } completion:^(__unused BOOL finished) { + [self setState:newState]; + self.paymentButton.alpha = 0.0f; + self.cardForm.alpha = 0.0f; + self.cardFormSectionHeader.alpha = 0.0f; + self.ctaControl.alpha = 0.0f; + [self setNeedsUpdateConstraints]; + [self layoutIfNeeded]; + [UIView animateWithDuration:duration animations:^{ + self.paymentButton.alpha = 1.0f; + self.cardForm.alpha = 1.0f; + self.cardFormSectionHeader.alpha = 1.0f; + self.ctaControl.alpha = 1.0f; + if (completionBlock) { + completionBlock(); + } + }]; + }]; + return; + } + + if (newState == BTDropInContentViewStatePaymentMethodsOnFile) { + self.activityView.alpha = 1.0f; + [UIView animateWithDuration:duration animations:^{ + self.activityView.alpha = 0.0f; + } completion:^(__unused BOOL finished) { + [self setState:newState]; + self.selectedPaymentMethodView.alpha = 0.0f; + self.changeSelectedPaymentMethodButton.alpha = 0.0f; + self.ctaControl.alpha = 0.0f; + [self setNeedsUpdateConstraints]; + [self layoutIfNeeded]; + [UIView animateWithDuration:duration animations:^{ + self.selectedPaymentMethodView.alpha = 1.0f; + self.changeSelectedPaymentMethodButton.alpha = 1.0f; + self.ctaControl.alpha = 1.0f; + if (completionBlock) { + completionBlock(); + } + }]; + }]; + return; + } + } + [self setState:newState]; + } +} + +- (void)setState:(BTDropInContentViewStateType)newState animate:(BOOL)animate { + [self setState:newState animate:animate completion:nil]; +} + +- (void)setHidePaymentButton:(BOOL)hidePaymentButton { + _hidePaymentButton = hidePaymentButton; + self.paymentButton.hidden = hidePaymentButton; + [self updateContentView]; +} + +- (void)updateContentView { + + // Reset all to hidden, just for clarity + self.activityView.hidden = YES; + self.summaryView.hidden = self.hideSummary; + self.paymentButton.hidden = YES; + self.cardFormSectionHeader.hidden = YES; + self.cardForm.hidden = YES; + self.selectedPaymentMethodView.hidden = YES; + self.changeSelectedPaymentMethodButton.hidden = YES; + self.ctaControl.hidden = YES; + + switch (self.state) { + case BTDropInContentViewStateForm: + self.activityView.hidden = YES; + [self.activityView stopAnimating]; + self.ctaControl.hidden = self.hideCTA; + self.paymentButton.hidden = self.hidePaymentButton; + if ([[BTTokenizationService sharedService] isTypeAvailable:@"Card"]) { + self.cardFormSectionHeader.hidden = NO; + self.cardForm.hidden = NO; + } + break; + case BTDropInContentViewStatePaymentMethodsOnFile: + self.activityView.hidden = YES; + [self.activityView stopAnimating]; + self.ctaControl.hidden = self.hideCTA; + self.selectedPaymentMethodView.hidden = NO; + self.changeSelectedPaymentMethodButton.hidden = NO; + break; + case BTDropInContentViewStateActivity: + self.activityView.hidden = NO; + self.activityView.alpha = 1.0f; + [self.activityView startAnimating]; + break; + default: + break; + } + [self setNeedsUpdateConstraints]; +} + + +#pragma mark Tap Gesture Delegate + +- (BOOL)gestureRecognizer:(__unused UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { + // Disallow recognition of tap gestures on UIControls (like, say, buttons) + if ([touch.view isKindOfClass:[UIControl class]] || [touch.view isDescendantOfView:self.paymentButton]) { + return NO; + } + return YES; +} + + +- (void)tapped { + [self.cardForm endEditing:YES]; +} + +- (NSArray*) evaluateVisualFormat{ + NSString *summaryViewVisualFormat = self.summaryView.hidden ? @"" : @"[summaryView(>=60)]"; + NSString *ctaControlVisualFormat = self.ctaControl.hidden ? @"" : @"[ctaControl(==50)]"; + + if (self.state == BTDropInContentViewStateActivity) { + return @[[NSString stringWithFormat:@"V:|%@-(40)-[activityView]-(>=40)-%@|", summaryViewVisualFormat, ctaControlVisualFormat]]; + + } else if (self.state != BTDropInContentViewStatePaymentMethodsOnFile) { + if (!self.ctaControl.hidden) { + ctaControlVisualFormat = [NSString stringWithFormat:@"-(15)-%@-(>=0)-", ctaControlVisualFormat]; + } + if (self.hidePaymentButton){ + return @[[NSString stringWithFormat:@"V:|%@-(35)-[cardFormSectionHeader]-(7)-[cardForm]%@|", summaryViewVisualFormat, ctaControlVisualFormat]]; + } else { + summaryViewVisualFormat = [NSString stringWithFormat:@"%@-(35)-", summaryViewVisualFormat]; + return @[[NSString stringWithFormat:@"V:|%@[paymentButton(==44)]-(18)-[cardFormSectionHeader]-(7)-[cardForm]%@|", summaryViewVisualFormat, ctaControlVisualFormat]]; + } + + } else { + NSString *primaryLayout = [NSString stringWithFormat:@"V:|%@-(15)-[selectedPaymentMethodView(==45)]-(15)-[changeSelectedPaymentMethodButton]-(>=15)-%@|", summaryViewVisualFormat, ctaControlVisualFormat]; + NSMutableArray *visualLayouts = [NSMutableArray arrayWithObject:primaryLayout]; + if (!self.ctaControl.hidden) { + [visualLayouts addObject:@"V:[ctaControl]|"]; + } + return visualLayouts; + } +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Drop-In/BTDropInErrorAlert.h b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInErrorAlert.h new file mode 100644 index 0000000..743f594 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInErrorAlert.h @@ -0,0 +1,21 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface BTDropInErrorAlert : NSObject + +@property (nonatomic, copy) NSString *title; +@property (nonatomic, copy, nullable) NSString *message; +@property (nonatomic, copy, nullable) void (^retryBlock)(void); +@property (nonatomic, copy, nullable) void (^cancelBlock)(void); +@property (nonatomic, weak, nullable) UIViewController *presentingViewController; + +- (instancetype)initWithPresentingViewController:(UIViewController *)viewController NS_DESIGNATED_INITIALIZER; + +- (instancetype)init __attribute__((unavailable("Please use initWithPresentingViewController:"))); + +- (void)showWithDismissalHandler:(void (^)(void))dismissalHandler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeUI/Drop-In/BTDropInErrorAlert.m b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInErrorAlert.m new file mode 100644 index 0000000..dd933fd --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInErrorAlert.m @@ -0,0 +1,93 @@ +#import "BTDropInErrorAlert.h" +#import "BTDropInLocalizedString.h" + +@interface BTDropInErrorAlert () + +@property (nonatomic, copy, nullable) void (^dismissalHandler)(void); + +@end + +@implementation BTDropInErrorAlert + +- (instancetype)initWithPresentingViewController:(UIViewController *)viewController +{ + if (self = [super init]) { + _presentingViewController = viewController; + } + return self; +} + + +- (void)showWithDismissalHandler:(void (^)(void))dismissalHandler { + NSString *localizedOK = BTDropInLocalizedString(ERROR_ALERT_OK_BUTTON_TEXT); + NSString *localizedCancel = BTDropInLocalizedString(ERROR_ALERT_CANCEL_BUTTON_TEXT); + self.dismissalHandler = dismissalHandler; + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 8.0, *)) { +#else + if ([UIAlertController class]) { +#endif + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:self.title message:self.message preferredStyle:UIAlertControllerStyleAlert]; + + [alertController addAction:[UIAlertAction actionWithTitle:self.retryBlock ? localizedCancel : localizedOK + style:UIAlertActionStyleCancel + handler:^(__unused UIAlertAction *action) { + if (self.cancelBlock) { + self.cancelBlock(); + } + if (self.dismissalHandler) { + self.dismissalHandler(); + } + }]]; + if (self.retryBlock) { + [alertController addAction:[UIAlertAction actionWithTitle:BTDropInLocalizedString(ERROR_ALERT_TRY_AGAIN_BUTTON_TEXT) + style:UIAlertActionStyleDefault + handler:^(__unused UIAlertAction *action) { + if (self.retryBlock) { + self.retryBlock(); + } + if (self.dismissalHandler) { + self.dismissalHandler(); + } + }]]; + } + + [self.presentingViewController presentViewController:alertController animated:YES completion:nil]; + } else { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:self.title + message:self.message + delegate:self + cancelButtonTitle:self.retryBlock ? localizedCancel : localizedOK + otherButtonTitles:nil]; + + if (self.retryBlock) { + NSString *localizedTryAgain = BTDropInLocalizedString(ERROR_ALERT_TRY_AGAIN_BUTTON_TEXT); + [alertView addButtonWithTitle:localizedTryAgain]; + } + + [alertView show]; +#pragma clang diagnostic pop + } +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +- (void)alertView:(__unused UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { + if (buttonIndex == 0 && self.cancelBlock) { + self.cancelBlock(); + } else if (buttonIndex == 1 && self.retryBlock) { + self.retryBlock(); + } + self.dismissalHandler(); +} +#pragma clang diagnostic pop + +- (NSString *)title { + return _title ?: BTDropInLocalizedString(ERROR_ALERT_CONNECTION_ERROR); +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Drop-In/BTDropInErrorState.h b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInErrorState.h new file mode 100644 index 0000000..a5b388a --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInErrorState.h @@ -0,0 +1,29 @@ +#import + +/** + @discussion Interprets NSError objects of domain BTHTTPErrorDomain, code + BTHTTPErrorCodeClientError (status code 422) for Drop-In UI Components. +*/ +@interface BTDropInErrorState : NSObject + +/** + @discussion Initializes a new error state object returned by + saveCardWithNumber:expirationMonth:expirationYear:cvv:postalCode:validate:success:failure:. + + @param error The error to interpret + + @return a new error state instance +*/ +- (instancetype)initWithError:(NSError *)error; + +/** + @brief Top-level description of error +*/ +@property (nonatomic, copy, readonly) NSString *errorTitle; + +/** + @brief Set of invalid fields to highlight, each represented as a boxed BTUICardFormField +*/ +@property (nonatomic, strong, readonly) NSSet *highlightedFields; + +@end diff --git a/Pods/Braintree/BraintreeUI/Drop-In/BTDropInErrorState.m b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInErrorState.m new file mode 100644 index 0000000..e9e3c4e --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInErrorState.m @@ -0,0 +1,64 @@ +#import "BTDropInErrorState.h" +#import "BTUICardFormView.h" +#import "BTErrors.h" + +@interface BTDropInErrorState () +@property (nonatomic, strong) NSError *error; + +@end + +@implementation BTDropInErrorState + +- (instancetype)initWithError:(__unused NSError *)error{ + self = [super init]; + if (self != nil) { + self.error = error; + } + return self; +} + +- (NSString *)errorTitle { + return self.validationErrors[@"error"][@"message"]; +} + +- (NSDictionary *)validationErrors { + return self.error.userInfo[BTCustomerInputBraintreeValidationErrorsKey]; +} + +- (NSSet *)highlightedFields{ + NSMutableSet *fieldsToHighlight = [[NSMutableSet alloc] init]; + NSArray *fieldErrors = self.validationErrors[@"fieldErrors"]; + + NSArray *creditCardFieldErrors = @[]; + for (NSDictionary *fieldError in fieldErrors) { + if ([fieldError[@"field"] isEqualToString:@"creditCard"]) { + creditCardFieldErrors = fieldError[@"fieldErrors"]; + break; + } + } + + for (NSDictionary *creditCardFieldError in creditCardFieldErrors) { + NSString *field = creditCardFieldError[@"field"]; + if([field isEqualToString:@"cvv"]){ + [fieldsToHighlight addObject:@(BTUICardFormFieldCvv)]; + } else if ([field isEqualToString:@"billingAddress"]) { + for (NSDictionary *billingAddressFieldError in creditCardFieldError[@"fieldErrors"]) { + NSString *billingAddressField = billingAddressFieldError[@"field"]; + if ([billingAddressField isEqualToString:@"postalCode"]) { + [fieldsToHighlight addObject:@(BTUICardFormFieldPostalCode)]; + } + } + } else if ([field isEqualToString:@"number"]) { + [fieldsToHighlight addObject:@(BTUICardFormFieldNumber)]; + } else if ([field isEqualToString:@"expirationDate"] || [field isEqualToString:@"expirationMonth"] || [field isEqualToString:@"expirationYear"]) { + [fieldsToHighlight addObject:@(BTUICardFormFieldExpiration)]; + } + } + return fieldsToHighlight; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"", self, self.errorTitle, self.highlightedFields]; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Drop-In/BTDropInSelectPaymentMethodViewController.h b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInSelectPaymentMethodViewController.h new file mode 100644 index 0000000..b2ebe50 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInSelectPaymentMethodViewController.h @@ -0,0 +1,37 @@ +#import + +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif + +#import "BTUI.h" + +@protocol BTDropInSelectPaymentMethodViewControllerDelegate; + +/** + @class BTDropInSelectPaymentMethodViewController + @brief Drop In's payment method selection flow. +*/ +@interface BTDropInSelectPaymentMethodViewController : UITableViewController + +@property (nonatomic, strong) BTAPIClient *client; +@property (nonatomic, weak) id delegate; + +@property (nonatomic, strong) NSArray *paymentMethodNonces; + +@property (nonatomic, assign) NSInteger selectedPaymentMethodIndex; + +@property (nonatomic, strong) BTUI *theme; + +@end + +@protocol BTDropInSelectPaymentMethodViewControllerDelegate + +- (void)selectPaymentMethodViewController:(BTDropInSelectPaymentMethodViewController *)viewController + didSelectPaymentMethodAtIndex:(NSUInteger)index; + +- (void)selectPaymentMethodViewControllerDidRequestNew:(BTDropInSelectPaymentMethodViewController *)viewController; + +@end diff --git a/Pods/Braintree/BraintreeUI/Drop-In/BTDropInSelectPaymentMethodViewController.m b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInSelectPaymentMethodViewController.m new file mode 100644 index 0000000..22d365d --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInSelectPaymentMethodViewController.m @@ -0,0 +1,78 @@ +#import "BTDropInSelectPaymentMethodViewController.h" +#import "BTDropInUtil.h" +#import "BTUIViewUtil.h" +#import "BTUI.h" +#import "BTDropInViewController.h" +#import "BTDropInLocalizedString.h" +#import "BTUILocalizedString.h" + +@interface BTDropInSelectPaymentMethodViewController () + +@end + +@implementation BTDropInSelectPaymentMethodViewController + +- (instancetype)init { + return [self initWithStyle:UITableViewStyleGrouped]; +} + +- (id)initWithStyle:(UITableViewStyle)style +{ + self = [super initWithStyle:style]; + if (self) { + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(didTapAdd)]; + self.tableView.accessibilityIdentifier = @"Payment Methods Table"; + } + return self; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + [self.tableView reloadData]; +} + +#pragma mark - + +- (void)didTapAdd { + [self.delegate selectPaymentMethodViewControllerDidRequestNew:self]; +} + +#pragma mark - Table view data source + +- (NSInteger)tableView:(__unused UITableView *)tableView numberOfRowsInSection:(__unused NSInteger)section { + return self.paymentMethodNonces.count; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *paymentMethodCellIdentifier = @"paymentMethodCell"; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:paymentMethodCellIdentifier]; + if (cell == nil) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:paymentMethodCellIdentifier]; + } + + BTPaymentMethodNonce *paymentInfo = self.paymentMethodNonces[indexPath.row]; + + BTUIPaymentOptionType paymentOptionType = [BTUI paymentOptionTypeForPaymentInfoType:paymentInfo.type]; + NSString *typeString = [BTUIViewUtil nameForPaymentMethodType:paymentOptionType]; + NSAttributedString *paymentOptionTypeString = [[NSAttributedString alloc] initWithString:typeString attributes:@{ NSFontAttributeName : self.theme.controlTitleFont }]; + cell.textLabel.attributedText = paymentOptionTypeString; + cell.detailTextLabel.text = paymentInfo.localizedDescription; + + BTUIVectorArtView *iconArt = [[BTUI braintreeTheme] vectorArtViewForPaymentInfoType:paymentInfo.type]; + UIImage *icon = [iconArt imageOfSize:CGSizeMake(42, 23)]; + cell.imageView.contentMode = UIViewContentModeCenter; + cell.imageView.image = icon; + cell.accessoryType = (indexPath.row == self.selectedPaymentMethodIndex) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; + + return cell; +} + +- (void)tableView:(__unused UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + self.selectedPaymentMethodIndex = indexPath.row; + [self.tableView reloadData]; + [self.delegate selectPaymentMethodViewController:self didSelectPaymentMethodAtIndex:indexPath.row]; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Drop-In/BTDropInUtil.h b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInUtil.h new file mode 100644 index 0000000..7b35d86 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInUtil.h @@ -0,0 +1,15 @@ +#import "BTCardNonce.h" +#import "BTUIPaymentOptionType.h" + +@interface BTDropInUtil : NSObject + ++ (BTUIPaymentOptionType)uiForCardNetwork:(BTCardNetwork)cardNetwork; + +/** + @brief Get the top view controller + + @return The top most UIViewController + */ ++ (UIViewController *)topViewController; + +@end diff --git a/Pods/Braintree/BraintreeUI/Drop-In/BTDropInUtil.m b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInUtil.m new file mode 100644 index 0000000..71aaac0 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInUtil.m @@ -0,0 +1,34 @@ +#import "BTDropInUtil.h" + +@implementation BTDropInUtil + ++ (BTUIPaymentOptionType)uiForCardNetwork:(BTCardNetwork)cardNetwork { + switch (cardNetwork) { + case BTCardNetworkUnknown: return BTUIPaymentOptionTypeUnknown; + case BTCardNetworkAMEX: return BTUIPaymentOptionTypeAMEX; + case BTCardNetworkDinersClub: return BTUIPaymentOptionTypeDinersClub; + case BTCardNetworkDiscover: return BTUIPaymentOptionTypeDiscover; + case BTCardNetworkMasterCard: return BTUIPaymentOptionTypeMasterCard; + case BTCardNetworkVisa: return BTUIPaymentOptionTypeVisa; + case BTCardNetworkJCB: return BTUIPaymentOptionTypeJCB; + case BTCardNetworkLaser: return BTUIPaymentOptionTypeLaser; + case BTCardNetworkMaestro: return BTUIPaymentOptionTypeMaestro; + case BTCardNetworkUnionPay: return BTUIPaymentOptionTypeUnionPay; + case BTCardNetworkSolo: return BTUIPaymentOptionTypeSolo; + case BTCardNetworkSwitch: return BTUIPaymentOptionTypeSwitch; + case BTCardNetworkUKMaestro: return BTUIPaymentOptionTypeUKMaestro; + default: return BTUIPaymentOptionTypeUnknown; + } +} + ++ (UIViewController *)topViewController { + UIApplication *sharedApplication = [UIApplication performSelector:@selector(sharedApplication)]; + UIViewController *topViewController = sharedApplication.keyWindow.rootViewController; + + while (topViewController.presentedViewController) { + topViewController = topViewController.presentedViewController; + } + return topViewController; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Drop-In/BTDropInViewController.m b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInViewController.m new file mode 100644 index 0000000..2526b8b --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInViewController.m @@ -0,0 +1,721 @@ +#import "BTAPIClient_Internal.h" +#import "BTCard.h" +#import "BTCardClient.h" +#import "BTCardRequest.h" +#import "BTDropInViewController_Internal.h" +#import "BTLogger_Internal.h" +#import "BTDropInErrorAlert.h" +#import "BTDropInErrorState.h" +#import "BTDropInLocalizedString.h" +#import "BTDropInSelectPaymentMethodViewController.h" +#import "BTDropInUtil.h" +#import "BTPaymentMethodNonceParser.h" +#import "BTTokenizationService.h" +#import "BTUICardFormView.h" +#import "BTUIScrollView.h" + +@interface BTDropInViewController () + +@property (nonatomic, strong) BTUIScrollView *scrollView; +@property (nonatomic, assign) NSInteger selectedPaymentMethodNonceIndex; +@property (nonatomic, strong) UIBarButtonItem *submitBarButtonItem; + +/// Whether currently visible. +@property (nonatomic, assign) BOOL visible; +@property (nonatomic, assign) NSTimeInterval visibleStartTime; + +/// If YES, fetch and display payment methods on file, summary view, CTA control. +/// If NO, do not fetch payment methods, and just show UI to add a new method. +/// +/// Defaults to `YES`. +@property (nonatomic, assign) BOOL fullForm; + +@property (nonatomic, assign) BOOL cardEntryDidBegin; +@property (nonatomic, assign) BOOL cardEntryDidFocus; + +@property (nonatomic, assign) BOOL originalCoinbaseStoreInVault; + +/// Used to strongly retain any BTDropInErrorAlert instances in case UIViewAlert is used +@property (nonatomic, strong, nonnull) NSMutableSet *errorAlerts; + +@end + +@implementation BTDropInViewController + +- (instancetype)initWithAPIClient:(BTAPIClient *)apiClient { + if (self = [super init]) { + self.theme = [BTUI braintreeTheme]; + self.dropInContentView = [[BTDropInContentView alloc] init]; + self.dropInContentView.paymentButton.viewControllerPresentingDelegate = self; + + self.apiClient = [apiClient copyWithSource:apiClient.metadata.source integration:BTClientMetadataIntegrationDropIn]; + self.dropInContentView.paymentButton.apiClient = self.apiClient; + + __weak typeof(self) weakSelf = self; + self.dropInContentView.paymentButton.completion = ^(BTPaymentMethodNonce *paymentMethodNonce, NSError *error) { + [weakSelf paymentButtonDidCompleteTokenization:paymentMethodNonce fromViewController:weakSelf error:error]; + }; + + self.dropInContentView.hidePaymentButton = !self.dropInContentView.paymentButton.hasAvailablePaymentMethod; + + self.selectedPaymentMethodNonceIndex = NSNotFound; + self.dropInContentView.state = BTDropInContentViewStateActivity; + self.fullForm = YES; + + self.errorAlerts = [NSMutableSet set]; + } + return self; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + self.edgesForExtendedLayout = UIRectEdgeNone; + + self.view.backgroundColor = self.theme.viewBackgroundColor; + + // Configure Subviews + self.scrollView = [[BTUIScrollView alloc] init]; + self.scrollView.scrollRectToVisibleDelegate = self; + self.scrollView.bounces = YES; + self.scrollView.scrollsToTop = YES; + self.scrollView.alwaysBounceVertical = YES; + self.scrollView.translatesAutoresizingMaskIntoConstraints = NO; + self.scrollView.delaysContentTouches = NO; + self.scrollView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(keyboardWillHide:) + name:UIKeyboardWillHideNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(keyboardWillShow:) + name:UIKeyboardWillShowNotification + object:nil]; + + self.dropInContentView.translatesAutoresizingMaskIntoConstraints = NO; + + self.dropInContentView.cardForm.delegate = self; + self.dropInContentView.cardForm.alphaNumericPostalCode = YES; + + [self.apiClient fetchOrReturnRemoteConfiguration:^(BTConfiguration *configuration, NSError *error) { + + if (!self.delegate) { + // Log integration error, as a delegate is required by this point + [[BTLogger sharedLogger] critical:@"ERROR: Drop-in delegate not set"]; + } + + self.dropInContentView.hidePaymentButton = !self.dropInContentView.paymentButton.hasAvailablePaymentMethod; + + if (![self isAddPaymentMethodDropInViewController]) { + [self fetchPaymentMethodsOnCompletion:^{}]; + } + + if (error) { + BTDropInErrorAlert *errorAlert = [[BTDropInErrorAlert alloc] initWithPresentingViewController:self]; + errorAlert.title = error.localizedDescription ?: BTDropInLocalizedString(ERROR_ALERT_CONNECTION_ERROR); + [self.errorAlerts addObject:errorAlert]; + [errorAlert showWithDismissalHandler:^{ + [self.errorAlerts removeObject:errorAlert]; + }]; + } + + NSArray *challenges = [configuration.json[@"challenges"] asStringArray]; + + static NSString *cvvChallenge = @"cvv"; + static NSString *postalCodeChallenge = @"postal_code"; + + BTUICardFormOptionalFields optionalFields; + if ([challenges containsObject:cvvChallenge] && [challenges containsObject:postalCodeChallenge]) { + optionalFields = BTUICardFormOptionalFieldsCvv | BTUICardFormFieldPostalCode; + } else if ([challenges containsObject:cvvChallenge]) { + optionalFields = BTUICardFormOptionalFieldsCvv; + } else if ([challenges containsObject:postalCodeChallenge]) { + optionalFields = BTUICardFormOptionalFieldsPostalCode; + } else { + optionalFields = BTUICardFormOptionalFieldsNone; + } + + self.dropInContentView.cardForm.optionalFields = optionalFields; + + [self informDelegateDidLoad]; + }]; + + [self.dropInContentView.changeSelectedPaymentMethodButton addTarget:self + action:@selector(tappedChangePaymentMethod) + forControlEvents:UIControlEventTouchUpInside]; + + [self.dropInContentView.ctaControl addTarget:self + action:@selector(tappedSubmitForm) + forControlEvents:UIControlEventTouchUpInside]; + + self.dropInContentView.cardFormSectionHeader.textColor = self.theme.sectionHeaderTextColor; + self.dropInContentView.cardFormSectionHeader.font = self.theme.sectionHeaderFont; + self.dropInContentView.cardFormSectionHeader.text = BTDropInLocalizedString(CARD_FORM_SECTION_HEADER); + + + // Call the setters explicitly + [self updateDropInContentViewFromPaymentRequest]; + + [self.dropInContentView setNeedsUpdateConstraints]; + + // Add Subviews + [self.view addSubview:self.scrollView]; + [self.scrollView addSubview:self.dropInContentView]; + + // Add initial constraints + [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" + options:0 + metrics:nil + views:@{@"scrollView": self.scrollView}]]; + [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" + options:0 + metrics:nil + views:@{@"scrollView": self.scrollView}]]; + + [self.scrollView addConstraint:[NSLayoutConstraint constraintWithItem:self.dropInContentView + attribute:NSLayoutAttributeWidth + relatedBy:NSLayoutRelationEqual + toItem:self.scrollView + attribute:NSLayoutAttributeWidth + multiplier:1 + constant:0]]; + + [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[dropInContentView]|" + options:0 + metrics:nil + views:@{@"dropInContentView": self.dropInContentView}]]; + + [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[dropInContentView]|" + options:0 + metrics:nil + views:@{@"dropInContentView": self.dropInContentView}]]; + + if (!self.fullForm) { + self.dropInContentView.state = BTDropInContentViewStateForm; + } + + [self updateValidity]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + self.visible = YES; + self.visibleStartTime = [NSDate timeIntervalSinceReferenceDate]; + + // Ensure dropInContentView is visible. See viewWillDisappear below + self.dropInContentView.alpha = 1.0f; + + if (self.fullForm) { + [self.apiClient sendAnalyticsEvent:@"dropin.ios.appear"]; + } + [self.apiClient sendAnalyticsEvent:@"ios.dropin.appear.succeeded"]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + // Quickly fade out the content view to prevent a jarring effect + // as keyboard dimisses. + [UIView animateWithDuration:self.theme.quickTransitionDuration animations:^{ + self.dropInContentView.alpha = 0.0f; + }]; + if (self.fullForm) { + [self.apiClient sendAnalyticsEvent:@"dropin.ios.disappear"]; + } +} + +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; + self.visible = NO; +} + +#pragma mark - BTUIScrollViewScrollRectToVisibleDelegate implementation + +// Delegate implementation to handle "custom" autoscrolling via the BTUIScrollView class +// +// Scroll priorities are: +// 1. Attempt to display the submit button, even if it means the card form title is not visible. +// 2. If that isn't possible, at least attempt to show the card form title. +// 3. If that fails, fail just do the default behavior (relevant in landscape). +// +// Some cleanup here could attempt to parameterize or make sane some of the magic number pixel nudging. +- (void)scrollView:(BTUIScrollView *)scrollView requestsScrollRectToVisible:(CGRect)rect animated:(BOOL)animated { + + CGRect targetRect = rect; + + CGRect desiredVisibleTopRect = [self.scrollView convertRect:self.dropInContentView.cardFormSectionHeader.frame fromView:self.dropInContentView]; + desiredVisibleTopRect.origin.y -= 7; + CGRect desiredVisibleBottomRect; + if (self.dropInContentView.ctaControl.hidden) { + desiredVisibleBottomRect = desiredVisibleTopRect; + } else { + desiredVisibleBottomRect = [self.scrollView convertRect:self.dropInContentView.ctaControl.frame fromView:self.dropInContentView]; + } + + CGFloat visibleAreaHeight = self.scrollView.frame.size.height - self.scrollView.contentInset.bottom - self.scrollView.contentInset.top; + + CGRect weightedBottomRect = CGRectUnion(targetRect, desiredVisibleBottomRect); + if (weightedBottomRect.size.height <= visibleAreaHeight) { + targetRect = weightedBottomRect; + } + + CGRect weightedTopRect = CGRectUnion(targetRect, desiredVisibleTopRect); + + if (weightedTopRect.size.height <= visibleAreaHeight) { + targetRect = weightedTopRect; + targetRect.size.height = MIN(visibleAreaHeight, CGRectGetMaxY(weightedBottomRect) - CGRectGetMinY(targetRect)); + } + + [scrollView defaultScrollRectToVisible:targetRect animated:animated]; +} + +#pragma mark - Keyboard behavior + +- (void)keyboardWillHide:(__unused NSNotification *)inputViewNotification { + UIEdgeInsets ei = UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0); + [UIView animateWithDuration:self.theme.transitionDuration animations:^{ + self.scrollView.scrollIndicatorInsets = ei; + self.scrollView.contentInset = ei; + }]; +} + +- (void)keyboardWillShow:(__unused NSNotification *)inputViewNotification { + CGRect inputViewFrame = [[[inputViewNotification userInfo] valueForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; + CGRect inputViewFrameInView = [self.view convertRect:inputViewFrame fromView:nil]; + CGRect intersection = CGRectIntersection(self.scrollView.frame, inputViewFrameInView); + UIEdgeInsets ei = UIEdgeInsetsMake(0.0, 0.0, intersection.size.height, 0.0); + self.scrollView.scrollIndicatorInsets = ei; + self.scrollView.contentInset = ei; +} + +#pragma mark - Handlers + +- (void)tappedChangePaymentMethod { + UIViewController *rootViewController; + if (self.paymentMethodNonces.count == 1) { + rootViewController = self.addPaymentMethodDropInViewController; + } else { + BTDropInSelectPaymentMethodViewController *selectPaymentMethod = [[BTDropInSelectPaymentMethodViewController alloc] init]; + selectPaymentMethod.title = BTDropInLocalizedString(SELECT_PAYMENT_METHOD_TITLE); + selectPaymentMethod.theme = self.theme; + selectPaymentMethod.paymentMethodNonces = self.paymentMethodNonces; + selectPaymentMethod.selectedPaymentMethodIndex = self.selectedPaymentMethodNonceIndex; + selectPaymentMethod.delegate = self; + selectPaymentMethod.client = self.apiClient; + rootViewController = selectPaymentMethod; + } + rootViewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel + target:self + action:@selector(didCancelChangePaymentMethod)]; + + UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; + [self presentViewController:navController animated:YES completion:nil]; +} + +- (void)tappedSubmitForm { + [self showLoadingState:YES]; + + BTPaymentMethodNonce *paymentInfo = [self selectedPaymentMethod]; + if (paymentInfo != nil) { + [self showLoadingState:NO]; + [self informDelegateWillComplete]; + [self informDelegateDidAddPaymentInfo:paymentInfo]; + } else if (!self.dropInContentView.cardForm.hidden) { + BTUICardFormView *cardForm = self.dropInContentView.cardForm; + + if (cardForm.valid) { + [self informDelegateWillComplete]; + + BTCard *card = [[BTCard alloc] initWithNumber:cardForm.number expirationMonth:cardForm.expirationMonth expirationYear:cardForm.expirationYear cvv:cardForm.cvv]; + card.postalCode = cardForm.postalCode; + card.shouldValidate = self.apiClient.tokenizationKey ? NO : YES; + BTCardRequest *request = [[BTCardRequest alloc] initWithCard:card]; + BTAPIClient *copiedAPIClient = [self.apiClient copyWithSource:BTClientMetadataSourceForm integration:BTClientMetadataIntegrationDropIn]; + BTCardClient *cardClient = [[BTCardClient alloc] initWithAPIClient:copiedAPIClient]; + + [cardClient tokenizeCard:request options:nil completion:^(BTCardNonce * _Nullable tokenizedCard, NSError * _Nullable error) { + [self showLoadingState:NO]; + + if (error) { + if ([error.domain isEqualToString:@"com.braintreepayments.BTCardClientErrorDomain"] && error.code == BTCardClientErrorTypeCustomerInputInvalid) { + [self informUserDidFailWithError:error]; + } else { + BTDropInErrorAlert *errorAlert = [[BTDropInErrorAlert alloc] initWithPresentingViewController:self]; + errorAlert.title = BTDropInLocalizedString(ERROR_SAVING_CARD_ALERT_TITLE); + errorAlert.message = error.localizedDescription; + __weak typeof(self) weakSelf = self; + errorAlert.cancelBlock = ^{ + // Use the paymentMethodNonces setter to update state + weakSelf.paymentMethodNonces = weakSelf.paymentMethodNonces; + }; + [self.errorAlerts addObject:errorAlert]; + [errorAlert showWithDismissalHandler:^{ + [self.errorAlerts removeObject:errorAlert]; + }]; + } + return; + } + + [self informDelegateDidAddPaymentInfo:tokenizedCard]; + }]; + } else { + BTDropInErrorAlert *errorAlert = [[BTDropInErrorAlert alloc] initWithPresentingViewController:self]; + errorAlert.title = BTDropInLocalizedString(ERROR_SAVING_CARD_ALERT_TITLE); + errorAlert.message = BTDropInLocalizedString(ERROR_SAVING_CARD_MESSAGE); + [self.errorAlerts addObject:errorAlert]; + [errorAlert showWithDismissalHandler:^{ + [self.errorAlerts removeObject:errorAlert]; + }]; + } + } +} + +- (void)didCancelChangePaymentMethod { + [self dismissViewControllerAnimated:YES completion:nil]; +} + +#pragma mark Progress UI + +- (void)cardFormViewDidBeginEditing:(__unused BTUICardFormView *)cardFormView { + if (!self.cardEntryDidFocus) { + [self.apiClient sendAnalyticsEvent:@"ios.dropin.card.focus"]; + self.cardEntryDidFocus = YES; + } +} + + +- (void)showLoadingState:(BOOL)loadingState { + [self.dropInContentView.ctaControl showLoadingState:loadingState]; + self.submitBarButtonItem.enabled = !loadingState; + if (self.submitBarButtonItem != nil) { + [BTUI activityIndicatorViewStyleForBarTintColor:self.navigationController.navigationBar.barTintColor]; + UIActivityIndicatorView *submitInProgressActivityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; + [submitInProgressActivityIndicator startAnimating]; + UIBarButtonItem *submitInProgressActivityIndicatorBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:submitInProgressActivityIndicator]; + [self.navigationItem setRightBarButtonItem:(loadingState ? submitInProgressActivityIndicatorBarButtonItem : self.submitBarButtonItem) animated:YES]; + } +} + +#pragma mark Error UI + +- (void)informUserDidFailWithError:(__unused NSError *)error { + BTDropInErrorState *state = [[BTDropInErrorState alloc] initWithError:error]; + + [self.dropInContentView.cardForm showTopLevelError:state.errorTitle]; + for (NSNumber *fieldNumber in state.highlightedFields) { + BTUICardFormField field = [fieldNumber unsignedIntegerValue]; + [self.dropInContentView.cardForm showErrorForField:field]; + } +} + +#pragma mark Card Form Delegate methods + +- (void)cardFormViewDidChange:(__unused BTUICardFormView *)cardFormView { + + if (!self.cardEntryDidBegin) { + [self.apiClient sendAnalyticsEvent:@"dropin.ios.add-card.start"]; + self.cardEntryDidBegin = YES; + } + + [self updateValidity]; +} + +#pragma mark Drop In Select Payment Method Table View Controller Delegate methods + +- (void)selectPaymentMethodViewController:(BTDropInSelectPaymentMethodViewController *)viewController + didSelectPaymentMethodAtIndex:(NSUInteger)index { + self.selectedPaymentMethodNonceIndex = index; + [viewController.navigationController dismissViewControllerAnimated:YES completion:nil]; +} + +- (void)selectPaymentMethodViewControllerDidRequestNew:(BTDropInSelectPaymentMethodViewController *)viewController { + [viewController.navigationController pushViewController:self.addPaymentMethodDropInViewController animated:YES]; +} + +#pragma mark BTDropInViewControllerDelegate implementation + +- (void)dropInViewController:(BTDropInViewController *)viewController didSucceedWithTokenization:(BTPaymentMethodNonce *)paymentMethodNonce { + [viewController.navigationController dismissViewControllerAnimated:YES completion:nil]; + + NSMutableArray *newPaymentMethodNonces = [NSMutableArray arrayWithArray:self.paymentMethodNonces]; + [newPaymentMethodNonces insertObject:paymentMethodNonce atIndex:0]; + self.paymentMethodNonces = newPaymentMethodNonces; +} + +- (void)dropInViewControllerDidCancel:(BTDropInViewController *)viewController { + [viewController.navigationController dismissViewControllerAnimated:YES completion:nil]; +} + +#pragma mark BTAppSwitchDelegate + +- (void)paymentDriverWillPerformAppSwitch:(__unused id)sender { + // If there is a presented view controller, dismiss it before app switch + // so that the result of the app switch can be shown in this view controller. + if ([self presentedViewController]) { + [self dismissViewControllerAnimated:YES completion:nil]; + } +} + +#pragma mark Delegate Notifications + +- (void)informDelegateDidLoad { + if ([self.delegate respondsToSelector:@selector(dropInViewControllerDidLoad:)]) { + [self.delegate dropInViewControllerDidLoad:self]; + } +} + +- (void)informDelegateWillComplete { + if ([self.delegate respondsToSelector:@selector(dropInViewControllerWillComplete:)]) { + [self.delegate dropInViewControllerWillComplete:self]; + } +} + +- (void)informDelegateDidAddPaymentInfo:(BTPaymentMethodNonce *)paymentMethodNonce { + if ([self.delegate respondsToSelector:@selector(dropInViewController:didSucceedWithTokenization:)]) { + [self.delegate dropInViewController:self + didSucceedWithTokenization:paymentMethodNonce]; + } +} + +- (void)informDelegateDidCancel { + if ([self.delegate respondsToSelector:@selector(dropInViewControllerDidCancel:)]) { + [self.delegate dropInViewControllerDidCancel:self]; + } +} + +#pragma mark User Supplied Parameters + +- (void)setFullForm:(BOOL)fullForm { + _fullForm = fullForm; + if (!self.fullForm) { + self.dropInContentView.state = BTDropInContentViewStateForm; + } +} + +- (void)setShouldHideCallToAction:(BOOL)shouldHideCallToAction { + self.dropInContentView.hideCTA = shouldHideCallToAction; + + self.submitBarButtonItem = shouldHideCallToAction ? [[UIBarButtonItem alloc] + initWithBarButtonSystemItem:UIBarButtonSystemItemSave + target:self + action:@selector(tappedSubmitForm)] : nil; + self.submitBarButtonItem.style = UIBarButtonItemStyleDone; + self.navigationItem.rightBarButtonItem = self.submitBarButtonItem; +} + +- (void)setSummaryTitle:(NSString *)summaryTitle { + self.dropInContentView.summaryView.slug = summaryTitle; + self.dropInContentView.hideSummary = (summaryTitle == nil || self.dropInContentView.summaryView.summary == nil); +} + +- (void)setSummaryDescription:(NSString *)summaryDescription { + self.dropInContentView.summaryView.summary = summaryDescription; + self.dropInContentView.hideSummary = (self.dropInContentView.summaryView.slug == nil || summaryDescription == nil); +} + +- (void)setDisplayAmount:(NSString *)displayAmount { + self.dropInContentView.summaryView.amount = displayAmount; +} + +- (void)setCallToActionText:(NSString *)callToActionText { + self.dropInContentView.ctaControl.callToAction = callToActionText; +} + +- (void)setCardNumber:(NSString *)cardNumber { + self.dropInContentView.cardForm.number = cardNumber; +} + +- (void)setCardExpirationMonth:(NSInteger)expirationMonth year:(NSInteger)expirationYear { + [self.dropInContentView.cardForm setExpirationMonth:expirationMonth year:expirationYear]; +} + +#pragma mark Data + +- (void)setPaymentMethodNonces:(NSArray *)paymentMethodNonces { + _paymentMethodNonces = paymentMethodNonces; + BTDropInContentViewStateType newState; + + if ([self.paymentMethodNonces count] == 0) { + self.selectedPaymentMethodNonceIndex = NSNotFound; + newState = BTDropInContentViewStateForm; + } else { + self.selectedPaymentMethodNonceIndex = 0; + newState = BTDropInContentViewStatePaymentMethodsOnFile; + } + if (self.visible) { + NSTimeInterval elapsed = [NSDate timeIntervalSinceReferenceDate] - self.visibleStartTime; + if (elapsed < self.theme.minimumVisibilityTime) { + NSTimeInterval delay = self.theme.minimumVisibilityTime - elapsed; + + __weak typeof(self) weakSelf = self; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self.dropInContentView setState:newState animate:YES completion:^{ + [weakSelf updateValidity]; + }]; + }); + return; + } + } + [self.dropInContentView setState:newState animate:self.visible]; + [self updateValidity]; +} + +- (void)setSelectedPaymentMethodNonceIndex:(NSInteger)selectedPaymentMethodNonceIndex { + _selectedPaymentMethodNonceIndex = selectedPaymentMethodNonceIndex; + if (_selectedPaymentMethodNonceIndex != NSNotFound) { + BTPaymentMethodNonce *defaultPaymentMethod = [self selectedPaymentMethod]; + BTUIPaymentOptionType paymentMethodType = [BTUI paymentOptionTypeForPaymentInfoType:defaultPaymentMethod.type]; + self.dropInContentView.selectedPaymentMethodView.type = paymentMethodType; + self.dropInContentView.selectedPaymentMethodView.detailDescription = defaultPaymentMethod.localizedDescription; + } + [self updateValidity]; +} + +- (BTPaymentMethodNonce *)selectedPaymentMethod { + return self.selectedPaymentMethodNonceIndex != NSNotFound ? self.paymentMethodNonces[self.selectedPaymentMethodNonceIndex] : nil; +} + +- (void)updateValidity { + BTPaymentMethodNonce *paymentMethod = [self selectedPaymentMethod]; + BOOL valid = (paymentMethod != nil) || (!self.dropInContentView.cardForm.hidden && self.dropInContentView.cardForm.valid); + + [self.navigationItem.rightBarButtonItem setEnabled:valid]; + [UIView animateWithDuration:self.theme.quickTransitionDuration animations:^{ + self.dropInContentView.ctaControl.enabled = valid; + self.dropInContentView.paymentButton.alpha = valid ? 0.3 : 1.0; + }]; +} + +- (void)fetchPaymentMethodsOnCompletion:(void(^)(void))completionBlock { + // Check for proper authorization before fetching payment methods to suppress errors when using tokenization key + if (!self.apiClient.clientToken) { + self.paymentMethodNonces = @[]; + if (completionBlock) { + completionBlock(); + } + return; + } + + [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; + + [self.apiClient fetchPaymentMethodNonces:self.paymentRequest.showDefaultPaymentMethodNonceFirst completion:^(NSArray *paymentMethodNonces, NSError *error) { + [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; + + if (error) { + BTDropInErrorAlert *errorAlert = [[BTDropInErrorAlert alloc] initWithPresentingViewController:self]; + errorAlert.title = error.localizedDescription; + BTJSON *errorBody = error.userInfo[BTHTTPJSONResponseBodyKey]; + errorAlert.message = [errorBody[@"error"][@"message"] asString]; + errorAlert.cancelBlock = ^{ + [self informDelegateDidCancel]; + if (completionBlock) completionBlock(); + }; + errorAlert.retryBlock = ^{ + [self fetchPaymentMethodsOnCompletion:completionBlock]; + }; + [self.errorAlerts addObject:errorAlert]; + [errorAlert showWithDismissalHandler:^{ + [self.errorAlerts removeObject:errorAlert]; + }]; + } else { + self.paymentMethodNonces = [paymentMethodNonces copy]; + if (completionBlock) { + completionBlock(); + } + } + }]; +} + +#pragma mark - BTPaymentRequest + +@synthesize paymentRequest = _paymentRequest; + +- (BTPaymentRequest *)paymentRequest { + if (!_paymentRequest) { + _paymentRequest = [[BTPaymentRequest alloc] init]; + } + return _paymentRequest; +} + +- (void)setPaymentRequest:(BTPaymentRequest *)paymentRequest { + _paymentRequest = paymentRequest; + [self updateDropInContentViewFromPaymentRequest]; +} + +- (void)updateDropInContentViewFromPaymentRequest { + self.dropInContentView.paymentButton.paymentRequest = self.paymentRequest; + [self setShouldHideCallToAction:self.paymentRequest.shouldHideCallToAction]; + [self setSummaryTitle:self.paymentRequest.summaryTitle]; + [self setSummaryDescription:self.paymentRequest.summaryDescription]; + [self setDisplayAmount:self.paymentRequest.displayAmount]; + [self setCallToActionText:self.paymentRequest.callToActionText]; +} + +#pragma mark - Helpers + +- (BTDropInViewController *)addPaymentMethodDropInViewController { + BTDropInViewController *addPaymentMethodDropInViewController = [[BTDropInViewController alloc] initWithAPIClient:self.apiClient]; + + addPaymentMethodDropInViewController.title = BTDropInLocalizedString(ADD_PAYMENT_METHOD_VIEW_CONTROLLER_TITLE); + addPaymentMethodDropInViewController.fullForm = NO; + + BTPaymentRequest *paymentRequest = [BTPaymentRequest new]; + paymentRequest.shouldHideCallToAction = YES; + addPaymentMethodDropInViewController.paymentRequest = paymentRequest; + + addPaymentMethodDropInViewController.delegate = self; + + __weak typeof(self) weakSelf = self; + __weak typeof(addPaymentMethodDropInViewController) weakAddPaymentMethodController = addPaymentMethodDropInViewController; + addPaymentMethodDropInViewController.dropInContentView.paymentButton.completion = ^(BTPaymentMethodNonce *paymentMethodNonce, NSError *error) { + [weakSelf paymentButtonDidCompleteTokenization:paymentMethodNonce fromViewController:weakAddPaymentMethodController error:error]; + }; + + return addPaymentMethodDropInViewController; +} + +- (void)paymentButtonDidCompleteTokenization:(BTPaymentMethodNonce *)paymentMethodNonce + fromViewController:(UIViewController *)viewController + error:(NSError *)error { + if (error) { + NSString *savePaymentMethodErrorAlertTitle = error.localizedDescription ?: BTDropInLocalizedString(ERROR_ALERT_CONNECTION_ERROR); + + BTDropInErrorAlert *errorAlert = [[BTDropInErrorAlert alloc] initWithPresentingViewController:viewController]; + errorAlert.title = savePaymentMethodErrorAlertTitle; + errorAlert.message = error.localizedFailureReason; + errorAlert.cancelBlock = ^{ + // Use the paymentMethodNonces setter to update state + self.paymentMethodNonces = self.paymentMethodNonces; + }; + + [self.errorAlerts addObject:errorAlert]; + [errorAlert showWithDismissalHandler:^{ + [self.errorAlerts removeObject:errorAlert]; + }]; + } else if (paymentMethodNonce) { + NSMutableArray *newPaymentMethods = [NSMutableArray arrayWithArray:self.paymentMethodNonces]; + [newPaymentMethods insertObject:paymentMethodNonce atIndex:0]; + self.paymentMethodNonces = newPaymentMethods; + [self informDelegateDidAddPaymentInfo:paymentMethodNonce]; + } else { + // Refresh payment methods display + self.paymentMethodNonces = self.paymentMethodNonces; + } +} + +- (BOOL)isAddPaymentMethodDropInViewController { + return [self.delegate isKindOfClass:[BTDropInViewController class]]; +} + +#pragma mark - BTViewControllerPresentingDelegate + +- (void)paymentDriver:(__unused id)driver requestsPresentationOfViewController:(UIViewController *)viewController { + UIViewController *presentingViewController = self.paymentRequest.presentViewControllersFromTop? [BTDropInUtil topViewController] : self; + [presentingViewController presentViewController:viewController animated:YES completion:nil]; +} + +- (void)paymentDriver:(__unused id)driver requestsDismissalOfViewController:(__unused UIViewController *)viewController { + [viewController dismissViewControllerAnimated:YES completion:nil]; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Drop-In/BTDropInViewController_Internal.h b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInViewController_Internal.h new file mode 100644 index 0000000..24b4b97 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/BTDropInViewController_Internal.h @@ -0,0 +1,14 @@ +#import "BTDropInViewController.h" +#import "BTDropInContentView.h" +#import "BTViewControllerPresentingDelegate.h" + +@interface BTDropInViewController () + +@property (nonatomic, strong) BTDropInContentView *dropInContentView; + +- (BTDropInViewController *)addPaymentMethodDropInViewController; + +// Exposed for internal testing of presenting view controllers from top +- (void)paymentDriver:(__unused id)driver requestsPresentationOfViewController:(UIViewController *)viewController; + +@end diff --git a/Pods/Braintree/BraintreeUI/Drop-In/BTPaymentButton.m b/Pods/Braintree/BraintreeUI/Drop-In/BTPaymentButton.m new file mode 100644 index 0000000..51d398d --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/BTPaymentButton.m @@ -0,0 +1,362 @@ +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif +#import "BTPaymentButton_Internal.h" +#import "BTLogger_Internal.h" +#import "BTUIVenmoButton.h" +#import "BTUIPayPalButton.h" +#import "BTUIPayPalCompactButton.h" +#import "BTUICoinbaseButton.h" +#import "BTUIHorizontalButtonStackCollectionViewFlowLayout.h" +#import "BTUIPaymentButtonCollectionViewCell.h" + +NSString *BTPaymentButtonPaymentButtonCellIdentifier = @"BTPaymentButtonPaymentButtonCellIdentifier"; + +@interface BTPaymentButton () + +@property (nonatomic, strong) UICollectionView *paymentButtonsCollectionView; +@property (nonatomic, strong) UIActivityIndicatorView *activityIndicatorView; +@property (nonatomic, strong) UIView *topBorder; +@property (nonatomic, strong) UIView *bottomBorder; +@property (nonatomic, assign) BOOL skipConfigurationValidation; + +@end + +@implementation BTPaymentButton + +- (instancetype)initWithAPIClient:(BTAPIClient *)apiClient + completion:(void(^)(BTPaymentMethodNonce *paymentMethodNonce, NSError *error))completion +{ + if (self = [super init]) { + _apiClient = apiClient; + _completion = [completion copy]; + [self setupViews]; + [self fetchConfiguration]; + } + return self; +} + +- (id)init { + self = [super init]; + return self; +} + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self setupViews]; + [self fetchConfiguration]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + [self setupViews]; + [self fetchConfiguration]; + } + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)fetchConfiguration { + [self.activityIndicatorView startAnimating]; + self.paymentButtonsCollectionView.hidden = YES; + + [self.apiClient fetchOrReturnRemoteConfiguration:^(__unused BTConfiguration * _Nullable configuration, __unused NSError * _Nullable error) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self.activityIndicatorView stopAnimating]; + self.paymentButtonsCollectionView.hidden = NO; + + if (error) { + self.completion(nil, error); + return; + } + + self.configuration = configuration; + }); + }]; +} + +- (void)setupViews { + self.clipsToBounds = YES; + + BTUIHorizontalButtonStackCollectionViewFlowLayout *layout = [[BTUIHorizontalButtonStackCollectionViewFlowLayout alloc] init]; + layout.minimumInteritemSpacing = 0.0f; + + self.paymentButtonsCollectionView = [[UICollectionView alloc] initWithFrame:self.bounds + collectionViewLayout:layout]; + self.paymentButtonsCollectionView.accessibilityIdentifier = @"Payment Options"; + self.paymentButtonsCollectionView.translatesAutoresizingMaskIntoConstraints = NO; + self.paymentButtonsCollectionView.allowsSelection = YES; + self.paymentButtonsCollectionView.delaysContentTouches = NO; + self.paymentButtonsCollectionView.delegate = self; + self.paymentButtonsCollectionView.dataSource = self; + self.paymentButtonsCollectionView.backgroundColor = [UIColor whiteColor]; + [self.paymentButtonsCollectionView registerClass:[BTUIPaymentButtonCollectionViewCell class] forCellWithReuseIdentifier:BTPaymentButtonPaymentButtonCellIdentifier]; + + self.topBorder = [[UIView alloc] init]; + self.topBorder.backgroundColor = [self.theme borderColor]; + self.topBorder.translatesAutoresizingMaskIntoConstraints = NO; + + self.bottomBorder = [[UIView alloc] init]; + self.bottomBorder.backgroundColor = [self.theme borderColor]; + self.bottomBorder.translatesAutoresizingMaskIntoConstraints = NO; + + [self addSubview:self.paymentButtonsCollectionView]; + [self addSubview:self.topBorder]; + [self addSubview:self.bottomBorder]; + + _activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + _activityIndicatorView.translatesAutoresizingMaskIntoConstraints = NO; + [self addSubview:_activityIndicatorView]; +} + +- (CGSize)intrinsicContentSize { + CGFloat height = self.enabledPaymentOptions.count > 0 ? 44 : 0; + + return CGSizeMake(UIViewNoIntrinsicMetric, height); +} + +- (void)layoutSubviews { + [super layoutSubviews]; + [self.paymentButtonsCollectionView.collectionViewLayout invalidateLayout]; +} + +- (void)updateConstraints { + NSDictionary *views = @{ @"paymentButtonsCollectionView": self.paymentButtonsCollectionView, + @"topBorder": self.topBorder, + @"bottomBorder": self.bottomBorder }; + NSDictionary *metrics = @{ @"borderWidth": @(self.theme.borderWidth) }; + + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[paymentButtonsCollectionView]|" + options:0 + metrics:metrics + views:views]]; + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[paymentButtonsCollectionView]|" + options:0 + metrics:metrics + views:views]]; + + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[topBorder]|" + options:0 + metrics:metrics + views:views]]; + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topBorder(==borderWidth)]" + options:0 + metrics:metrics + views:views]]; + + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[bottomBorder]|" + options:0 + metrics:metrics + views:views]]; + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[bottomBorder(==borderWidth)]|" + options:0 + metrics:metrics + views:views]]; + + [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicatorView + attribute:NSLayoutAttributeCenterX + relatedBy:NSLayoutRelationEqual + toItem:self + attribute:NSLayoutAttributeCenterX + multiplier:1 + constant:0]]; + [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicatorView + attribute:NSLayoutAttributeCenterY + relatedBy:NSLayoutRelationEqual + toItem:self + attribute:NSLayoutAttributeCenterY + multiplier:1 + constant:0]]; + + [super updateConstraints]; +} + +#pragma mark - Accessors + +- (id)application { + if (!_application) { + _application = [UIApplication sharedApplication]; + } + return _application; +} + +- (void)setApiClient:(BTAPIClient *)apiClient { + _apiClient = apiClient; + [self fetchConfiguration]; +} + +#pragma mark PaymentButton State + +@synthesize enabledPaymentOptions = _enabledPaymentOptions; + +- (NSOrderedSet *)enabledPaymentOptions { + if (!_enabledPaymentOptions) { + _enabledPaymentOptions = [NSOrderedSet orderedSetWithArray:@[ @"PayPal", @"Venmo" ]]; + } + + if (self.skipConfigurationValidation) { + return _enabledPaymentOptions; + } + + /// Filter the availability of payment options by checking the merchant configuration + NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(NSString *paymentOption, __unused NSDictionary * _Nullable bindings) { + return [self isPaymentOptionAvailable:paymentOption]; + }]; + return [_enabledPaymentOptions filteredOrderedSetUsingPredicate:predicate]; +} + +- (void)setEnabledPaymentOptions:(NSOrderedSet *)enabledPaymentOptions { + _enabledPaymentOptions = enabledPaymentOptions; + self.skipConfigurationValidation = YES; + + [self invalidateIntrinsicContentSize]; + [self.paymentButtonsCollectionView reloadData]; +} + +- (void)setConfiguration:(BTConfiguration *)configuration { + _configuration = configuration; + + [self invalidateIntrinsicContentSize]; + [self.paymentButtonsCollectionView reloadData]; +} + +- (BOOL)isPaymentOptionAvailable:(NSString *)paymentOption { + if (![[BTTokenizationService sharedService] isTypeAvailable:paymentOption]) { + return NO; // If the payment option's framework is not present, it should never be shown + } + + if (self.configuration == nil) { + return YES; // Without Configuration, we can't do additional filtering. + } + + if ([paymentOption isEqualToString:@"PayPal"]) { + return [self.configuration.json[@"paypalEnabled"] isTrue]; + } else if ([paymentOption isEqualToString:@"Venmo"]) { + // Directly from BTConfiguration+Venmo.m. Be sure to keep these files in sync! This + // is intentionally not DRY so that BraintreeUI does not depend on BraintreeVenmo. + BTJSON *venmoAccessToken = self.configuration.json[@"payWithVenmo"][@"accessToken"]; + NSURLComponents *components = [NSURLComponents componentsWithString:@"com.venmo.touch.v2://x-callback-url/vzero/auth"]; + + BOOL isVenmoAppInstalled = [[self application] canOpenURL:components.URL]; + return venmoAccessToken.isString && isVenmoAppInstalled; + } + // Payment option is available in the tokenization service, but BTPaymentButton does not know how + // to check Configuration for whether it is enabled. Default to YES. + return YES; + +} + +- (BOOL)hasAvailablePaymentMethod { + return self.enabledPaymentOptions.count > 0 ? YES : NO; +} + +- (NSString *)paymentOptionForIndexPath:(NSIndexPath *)indexPath { + return self.enabledPaymentOptions[indexPath.row]; +} + +#pragma mark UICollectionViewDataSource methods + +- (NSInteger)collectionView:(__unused UICollectionView *)collectionView numberOfItemsInSection:(__unused NSInteger)section { + NSParameterAssert(section == 0); + return [self.enabledPaymentOptions count]; +} + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { + NSParameterAssert(indexPath.section == 0); + + BTUIPaymentButtonCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:BTPaymentButtonPaymentButtonCellIdentifier + forIndexPath:indexPath]; + NSString *paymentOption = [self paymentOptionForIndexPath:indexPath]; + + UIControl *paymentButton; + if ([paymentOption isEqualToString:@"PayPal"]) { + if (self.enabledPaymentOptions.count == 1) { + BTUIPayPalButton *payPalButton = [[BTUIPayPalButton alloc] initWithFrame:cell.bounds]; + payPalButton.layer.cornerRadius = self.theme.cornerRadius; + self.topBorder.hidden = YES; + self.bottomBorder.hidden = YES; + collectionView.backgroundColor = [UIColor clearColor]; + paymentButton = payPalButton; + } else { + paymentButton = [[BTUIPayPalCompactButton alloc] initWithFrame:cell.bounds]; + } + } else if ([paymentOption isEqualToString:@"Venmo"]) { + paymentButton = [[BTUIVenmoButton alloc] initWithFrame:cell.bounds]; + } else if ([paymentOption isEqualToString:@"Coinbase"]) { + paymentButton = [[BTUICoinbaseButton alloc] initWithFrame:cell.bounds]; + } else { + [[BTLogger sharedLogger] warning:@"BTPaymentButton encountered an unexpected payment option value: %@", paymentOption]; + return cell; + } + + cell.accessibilityLabel = paymentOption; + paymentButton.translatesAutoresizingMaskIntoConstraints = NO; + cell.paymentButton = paymentButton; + + return cell; +} + +- (void)collectionView:(__unused UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { + NSAssert(self.apiClient, @"BTPaymentButton tapped without an apiClient. Please set a BTAPIClient on this payment button by setting the apiClient property."); + NSAssert(self.completion, @"BTPaymentButton tapped without a completion block. Please set up a completion block on this payment button by setting the completion property."); + + NSString *paymentOption = [self paymentOptionForIndexPath:indexPath]; + + if ([[BTTokenizationService sharedService] isTypeAvailable:paymentOption]) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willAppSwitch:) name:BTAppSwitchWillSwitchNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didAppSwitch:) name:BTAppSwitchDidSwitchNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willProcessPaymentInfo:) name:BTAppSwitchWillProcessPaymentInfoNotification object:nil]; + + NSMutableDictionary *options = [NSMutableDictionary dictionary]; + if (self.viewControllerPresentingDelegate != nil) { + options[BTTokenizationServiceViewPresentingDelegateOption] = self.viewControllerPresentingDelegate; + } + if (self.paymentRequest.additionalPayPalScopes != nil) { + options[BTTokenizationServicePayPalScopesOption] = self.paymentRequest.additionalPayPalScopes; + } + + [[BTTokenizationService sharedService] tokenizeType:paymentOption options:options withAPIClient:self.apiClient completion:self.completion]; + } else { + [[BTLogger sharedLogger] warning:@"BTPaymentButton encountered an unexpected payment option value: %@", paymentOption]; + } +} + +- (void)willAppSwitch:(NSNotification *)notification { + [[NSNotificationCenter defaultCenter] removeObserver:self name:BTAppSwitchWillSwitchNotification object:nil]; + + id paymentDriver = notification.object; + if ([self.appSwitchDelegate respondsToSelector:@selector(appSwitcherWillPerformAppSwitch:)]) { + [self.appSwitchDelegate appSwitcherWillPerformAppSwitch:paymentDriver]; + } +} + +- (void)didAppSwitch:(NSNotification *)notification { + [[NSNotificationCenter defaultCenter] removeObserver:self name:BTAppSwitchDidSwitchNotification object:nil]; + + id paymentDriver = notification.object; + BTAppSwitchTarget appSwitchTarget = [notification.userInfo[BTAppSwitchNotificationTargetKey] integerValue]; + if ([self.appSwitchDelegate respondsToSelector:@selector(appSwitcher:didPerformSwitchToTarget:)]) { + [self.appSwitchDelegate appSwitcher:paymentDriver didPerformSwitchToTarget:appSwitchTarget]; + } +} + +- (void)willProcessPaymentInfo:(NSNotification *)notification { + [[NSNotificationCenter defaultCenter] removeObserver:self name:BTAppSwitchWillProcessPaymentInfoNotification object:nil]; + + id paymentDriver = notification.object; + if ([self.appSwitchDelegate respondsToSelector:@selector(appSwitcherWillProcessPaymentInfo:)]) { + [self.appSwitchDelegate appSwitcherWillProcessPaymentInfo:paymentDriver]; + } +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Drop-In/BTPaymentButton_Internal.h b/Pods/Braintree/BraintreeUI/Drop-In/BTPaymentButton_Internal.h new file mode 100644 index 0000000..d1259af --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/BTPaymentButton_Internal.h @@ -0,0 +1,12 @@ +#import "BTPaymentButton.h" + +@interface BTPaymentButton () + +/** + @discussion Defaults to [UIApplication sharedApplication], but exposed for unit tests to inject test doubles + to prevent calls to openURL. Its type is `id` and not `UIApplication` because trying to subclass + UIApplication is not possible, since it enforces that only one instance can ever exist +*/ +@property (nonatomic, strong) id application; + +@end diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/BTDropInLocalizedString.h b/Pods/Braintree/BraintreeUI/Drop-In/Localization/BTDropInLocalizedString.h new file mode 100644 index 0000000..e06d103 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/Localization/BTDropInLocalizedString.h @@ -0,0 +1,21 @@ +#import + +#define BTDropInLocalizedString(KEY) [BTDropInLocalizedString KEY] + +@interface BTDropInLocalizedString : NSObject + ++ (NSString *)DROP_IN_CHANGE_PAYMENT_METHOD_BUTTON_TEXT; ++ (NSString *)ERROR_ALERT_OK_BUTTON_TEXT; ++ (NSString *)ERROR_ALERT_CANCEL_BUTTON_TEXT; ++ (NSString *)ERROR_ALERT_TRY_AGAIN_BUTTON_TEXT; ++ (NSString *)ERROR_ALERT_CONNECTION_ERROR; ++ (NSString *)DEFAULT_CALL_TO_ACTION; ++ (NSString *)CARD_FORM_SECTION_HEADER; ++ (NSString *)SELECT_PAYMENT_METHOD_TITLE; ++ (NSString *)ERROR_SAVING_CARD_ALERT_TITLE; ++ (NSString *)ERROR_SAVING_CARD_MESSAGE; ++ (NSString *)ERROR_SAVING_PAYMENT_METHOD_ALERT_TITLE; ++ (NSString *)ERROR_SAVING_PAYPAL_ACCOUNT_ALERT_MESSAGE; ++ (NSString *)ADD_PAYMENT_METHOD_VIEW_CONTROLLER_TITLE; + +@end diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/BTDropInLocalizedString.m b/Pods/Braintree/BraintreeUI/Drop-In/Localization/BTDropInLocalizedString.m new file mode 100644 index 0000000..83b1646 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Drop-In/Localization/BTDropInLocalizedString.m @@ -0,0 +1,74 @@ +#import "BTDropInLocalizedString.h" + +@implementation BTDropInLocalizedString + ++ (NSBundle *)localizationBundle { + + static NSString * bundleName = @"Braintree-Drop-In-Localization"; + NSString *localizationBundlePath = [[NSBundle mainBundle] pathForResource:bundleName ofType:@"bundle"]; + if (!localizationBundlePath) { + localizationBundlePath = [[NSBundle bundleForClass:[self class]] pathForResource:bundleName ofType:@"bundle"]; + } + + return localizationBundlePath ? [NSBundle bundleWithPath:localizationBundlePath] : [NSBundle mainBundle]; +} + ++ (NSString *)localizationTable { + return @"Drop-In"; +} + ++ (NSString *)DROP_IN_CHANGE_PAYMENT_METHOD_BUTTON_TEXT { + return NSLocalizedStringWithDefaultValue(@"DROP_IN_CHANGE_PAYMENT_METHOD_BUTTON_TEXT", [self localizationTable], [self localizationBundle], @"Change payment method", @"Title text for button on Drop In with a selected payment method that allows user to choose a different payment method on file"); +} + ++ (NSString *)ERROR_ALERT_OK_BUTTON_TEXT { + return NSLocalizedStringWithDefaultValue(@"ERROR_ALERT_OK_BUTTON_TEXT", [self localizationTable], [self localizationBundle], @"OK", @"Button text to indicate acceptance of an alert condition"); +} + + ++ (NSString *)ERROR_ALERT_CANCEL_BUTTON_TEXT { + return NSLocalizedStringWithDefaultValue(@"ERROR_ALERT_CANCEL_BUTTON_TEXT", [self localizationTable], [self localizationBundle], @"Cancel", @"Button text to indicate acceptance of an alert condition"); +} + ++ (NSString *)ERROR_ALERT_TRY_AGAIN_BUTTON_TEXT { + return NSLocalizedStringWithDefaultValue(@"ERROR_ALERT_TRY_AGAIN_BUTTON_TEXT", [self localizationTable], [self localizationBundle], @"Try Again", @"Button text to request that an failed operation should be restarted and to try again"); +} + ++ (NSString *)ERROR_ALERT_CONNECTION_ERROR { + return NSLocalizedStringWithDefaultValue(@"ERROR_ALERT_CONNECTION_ERROR", [self localizationTable], [self localizationBundle], @"Connection Error", @"Vague title for alert view that ambiguously indicates an unspecified failure"); +} + ++ (NSString *)DEFAULT_CALL_TO_ACTION { + return NSLocalizedStringWithDefaultValue(@"DEFAULT_CALL_TO_ACTION", [self localizationTable], [self localizationBundle], @"Pay", @"Default text to display in Drop In view controller call to action (Submit button)"); +} + ++ (NSString *)CARD_FORM_SECTION_HEADER { + return NSLocalizedStringWithDefaultValue(@"CARD_FORM_SECTION_HEADER", [self localizationTable], [self localizationBundle], @"Pay with a card", @"Section header above card form in Drop In view controller"); +} + ++ (NSString *)SELECT_PAYMENT_METHOD_TITLE { + return NSLocalizedStringWithDefaultValue(@"SELECT_PAYMENT_METHOD_TITLE", [self localizationTable], [self localizationBundle], @"Payment Method", @"Title for select payment method view controller"); +} + ++ (NSString *)ERROR_SAVING_CARD_ALERT_TITLE{ + return NSLocalizedStringWithDefaultValue(@"ERROR_SAVING_CARD_ALERT_TITLE", [self localizationTable], [self localizationBundle], @"Error Saving Card", @"Title for alert view that is displayed when Drop In submission fails because there was an error saving the card"); +} + ++ (NSString *)ERROR_SAVING_CARD_MESSAGE { + return NSLocalizedStringWithDefaultValue(@"ERROR_SAVING_CARD_MESSAGE", [self localizationTable], [self localizationBundle], @"Please try again.", @"Message for alert view that is displayed when Drop In submission fails because there was an error saving the card"); +} + ++ (NSString *)ERROR_SAVING_PAYMENT_METHOD_ALERT_TITLE { + return NSLocalizedStringWithDefaultValue(@"ERROR_SAVING_PAYMENT_METHOD_ALERT_TITLE", [self localizationTable], [self localizationBundle], @"PayPal Error", @"Title for alert view that is displayed when Drop In submission fails because there was an error saving the PayPal account"); +} + + ++ (NSString *)ERROR_SAVING_PAYPAL_ACCOUNT_ALERT_MESSAGE { + return NSLocalizedStringWithDefaultValue(@"ERROR_SAVING_PAYPAL_ACCOUNT_ALERT_MESSAGE", [self localizationTable], [self localizationBundle], @"Please try again.", @"Message for alert view that is displayed when Drop In submission fails because there was an error saving the PayPal account"); +} + ++ (NSString *)ADD_PAYMENT_METHOD_VIEW_CONTROLLER_TITLE { + return NSLocalizedStringWithDefaultValue(@"ADD_PAYMENT_METHOD_VIEW_CONTROLLER_TITLE", [self localizationTable], [self localizationBundle], @"Add Payment Method", @"Title for view controller presented by Drop In to collect a new payment method when payment methods are already on file"); +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/da.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/da.lproj/Drop-In.strings new file mode 100644 index 0000000..4c29707 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/da.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/de.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/de.lproj/Drop-In.strings new file mode 100644 index 0000000..fb374e0 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/de.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/en.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/en.lproj/Drop-In.strings new file mode 100644 index 0000000..9f87bef Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/en.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/en_AU.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/en_AU.lproj/Drop-In.strings new file mode 100644 index 0000000..6831369 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/en_AU.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/en_CA.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/en_CA.lproj/Drop-In.strings new file mode 100644 index 0000000..9f87bef Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/en_CA.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/en_GB.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/en_GB.lproj/Drop-In.strings new file mode 100644 index 0000000..66af1ca Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/en_GB.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/es.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/es.lproj/Drop-In.strings new file mode 100644 index 0000000..d22ffec Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/es.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/es_ES.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/es_ES.lproj/Drop-In.strings new file mode 100644 index 0000000..ef39242 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/es_ES.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/fr.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/fr.lproj/Drop-In.strings new file mode 100644 index 0000000..35a6078 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/fr.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/fr_CA.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/fr_CA.lproj/Drop-In.strings new file mode 100644 index 0000000..940077d Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/fr_CA.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/fr_FR.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/fr_FR.lproj/Drop-In.strings new file mode 100644 index 0000000..f829499 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/fr_FR.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/he.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/he.lproj/Drop-In.strings new file mode 100644 index 0000000..da09d22 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/he.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/it.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/it.lproj/Drop-In.strings new file mode 100644 index 0000000..a95735c Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/it.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/nb.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/nb.lproj/Drop-In.strings new file mode 100644 index 0000000..59665fb Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/nb.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/nl.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/nl.lproj/Drop-In.strings new file mode 100644 index 0000000..cbfe53f Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/nl.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/pl.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/pl.lproj/Drop-In.strings new file mode 100644 index 0000000..5c1c930 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/pl.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/pt.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/pt.lproj/Drop-In.strings new file mode 100644 index 0000000..b0d7302 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/pt.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/ru.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/ru.lproj/Drop-In.strings new file mode 100644 index 0000000..cfaf5d0 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/ru.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/sv.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/sv.lproj/Drop-In.strings new file mode 100644 index 0000000..0a6c7d7 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/sv.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/tr.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/tr.lproj/Drop-In.strings new file mode 100644 index 0000000..0a70112 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/tr.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Drop-In/Localization/zh-Hans.lproj/Drop-In.strings b/Pods/Braintree/BraintreeUI/Drop-In/Localization/zh-Hans.lproj/Drop-In.strings new file mode 100644 index 0000000..0527d28 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Drop-In/Localization/zh-Hans.lproj/Drop-In.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/BTUILocalizedString.h b/Pods/Braintree/BraintreeUI/Localization/BTUILocalizedString.h new file mode 100644 index 0000000..b80ffba --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Localization/BTUILocalizedString.h @@ -0,0 +1,33 @@ +#import + +#define BTUILocalizedString(KEY) [BTUILocalizedString KEY] + +@interface BTUILocalizedString : NSObject + ++ (NSString *)CARD_NUMBER_PLACEHOLDER; ++ (NSString *)CVV_FIELD_PLACEHOLDER; ++ (NSString *)EXPIRY_PLACEHOLDER_FOUR_DIGIT_YEAR; ++ (NSString *)EXPIRY_PLACEHOLDER_TWO_DIGIT_YEAR; ++ (NSString *)PAYPAL_CARD_BRAND; ++ (NSString *)POSTAL_CODE_PLACEHOLDER; ++ (NSString *)TOP_LEVEL_ERROR_ALERT_VIEW_OK_BUTTON_TEXT; ++ (NSString *)PHONE_NUMBER_PLACEHOLDER; + +#pragma mark Card Brands + ++ (NSString *)CARD_TYPE_AMERICAN_EXPRESS; ++ (NSString *)CARD_TYPE_DISCOVER; ++ (NSString *)CARD_TYPE_DINERS_CLUB; ++ (NSString *)CARD_TYPE_MASTER_CARD; ++ (NSString *)CARD_TYPE_VISA; ++ (NSString *)CARD_TYPE_JCB; ++ (NSString *)CARD_TYPE_MAESTRO; ++ (NSString *)CARD_TYPE_UNION_PAY; ++ (NSString *)CARD_TYPE_SWITCH; ++ (NSString *)CARD_TYPE_SOLO; ++ (NSString *)CARD_TYPE_LASER; ++ (NSString *)PAYMENT_METHOD_TYPE_PAYPAL; ++ (NSString *)PAYMENT_METHOD_TYPE_COINBASE; ++ (NSString *)PAYMENT_METHOD_TYPE_VENMO; + +@end diff --git a/Pods/Braintree/BraintreeUI/Localization/BTUILocalizedString.m b/Pods/Braintree/BraintreeUI/Localization/BTUILocalizedString.m new file mode 100644 index 0000000..247ba9b --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Localization/BTUILocalizedString.m @@ -0,0 +1,108 @@ +#import "BTUILocalizedString.h" + +@implementation BTUILocalizedString + ++ (NSBundle *)localizationBundle { + + static NSString * bundleName = @"Braintree-UI-Localization"; + NSString *localizationBundlePath = [[NSBundle mainBundle] pathForResource:bundleName ofType:@"bundle"]; + if (!localizationBundlePath) { + localizationBundlePath = [[NSBundle bundleForClass:[self class]] pathForResource:bundleName ofType:@"bundle"]; + } + + return localizationBundlePath ? [NSBundle bundleWithPath:localizationBundlePath] : [NSBundle mainBundle]; +} + ++ (NSString *)localizationTable { + return @"UI"; +} + ++ (NSString *)CVV_FIELD_PLACEHOLDER { + return NSLocalizedStringWithDefaultValue(@"CVV_FIELD_PLACEHOLDER", [self localizationTable], [self localizationBundle], @"CVV", @"CVV (credit card security code) field placeholder"); +} + ++ (NSString *)CARD_NUMBER_PLACEHOLDER { + return NSLocalizedStringWithDefaultValue(@"CARD_NUMBER_PLACEHOLDER", [self localizationTable], [self localizationBundle], @"Card Number", @"Credit card number field placeholder"); +} + ++ (NSString *)PHONE_NUMBER_PLACEHOLDER { + return NSLocalizedStringWithDefaultValue(@"PHONE_NUMBER_PLACEHOLDER", [self localizationTable], [self localizationBundle], @"Phone Number", @"Phone number field placeholder"); +} + ++ (NSString *)EXPIRY_PLACEHOLDER_FOUR_DIGIT_YEAR { + return NSLocalizedStringWithDefaultValue(@"EXPIRY_PLACEHOLDER_FOUR_DIGIT_YEAR", [self localizationTable], [self localizationBundle], @"MM/YYYY", @"Credit card expiration date field placeholder (MM/YYYY format)"); +} + ++ (NSString *)EXPIRY_PLACEHOLDER_TWO_DIGIT_YEAR { + return NSLocalizedStringWithDefaultValue(@"EXPIRY_PLACEHOLDER_TWO_DIGIT_YEAR", [self localizationTable], [self localizationBundle], @"MM/YY", @"Credit card expiration date field placeholder (MM/YY format)"); +} + ++ (NSString *)PAYPAL_CARD_BRAND { + return NSLocalizedStringWithDefaultValue(@"PAYPAL_CARD_BRAND", [self localizationTable], [self localizationBundle], @"PayPal", @"PayPal payment method name"); +} + ++ (NSString *)POSTAL_CODE_PLACEHOLDER { + return NSLocalizedStringWithDefaultValue(@"POSTAL_CODE_PLACEHOLDER", [self localizationTable], [self localizationBundle], @"Postal Code", @"Credit card billing postal code field placeholder"); +} + ++ (NSString *)TOP_LEVEL_ERROR_ALERT_VIEW_OK_BUTTON_TEXT { + return NSLocalizedStringWithDefaultValue(@"TOP_LEVEL_ERROR_ALERT_VIEW_OK_BUTTON_TEXT", [self localizationTable], [self localizationBundle], @"OK", @"OK Button on card form alert view for top level errors"); +} + ++ (NSString *)CARD_TYPE_AMERICAN_EXPRESS { + return NSLocalizedStringWithDefaultValue(@"CARD_TYPE_AMERICAN_EXPRESS", [self localizationTable], [self localizationBundle], @"American Express", @"American Express card brand"); +} + ++ (NSString *)CARD_TYPE_DINERS_CLUB { + return NSLocalizedStringWithDefaultValue(@"CARD_TYPE_DINERS_CLUB", [self localizationTable], [self localizationBundle], @"Diners Club", @"Diners Club card brand"); +} + ++ (NSString *)CARD_TYPE_DISCOVER { + return NSLocalizedStringWithDefaultValue(@"CARD_TYPE_DISCOVER", [self localizationTable], [self localizationBundle], @"Discover", @"Discover card brand"); +} + ++ (NSString *)CARD_TYPE_MASTER_CARD { + return NSLocalizedStringWithDefaultValue(@"CARD_TYPE_MASTER_CARD", [self localizationTable], [self localizationBundle], @"MasterCard", @"MasterCard card brand"); +} + ++ (NSString *)CARD_TYPE_VISA { + return NSLocalizedStringWithDefaultValue(@"CARD_TYPE_VISA", [self localizationTable], [self localizationBundle], @"Visa", @"Visa card brand"); +} + ++ (NSString *)CARD_TYPE_JCB { + return NSLocalizedStringWithDefaultValue(@"CARD_TYPE_JCB", [self localizationTable], [self localizationBundle], @"JCB", @"JCB card brand"); +} + ++ (NSString *)CARD_TYPE_MAESTRO { + return NSLocalizedStringWithDefaultValue(@"CARD_TYPE_MAESTRO", [self localizationTable], [self localizationBundle], @"Maestro", @"Maestro card brand"); +} + ++ (NSString *)CARD_TYPE_UNION_PAY { + return NSLocalizedStringWithDefaultValue(@"CARD_TYPE_UNION_PAY", [self localizationTable], [self localizationBundle], @"UnionPay", @"UnionPay card brand"); +} + ++ (NSString *)CARD_TYPE_LASER { + return NSLocalizedStringWithDefaultValue(@"CARD_TYPE_LASER", [self localizationTable], [self localizationBundle], @"Laser", @"Laser card brand"); +} + ++ (NSString *)CARD_TYPE_SOLO { + return NSLocalizedStringWithDefaultValue(@"CARD_TYPE_SOLO", [self localizationTable], [self localizationBundle], @"Solo", @"Solo card brand"); +} + ++ (NSString *)CARD_TYPE_SWITCH { + return NSLocalizedStringWithDefaultValue(@"CARD_TYPE_SWITCH", [self localizationTable], [self localizationBundle], @"Switch", @"Switch card brand"); +} + ++ (NSString *)PAYMENT_METHOD_TYPE_PAYPAL { + return NSLocalizedStringWithDefaultValue(@"PAYPAL", [self localizationTable], [self localizationBundle], @"PayPal", @"PayPal (as a standalone term, referring to the payment method type, analogous to Visa or Discover)"); +} + ++ (NSString *)PAYMENT_METHOD_TYPE_COINBASE { + return NSLocalizedStringWithDefaultValue(@"COINBASE", [self localizationTable], [self localizationBundle], @"Coinbase", @"Coinbase (as a standalone term, referring to the bitcoin wallet company)"); +} + ++ (NSString *)PAYMENT_METHOD_TYPE_VENMO { + return NSLocalizedStringWithDefaultValue(@"VENMO", [self localizationTable], [self localizationBundle], @"Venmo", @"Venmo (as a standalone term, referring to Venmo the company)"); +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Localization/da.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/da.lproj/UI.strings new file mode 100644 index 0000000..18bb418 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/da.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/de.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/de.lproj/UI.strings new file mode 100644 index 0000000..d0b59e0 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/de.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/en.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/en.lproj/UI.strings new file mode 100644 index 0000000..647df60 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/en.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/en_AU.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/en_AU.lproj/UI.strings new file mode 100644 index 0000000..889ba70 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/en_AU.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/en_CA.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/en_CA.lproj/UI.strings new file mode 100644 index 0000000..ef2558a Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/en_CA.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/en_GB.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/en_GB.lproj/UI.strings new file mode 100644 index 0000000..e70ece8 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/en_GB.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/es.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/es.lproj/UI.strings new file mode 100644 index 0000000..270e1a7 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/es.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/es_ES.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/es_ES.lproj/UI.strings new file mode 100644 index 0000000..338fcf7 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/es_ES.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/fr.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/fr.lproj/UI.strings new file mode 100644 index 0000000..c45a8a0 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/fr.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/fr_CA.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/fr_CA.lproj/UI.strings new file mode 100644 index 0000000..7927651 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/fr_CA.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/fr_FR.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/fr_FR.lproj/UI.strings new file mode 100644 index 0000000..df933d9 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/fr_FR.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/he.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/he.lproj/UI.strings new file mode 100644 index 0000000..dad0e4f Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/he.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/it.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/it.lproj/UI.strings new file mode 100644 index 0000000..9ee4a22 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/it.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/nb.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/nb.lproj/UI.strings new file mode 100644 index 0000000..449ddb5 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/nb.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/nl.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/nl.lproj/UI.strings new file mode 100644 index 0000000..12ff373 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/nl.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/pl.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/pl.lproj/UI.strings new file mode 100644 index 0000000..36683db Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/pl.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/pt.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/pt.lproj/UI.strings new file mode 100644 index 0000000..2baa2a5 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/pt.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/ru.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/ru.lproj/UI.strings new file mode 100644 index 0000000..f90bf3f Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/ru.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/sv.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/sv.lproj/UI.strings new file mode 100644 index 0000000..449ddb5 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/sv.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/tr.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/tr.lproj/UI.strings new file mode 100644 index 0000000..bf4f400 Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/tr.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Localization/zh-Hans.lproj/UI.strings b/Pods/Braintree/BraintreeUI/Localization/zh-Hans.lproj/UI.strings new file mode 100644 index 0000000..6de374b Binary files /dev/null and b/Pods/Braintree/BraintreeUI/Localization/zh-Hans.lproj/UI.strings differ diff --git a/Pods/Braintree/BraintreeUI/Models/BTPaymentRequest.m b/Pods/Braintree/BraintreeUI/Models/BTPaymentRequest.m new file mode 100644 index 0000000..be6ec3f --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Models/BTPaymentRequest.m @@ -0,0 +1,32 @@ +#import "BTPaymentRequest.h" +#import "BTDropInLocalizedString.h" + +@implementation BTPaymentRequest + +- (instancetype)init +{ + if (self = [super init]) { + _displayAmount = @""; // Use empty string as default value for this non-nullable property. + _callToActionText = BTDropInLocalizedString(DEFAULT_CALL_TO_ACTION); // Default value for this non-nullable property. + _showDefaultPaymentMethodNonceFirst = NO; + } + return self; +} + +- (id)copyWithZone:(__unused NSZone *)zone { + BTPaymentRequest *request = [BTPaymentRequest new]; + request.summaryTitle = self.summaryTitle; + request.summaryDescription = self.summaryDescription; + request.displayAmount = self.displayAmount; + request.callToActionText = self.callToActionText; + request.shouldHideCallToAction = self.shouldHideCallToAction; + request.amount = self.amount; + request.currencyCode = self.currencyCode; + request.noShipping = self.noShipping; + request.presentViewControllersFromTop = self.presentViewControllersFromTop; + request.shippingAddress = self.shippingAddress; + request.showDefaultPaymentMethodNonceFirst = self.showDefaultPaymentMethodNonceFirst; + return request; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Models/BTUICardExpirationValidator.h b/Pods/Braintree/BraintreeUI/Models/BTUICardExpirationValidator.h new file mode 100644 index 0000000..9268fd3 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Models/BTUICardExpirationValidator.h @@ -0,0 +1,9 @@ +#import + +#define kBTUICardExpirationValidatorFarFutureYears 20 + +@interface BTUICardExpirationValidator : NSObject + ++ (BOOL)month:(NSUInteger)month year:(NSUInteger)year validForDate:(NSDate *)date; + +@end diff --git a/Pods/Braintree/BraintreeUI/Models/BTUICardExpirationValidator.m b/Pods/Braintree/BraintreeUI/Models/BTUICardExpirationValidator.m new file mode 100644 index 0000000..f424325 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Models/BTUICardExpirationValidator.m @@ -0,0 +1,43 @@ +#import "BTUICardExpirationValidator.h" + +#ifdef __IPHONE_8_0 +#define kBTNSGregorianCalendarIdentifier NSCalendarIdentifierGregorian +#else +#define kBTNSGregorianCalendarIdentifier NSGregorianCalendar +#endif + +@implementation BTUICardExpirationValidator + ++ (BOOL)month:(NSUInteger)month year:(NSUInteger)year validForDate:(NSDate *)date { + // Creating NSCalendar is expensive, so cache it! + static NSCalendar *gregorianCalendar; + if (!gregorianCalendar) { + gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:kBTNSGregorianCalendarIdentifier]; + } + + NSDateComponents *dateComponents = [[NSDateComponents alloc] init]; + dateComponents.calendar = gregorianCalendar; + dateComponents.year = ((year % 2000) + 2000) ; + dateComponents.month = month; + NSInteger newMonth = (dateComponents.month + 1); + if (newMonth > 12) { + dateComponents.month = newMonth % 12; + dateComponents.year += 1; + } else { + dateComponents.month = newMonth; + } + BOOL expired = [date compare:dateComponents.date] != NSOrderedAscending; + if (expired) { + return NO; + } + + NSDate *farFuture = [date dateByAddingTimeInterval:3600 * 24 * 365.25 * kBTUICardExpirationValidatorFarFutureYears]; // roughly years in the future + BOOL tooFarInTheFuture = [farFuture compare:dateComponents.date] != NSOrderedDescending; + + return !tooFarInTheFuture; +} + + + + +@end diff --git a/Pods/Braintree/BraintreeUI/Models/BTUICardExpiryFormat.h b/Pods/Braintree/BraintreeUI/Models/BTUICardExpiryFormat.h new file mode 100644 index 0000000..7d8c646 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Models/BTUICardExpiryFormat.h @@ -0,0 +1,10 @@ +#import + +@interface BTUICardExpiryFormat : NSObject +@property (nonatomic, copy) NSString *value; +@property (nonatomic, assign) NSUInteger cursorLocation; +@property (nonatomic, assign) BOOL backspace; + +- (void)formattedValue:(NSString * __autoreleasing *)value cursorLocation:(NSUInteger *)cursorLocation; + +@end diff --git a/Pods/Braintree/BraintreeUI/Models/BTUICardExpiryFormat.m b/Pods/Braintree/BraintreeUI/Models/BTUICardExpiryFormat.m new file mode 100644 index 0000000..36efc56 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Models/BTUICardExpiryFormat.m @@ -0,0 +1,51 @@ +#import "BTUICardExpiryFormat.h" +#import "BTUIUtil.h" + +@implementation BTUICardExpiryFormat + +- (void)formattedValue:(NSString *__autoreleasing *)value cursorLocation:(NSUInteger *)cursorLocation { + if (value == NULL || cursorLocation == NULL) { + return; + } + + NSMutableString *s = [NSMutableString stringWithString:self.value]; + *cursorLocation = self.cursorLocation; + + if (s.length == 0) { + *value = s; + return; + } + + if (*cursorLocation == 1 && s.length == 1 && [s characterAtIndex:0] > '1' && [s characterAtIndex:0] <= '9') { + [s insertString:@"0" atIndex:0]; + *cursorLocation += 1; + } + + if (self.backspace) { + if (*cursorLocation == 2 && s.length == 2) { + [s deleteCharactersInRange:NSMakeRange(1, 1)]; + *cursorLocation -= 1; + } + } else { + + NSUInteger slashLocation = [s rangeOfString:@"/"].location; + if (slashLocation != NSNotFound) { + if (slashLocation > 2) { + s = [NSMutableString stringWithString:[BTUIUtil stripNonDigits:s]]; + [s insertString:@"/" atIndex:2]; + *cursorLocation += 1; + } + } else { + if (s.length >= 2) { + [s insertString:@"/" atIndex:2]; + if (*cursorLocation >= 2) { + *cursorLocation += 1; + } + } + } + } + + *value = s; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Models/BTUICardType.h b/Pods/Braintree/BraintreeUI/Models/BTUICardType.h new file mode 100644 index 0000000..4173f57 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Models/BTUICardType.h @@ -0,0 +1,64 @@ +#import + +#import "BTUILocalizedString.h" + +/** + @class BTUICardType + @brief Immutable card type + */ +@interface BTUICardType : NSObject + +/** + @brief Obtain the `BTCardType` for the given brand, or nil if none is found + */ ++ (instancetype)cardTypeForBrand:(NSString *)brand; + +/** + @brief Obtain the `BTCardType` for the given number, or nil if none is found + */ ++ (instancetype)cardTypeForNumber:(NSString *)number; + +/** + @brief Return all possible card types for a number + */ ++ (NSArray *)possibleCardTypesForNumber:(NSString *)number; + +/** + @brief Check if a number is valid + */ +- (BOOL)validNumber:(NSString *)number; + +/** + @brief Check if a number is complete + */ +- (BOOL)completeNumber:(NSString *)number; + +/** + @brief Check is a number is valid and necessarily complete + @note (i.e. it can't get any longer) + */ +- (BOOL)validAndNecessarilyCompleteNumber:(NSString *)number; + +/** + @brief Check if the CVV is valid for a `BTCardType` + */ +- (BOOL)validCvv:(NSString *)cvv; + +/** + @brief Format a number based on type + @note Does NOT validate + */ +- (NSAttributedString *)formatNumber:(NSString *)input; +- (NSAttributedString *)formatNumber:(NSString *)input kerning:(CGFloat)kerning; + ++ (NSUInteger)maxNumberLength; + +@property (nonatomic, copy, readonly) NSString *brand; +@property (nonatomic, strong, readonly) NSArray *validNumberPrefixes; +@property (nonatomic, strong, readonly) NSIndexSet *validNumberLengths; +@property (nonatomic, assign, readonly) NSUInteger validCvvLength; + +@property (nonatomic, strong, readonly) NSArray *formatSpaces; +@property (nonatomic, assign, readonly) NSUInteger maxNumberLength; + +@end diff --git a/Pods/Braintree/BraintreeUI/Models/BTUICardType.m b/Pods/Braintree/BraintreeUI/Models/BTUICardType.m new file mode 100644 index 0000000..2a2e8e9 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Models/BTUICardType.m @@ -0,0 +1,227 @@ +#import + +#import "BTUICardType.h" +#import "BTUIUtil.h" + +#define kDefaultFormatSpaceIndices @[@4, @8, @12, @16] +#define kDefaultCvvLength 3 +#define kDefaultValidNumberLengths [NSIndexSet indexSetWithIndex:16] +#define kInvalidCvvCharacterSet [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet] + + +@implementation BTUICardType + +#pragma mark - Private initializers + +- (instancetype)initWithBrand:(NSString *)brand + prefixes:(NSArray *)prefixes +{ + return [self initWithBrand:brand + prefixes:prefixes + validNumberLengths:kDefaultValidNumberLengths + validCvvLength:kDefaultCvvLength + formatSpaces:kDefaultFormatSpaceIndices]; +} + +- (instancetype)initWithBrand:(NSString *)brand + prefixes:(NSArray *)prefixes + validNumberLengths:(NSIndexSet *)validLengths + validCvvLength:(NSUInteger)cvvLength + formatSpaces:(NSArray *)formatSpaces +{ + self = [super init]; + if (self != nil) { + _brand = brand; + NSError *error; + + _validNumberPrefixes = prefixes; + if (error != nil) { + NSLog(@"Braintree-Payments-UI: %@", error); + } + _validNumberLengths = validLengths; + _validCvvLength = cvvLength; + + NSArray *sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"self" ascending:YES]]; + _formatSpaces = [formatSpaces sortedArrayUsingDescriptors:sortDescriptors] ?: kDefaultFormatSpaceIndices; + _maxNumberLength = [validLengths lastIndex]; + } + return self; +} + +#pragma mark - Finders + ++ (instancetype)cardTypeForBrand:(NSString *)rename { + return [[self class] cardsByBrand][rename]; +} + ++ (instancetype)cardTypeForNumber:(NSString *)number { + if (number.length == 0) { + return nil; + } + for (BTUICardType *cardType in [[self class] allCards]) { + for (NSString *prefix in cardType.validNumberPrefixes) { + if (number.length >= prefix.length) { + NSUInteger compareLength = MIN(prefix.length, number.length); + NSString *sizedNumber = [number substringToIndex:compareLength]; + if ([sizedNumber isEqualToString:prefix]) { + return cardType; + } + } + } + } + return nil; +} + +// Since each card type has a list of acceptable card prefixes, we +// can determine which card types may match a given number ++ (NSArray *)possibleCardTypesForNumber:(NSString *)number { + number = [BTUIUtil stripNonDigits:number]; + if (number.length == 0) { + return [[self class] allCards]; + } + NSMutableSet *possibleCardTypes = [NSMutableSet set]; + for (BTUICardType *cardType in [[self class] allCards]) { + for (NSString *prefix in cardType.validNumberPrefixes) { + NSUInteger compareLength = MIN(prefix.length, number.length); + + NSString *sizedPrefix = [prefix substringToIndex:compareLength]; + NSString *sizedNumber = [number substringToIndex:compareLength]; + if ([sizedNumber isEqualToString:sizedPrefix]) { + [possibleCardTypes addObject:cardType]; + break; + } + } + } + return [possibleCardTypes allObjects]; +} + +#pragma mark - Instance methods + +- (BOOL)validCvv:(NSString *)cvv { + if (cvv.length != self.validCvvLength) { + return NO; + } + return ([cvv rangeOfCharacterFromSet:kInvalidCvvCharacterSet].location == NSNotFound); +} + +- (NSString *)description { + return [NSString stringWithFormat:@"BTUICardType %@", self.brand]; +} + +#pragma mark - Immutable singletons + ++ (NSUInteger)maxNumberLength { + static dispatch_once_t p = 0; + static NSUInteger _maxNumberLength = 0; + dispatch_once(&p, ^{ + for (BTUICardType *t in [self allCards]) { + _maxNumberLength = MAX(_maxNumberLength, t.maxNumberLength); + } + }); + return _maxNumberLength; +} + ++ (NSArray *)allCards +{ + static dispatch_once_t p = 0; + static NSArray *_allCards = nil; + + dispatch_once(&p, ^{ + + BTUICardType *visa = [[BTUICardType alloc] initWithBrand:BTUILocalizedString(CARD_TYPE_VISA) prefixes:@[@"4"]]; + BTUICardType *mastercard = [[BTUICardType alloc] initWithBrand:BTUILocalizedString(CARD_TYPE_MASTER_CARD) + prefixes:@[@"51", @"52", @"53", @"54", @"55"]]; + BTUICardType *discover = [[BTUICardType alloc] initWithBrand:BTUILocalizedString(CARD_TYPE_DISCOVER) prefixes:@[@"6011", @"65", @"644", @"645", @"646", @"647", @"648", @"649"]]; + BTUICardType *jcb = [[BTUICardType alloc] initWithBrand:BTUILocalizedString(CARD_TYPE_JCB) prefixes:@[@"35"]]; + + BTUICardType *amex = [[BTUICardType alloc] initWithBrand:BTUILocalizedString(CARD_TYPE_AMERICAN_EXPRESS) + prefixes:@[@"34", @"37"] + validNumberLengths:[NSIndexSet indexSetWithIndex:15] + validCvvLength:4 + formatSpaces:@[@4, @10]]; + + BTUICardType *dinersClub = [[BTUICardType alloc] initWithBrand:BTUILocalizedString(CARD_TYPE_DINERS_CLUB) + prefixes:@[@"36", @"38", @"300", @"301", @"302", @"303", @"304", @"305"] + validNumberLengths:[NSIndexSet indexSetWithIndex:14] + validCvvLength:3 + formatSpaces:nil]; + + BTUICardType *maestro = [[BTUICardType alloc] initWithBrand:BTUILocalizedString(CARD_TYPE_MAESTRO) + prefixes:@[@"5018", @"5020", @"5038", @"6304", @"6307", @"6759", @"6761", @"6762", @"6763"] + validNumberLengths:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(12, 8)] + validCvvLength:3 + formatSpaces:nil]; + + BTUICardType *unionPay = [[BTUICardType alloc] initWithBrand:BTUILocalizedString(CARD_TYPE_UNION_PAY) + prefixes:@[@"62"] + validNumberLengths:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(16, 4)] + validCvvLength:3 + formatSpaces:nil]; + + _allCards = @[visa, mastercard, discover, amex, dinersClub, jcb, mastercard, maestro, unionPay]; + }); + + // returns the same object each time + return _allCards; +} + ++ (NSDictionary *)cardsByBrand { + + static dispatch_once_t p = 0; + static NSDictionary *_cardsByBrand = nil; + + dispatch_once(&p, ^{ + NSMutableDictionary *d = [NSMutableDictionary dictionary]; + for (BTUICardType *cardType in [self allCards]) { + d[cardType.brand] = cardType; + } + _cardsByBrand = d; + }); + return _cardsByBrand; +} + +#pragma mark - Formatting + +- (NSAttributedString *)formatNumber:(NSString *)input kerning:(CGFloat)kerning{ + + input = [BTUIUtil stripNonDigits:input]; + + NSMutableAttributedString *result = [[NSMutableAttributedString alloc] initWithString:input]; + + if (input.length > self.maxNumberLength) { + return result; + } + + for (NSNumber *indexNumber in self.formatSpaces) { + NSUInteger index = [indexNumber unsignedIntegerValue]; + if (index >= result.length) { + break; + } + [result setAttributes:@{NSKernAttributeName: @(kerning)} range:NSMakeRange(index-1, 1)]; + } + return result; +} + +- (NSAttributedString *)formatNumber:(NSString *)input { + return [self formatNumber:input kerning:8.0f]; +} + +#pragma mark - Validation + +- (BOOL)validAndNecessarilyCompleteNumber:(NSString *)number { + return (number.length == self.validNumberLengths.lastIndex && + ([BTUIUtil luhnValid:number] || [self.brand isEqualToString:BTUILocalizedString(CARD_TYPE_UNION_PAY)])); +} + +- (BOOL)validNumber:(NSString *)number { + return ([self completeNumber:number] && + ([BTUIUtil luhnValid:number] || [self.brand isEqualToString:BTUILocalizedString(CARD_TYPE_UNION_PAY)])); +} + +- (BOOL)completeNumber:(NSString *)number { + return [self.validNumberLengths containsIndex:number.length]; +} + + + +@end diff --git a/Pods/Braintree/BraintreeUI/Models/BTUIUtil.h b/Pods/Braintree/BraintreeUI/Models/BTUIUtil.h new file mode 100644 index 0000000..a71c3ea --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Models/BTUIUtil.h @@ -0,0 +1,18 @@ +#import + +@interface BTUIUtil : NSObject + ++ (BOOL)luhnValid:(NSString *)cardNumber; + +/** + @brief Strips non-digit characters from a string. + + @param input The string to strip. + + @return The string stripped of non-digit characters, or `nil` if `input` is `nil` +*/ ++ (NSString *)stripNonDigits:(NSString *)input; + ++ (NSString *)stripNonExpiry:(NSString *)input; + +@end diff --git a/Pods/Braintree/BraintreeUI/Models/BTUIUtil.m b/Pods/Braintree/BraintreeUI/Models/BTUIUtil.m new file mode 100644 index 0000000..7fe51c7 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Models/BTUIUtil.m @@ -0,0 +1,48 @@ +#import "BTUIUtil.h" + +@implementation BTUIUtil + +#pragma mark - Class Method Utils + ++ (BOOL)luhnValid:(NSString *)cardNumber { + // http://rosettacode.org/wiki/Luhn_test_of_credit_card_numbers#Objective-C + const char *digitChars = [cardNumber UTF8String]; + BOOL isOdd = YES; + NSInteger oddSum = 0; + NSInteger evenSum = 0; + for (NSInteger i = [cardNumber length] - 1; i >= 0; i--) { + NSInteger digit = digitChars[i] - '0'; + if (isOdd) { + oddSum += digit; + } else { + evenSum += digit/5 + (2*digit) % 10; + } + isOdd = !isOdd; + } + + return ((oddSum + evenSum) % 10 == 0); +} + ++ (NSString *)stripNonDigits:(NSString *)input { + return [self stripPattern:@"[^0-9]" input:input]; +} + ++ (NSString *)stripNonExpiry:(NSString *)input { + return [self stripPattern:@"[^0-9/]" input:input]; +} + ++ (NSString *)stripPattern:(NSString *)pattern input:(NSString *)input { + if (!input) return nil; + + NSError *error; + NSRegularExpression *re = [NSRegularExpression regularExpressionWithPattern:pattern + options:0 + error:&error]; + + return [re stringByReplacingMatchesInString:input + options:0 + range:NSMakeRange(0, input.length) + withTemplate:@""]; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Public/BTDropInViewController.h b/Pods/Braintree/BraintreeUI/Public/BTDropInViewController.h new file mode 100644 index 0000000..6e19dce --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BTDropInViewController.h @@ -0,0 +1,146 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@class BTAPIClient, BTUI, BTPaymentRequest, BTPaymentMethodNonce; +@protocol BTDropInViewControllerDelegate; + +/** + @class BTDropInViewController + @brief A view controller that provides a quick and easy payment experience. + + @discussion When initialized with a Braintree client, the Drop In will prompt a user for payment details, + based on your Gateway configuration. The Drop In payment form supports cards and PayPal. When + using Drop In, you don't need to worry about which methods are already on file with Braintree; + newly created methods are saved as part of the Drop In flow as needed. + + Upon successful form submission, you will receive a payment method nonce, which you can + transact with on your server. Client and validation errors are handled internally by Drop In; + other types of Errors are rare and generally irrecoverable. + + The Drop In view controller delegates presentation and dismissal to the developer. It has been + most thoroughly tested in the context of a UINavigationController. + + The Drop In can send success and cancelation messages to the developer via the + delegate. See `delegate` and `BTDropInViewControllerDelegate`. + + You can customize Drop In in various ways, for example, you can change the primary Call To + Action button text. For visual customzation options see `theme` and `BTUI`. Like any + UIViewController, you can setup properties like `title` or `navigationBar.rightBarButtonItem`. +*/ +@interface BTDropInViewController : UIViewController + +/** + @brief Initialize a new Drop-in view controller. + + @param apiClient A BTAPIClient used for communicating with Braintree servers. Required. + + @return A new Drop-in view controller that is ready to be presented. +*/ +- (instancetype)initWithAPIClient:(BTAPIClient *)apiClient; + +/** + @brief The API Client used for communication with Braintree servers. +*/ +@property (nonatomic, strong) BTAPIClient *apiClient; + +/** + @brief The BTPaymentRequest that defines the Drop-in experience. + + @note The properties of this payment request are used to customize Drop-in. +*/ +@property (nonatomic, strong, nullable) BTPaymentRequest *paymentRequest; + +/** + @brief The array of `BTPaymentMethodNonce` payment method nonces on file. + @discussion The payment method nonces may be in the Vault. + Most payment methods are automatically Vaulted if the client token was generated with a customer ID. +*/ +@property (nonatomic, strong) NSArray *paymentMethodNonces; + +#pragma mark State Change Notifications + +/** + @brief The delegate that, if set, is notified of success or failure. +*/ +@property (nonatomic, weak, nullable) id delegate; + +#pragma mark Customization + +/** + @brief The presentation theme to use for the Drop In. +*/ +@property (nonatomic, strong, nullable) BTUI *theme; + +/** + @brief Fetches the customer's saved payment methods and populates Drop In with them. + + @discussion For the best user experience, you should call this method as early as + possible (after initializing BTDropInViewController, before presenting it) + in order to avoid a loading spinner. + + @param completionBlock A block that gets called on completion. +*/ +- (void)fetchPaymentMethodsOnCompletion:(void(^)(void))completionBlock; + +/** + @brief Sets the card number in the card form. +*/ +- (void)setCardNumber:(nullable NSString *)cardNumber; + +/** + @brief Sets the expiration month and year in the card form. + + @note The expiration date uses the Gregorian calendar. + + @param expirationMonth The expiration month as a one- or two-digit number. + @param expirationYear The expiration year as a four-digit number. +*/ +- (void)setCardExpirationMonth:(NSInteger)expirationMonth year:(NSInteger)expirationYear; + +@end + +/** + @brief A protocol for BTDropInViewController completion notifications. +*/ +@protocol BTDropInViewControllerDelegate + +/** + @brief Informs the delegate when the user has successfully provided payment info that has been successfully tokenized. + + @discussion Upon receiving this message, you should dismiss Drop In. + + @param viewController The Drop In view controller informing its delegate of success + @param paymentMethodNonce The selected (and possibly newly created) tokenized payment information. +*/ +- (void)dropInViewController:(BTDropInViewController *)viewController didSucceedWithTokenization:(BTPaymentMethodNonce *)paymentMethodNonce; + +/** + @brief Informs the delegate when the user has decided to cancel out of the Drop-in payment form. + + @discussion Drop-in handles its own error cases, so this cancelation is user initiated and + irreversable. Upon receiving this message, you should dismiss Drop-in. + + @param viewController The Drop-in view controller informing its delegate of failure or cancelation. +*/ +- (void)dropInViewControllerDidCancel:(BTDropInViewController *)viewController; + +@optional + +/** + @brief Informs the delegate when the Drop-in view controller has finished loading. + + @param viewController The Drop-in view controller informing its delegate +*/ +- (void)dropInViewControllerDidLoad:(BTDropInViewController *)viewController; + +/** + @brief Informs the delegate when the user has entered or selected payment information. + + @param viewController The Drop-in view controller informing its delegate +*/ +- (void)dropInViewControllerWillComplete:(BTDropInViewController *)viewController; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeUI/Public/BTPaymentButton.h b/Pods/Braintree/BraintreeUI/Public/BTPaymentButton.h new file mode 100644 index 0000000..d1db173 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BTPaymentButton.h @@ -0,0 +1,84 @@ +#import "BTPaymentRequest.h" +#import "BTUIThemedView.h" +#import + +@protocol BTAppSwitchDelegate, BTViewControllerPresentingDelegate; +@class BTAPIClient, BTPaymentMethodNonce; + +NS_ASSUME_NONNULL_BEGIN + +@interface BTPaymentButton : BTUIThemedView + +/** + @brief Initialize a BTPaymentButton. + + @param apiClient A `BTAPIClient` used for communicating with Braintree servers. Required. + @param completion A completion block. Required. + + @return A new BTPaymentButton. +*/ +- (instancetype)initWithAPIClient:(BTAPIClient *)apiClient + completion:(void(^)(BTPaymentMethodNonce * _Nullable paymentMethodNonce, NSError * _Nullable error))completion; + +/** + @brief The `BTAPIClient` used for communicating with Braintree servers. + + @discussion This property is exposed to enable the use of other UIView initializers, e.g. + when using Storyboards. +*/ +@property (nonatomic, strong, nullable) BTAPIClient *apiClient; + +/** + @brief The `BTPaymentRequest` that customizes the payment experience. +*/ +@property (nonatomic, strong, nullable) BTPaymentRequest *paymentRequest; + +/** + @brief The completion block to handle the result of a payment authorization flow. + + @discussion This property is exposed to enable the use of other `UIView` initializers, e.g. + when using Storyboards. +*/ +@property (nonatomic, copy) void(^completion)(BTPaymentMethodNonce * _Nullable paymentMethodNonce, NSError * _Nullable error); + +/** + @brief Set of payment options as strings. + @discussion e.g. `@"PayPal"`, `@"Venmo"`. By default, this is configured + to the set of payment options that have been included in the client-side app integration, + e.g. via frameworks. + + Setting this property will force the button to reload and display the specified payment options, + even if the payment option is disabled in the Control Panel. +*/ +@property (nonatomic, strong) NSOrderedSet *enabledPaymentOptions; + +/** + @brief The configuration from a `BTAPIClient`. + @discussion This is automatically fetched when the payment button + is initialized with a `BTAPIClient`, but it can be `nil` if the `BTAPIClient` has not yet been + set or if the configuration fetch fails. + + Setting this property will force the button to reload using the new configuration. +*/ +@property (nonatomic, strong, nullable) BTConfiguration *configuration; + +/** + @brief Optional delegate for receiving payment lifecycle messages from a payment option that may initiate an app or browser switch to authorize payments. +*/ +@property (nonatomic, weak, nullable) id appSwitchDelegate; + +/** + @brief Optional delegate for receiving payment lifecycle messages from a payment driverthat requires presentation of a view controller to authorize a payment. + + @note Required by PayPal. +*/ +@property (nonatomic, weak, nullable) id viewControllerPresentingDelegate; + +/** + @brief Indicates whether any payment options available. +*/ +@property (nonatomic, readonly) BOOL hasAvailablePaymentMethod; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeUI/Public/BTPaymentRequest.h b/Pods/Braintree/BraintreeUI/Public/BTPaymentRequest.h new file mode 100644 index 0000000..6954e7e --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BTPaymentRequest.h @@ -0,0 +1,112 @@ +#import +#if __has_include("BraintreeCore.h") +#import "BTPostalAddress.h" +#else +#import +#endif + +@class BTAPIClient; + +NS_ASSUME_NONNULL_BEGIN + +@interface BTPaymentRequest : NSObject + +/** + @brief Primary text to display in the summary view. + + @discussion Intended to provide a name the overall transaction taking place. For example, "1 Item", "1 Year Subscription", "Yellow T-Shirt", etc. + + If summaryTitle or summaryDescription are nil, then the summary view is not shown. +*/ +@property (nonatomic, copy, nullable) NSString *summaryTitle; + +/** + @brief Detail text to display in the summary view. + + @discussion Intended to provide a few words of detail. For example, "Ships in Five Days", "15 feet by 12 feet" or "We know you'll love it" + + If summaryTitle or summaryDescription are nil, then the summary view is not shown. +*/ +@property (nonatomic, copy, nullable) NSString *summaryDescription; + +/** + @brief A string representation of the grand total amount + + @note For example, "$12.95" +*/ +@property (nonatomic, copy) NSString *displayAmount; + +/** + @brief The text to display in the primary call-to-action button. For example: "$19 - Purchase" or "Subscribe Now". +*/ +@property (nonatomic, copy) NSString *callToActionText; + +/** + @brief Whether to hide the call to action control in Drop-in's content view. + + @discussion When `YES`, the call to action control in Drop-in's content view will be hidden; + instead, a submit button will be added as a bar button item, which relies on the + Drop-in view controller being embedded in a navigation controller. + + Defaults to `NO`, so that the call to action control will be shown within Drop-in's + content view. + + @see callToAction + @see callToActionAmount +*/ +@property (nonatomic, assign) BOOL shouldHideCallToAction; + +/** + @brief Optional: Amount of the transaction. + + @discussion Amount must be a non-negative number, may optionally contain exactly 2 decimal places + separated by '.', optional thousands separator ',', limited to 7 digits before the decimal point. + + @note Used by PayPal. +*/ +@property (nonatomic, copy, nullable) NSString *amount; + +/** + @brief Optional: A valid ISO currency code to use for the transaction. Defaults to merchant currency code if not set. + + @note Used by PayPal. +*/ +@property (nonatomic, copy, nullable) NSString *currencyCode; + +/** + @brief Defaults to false. When set to true, the shipping address selector will not be displayed. + + @note Used by PayPal. +*/ +@property (nonatomic, assign) BOOL noShipping; + +/** + @brief When set to `YES`, this controls whether to present additional modal view controllers from the root view controller of the application's key window. Defaults to `NO`. + + @note Setting this to `YES` can fix issues with blank `SFSafariViewControllers`, which can occur when apps use multiple `UIWindow` instances. +*/ +@property (nonatomic, assign) BOOL presentViewControllersFromTop; + +/** + @brief Show a customer's vaulted payment methods with the default payment method nonce first, followed by the remaining payment methods sorted by most recent usage. Defaults to `NO`. + + @note Must be using client token with a customer ID +*/ +@property (nonatomic, assign) BOOL showDefaultPaymentMethodNonceFirst; + +/** + @brief Optional: A valid shipping address to be displayed in the transaction flow. + @discussion An error will occur if this address is not valid. + + @note Used by PayPal. +*/ +@property (nonatomic, strong, nullable) BTPostalAddress *shippingAddress; + +/** + @brief Optional: A set of PayPal scopes to use when requesting payment via PayPal. Used by Drop-in and payment button. +*/ +@property (nonatomic, strong, nullable) NSSet *additionalPayPalScopes; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeUI/Public/BTUI.h b/Pods/Braintree/BraintreeUI/Public/BTUI.h new file mode 100644 index 0000000..464cbfb --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BTUI.h @@ -0,0 +1,110 @@ +#import + +#import "BTUIPaymentOptionType.h" +#import "BTUIVectorArtView.h" + +/** + @brief BTUI represents a visual theme and can be applied to any `BTUIThemedView`. +*/ +@interface BTUI : NSObject + +/** + @brief Returns a default Braintree theme. + + @return the default Braintree theme. +*/ ++ (BTUI *)braintreeTheme; + +#pragma mark - Palette + +- (UIColor *)idealGray; + +#pragma mark - Colors + +/** + @brief Tint color if none is set. Defaults to nil. +*/ +- (UIColor *)defaultTintColor; + +- (UIColor *)viewBackgroundColor; +- (UIColor *)callToActionColor; +- (UIColor *)callToActionColorHighlighted; +- (UIColor *)disabledButtonColor; + +- (UIColor *)titleColor; +- (UIColor *)detailColor; +- (UIColor *)borderColor; + +- (UIColor *)textFieldTextColor; +- (UIColor *)textFieldPlaceholderColor; + +- (UIColor *)sectionHeaderTextColor; +- (UIColor *)textFieldFloatLabelTextColor; + +- (UIColor *)cardHintBorderColor; + +- (UIColor *)errorBackgroundColor; +- (UIColor *)errorForegroundColor; + +#pragma mark Adjustments + +- (CGFloat) highlightedBrightnessAdjustment; + +#pragma mark PayPal Colors + +- (UIColor *)payBlue; +- (UIColor *)palBlue; +- (UIColor *)payPalButtonBlue; +- (UIColor *)payPalButtonActiveBlue; + +#pragma mark Venmo Color + +- (UIColor *)venmoPrimaryBlue; + +#pragma mark Coinbase Color + +- (UIColor *)coinbasePrimaryBlue; + +#pragma mark Typography + +- (UIFont *)controlFont; +- (UIFont *)controlTitleFont; +- (UIFont *)controlDetailFont; +- (UIFont *)textFieldFont; +- (UIFont *)textFieldFloatLabelFont; +- (UIFont *)sectionHeaderFont; + +#pragma mark Attributes + +- (NSDictionary *)textFieldTextAttributes; +- (NSDictionary *)textFieldPlaceholderAttributes; + +#pragma mark Visuals + +- (CGFloat)borderWidth; +- (CGFloat)cornerRadius; +- (CGFloat)formattedEntryKerning; +- (CGFloat)horizontalMargin; +- (CGFloat)paymentButtonMinHeight; +- (CGFloat)paymentButtonMaxHeight; +- (CGFloat)paymentButtonWordMarkHeight DEPRECATED_ATTRIBUTE; + +#pragma mark Transitions + +- (CGFloat)quickTransitionDuration; +- (CGFloat)transitionDuration; +- (CGFloat)minimumVisibilityTime; + + + +#pragma mark Icons + +- (BTUIVectorArtView *)vectorArtViewForPaymentInfoType:(NSString *)typeString; +- (BTUIVectorArtView *)vectorArtViewForPaymentOptionType:(BTUIPaymentOptionType)type; + +#pragma mark Utilities + ++ (BTUIPaymentOptionType)paymentOptionTypeForPaymentInfoType:(NSString *)typeString; ++ (UIActivityIndicatorViewStyle)activityIndicatorViewStyleForBarTintColor:(UIColor *)color; + +@end diff --git a/Pods/Braintree/BraintreeUI/Public/BTUICTAControl.h b/Pods/Braintree/BraintreeUI/Public/BTUICTAControl.h new file mode 100644 index 0000000..4c5f24e --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BTUICTAControl.h @@ -0,0 +1,31 @@ +#import + +@class BTUI; + +NS_ASSUME_NONNULL_BEGIN + +/** + @class BTUICTAControl + @discussion The Call To Action control is a button that is intended to be used as the submit button + on the bottom of a payment form. As a UIControl subclass, typical target-action event + listeners are available. +*/ +@interface BTUICTAControl : UIControl + +/** + @brief The amount, including a currency symbol, to be displayed. +*/ +@property (nonatomic, copy, nullable) NSString *displayAmount; + +/** + @brief The call to action verb, such as "Subscribe" or "Buy". +*/ +@property (nonatomic, copy) NSString *callToAction; + +- (void)showLoadingState:(BOOL)loadingState; + +@property (nonatomic, strong) BTUI *theme; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/Braintree/BraintreeUI/Public/BTUICardFormView.h b/Pods/Braintree/BraintreeUI/Public/BTUICardFormView.h new file mode 100644 index 0000000..7e51c67 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BTUICardFormView.h @@ -0,0 +1,130 @@ +#import "BTUIThemedView.h" + +typedef NS_OPTIONS(NSUInteger, BTUICardFormOptionalFields) { + BTUICardFormOptionalFieldsNone = 0, + BTUICardFormOptionalFieldsCvv = 1 << 0, + BTUICardFormOptionalFieldsPostalCode = 1 << 1, + BTUICardFormOptionalFieldsPhoneNumber= 1 << 2, + BTUICardFormOptionalFieldsAll = BTUICardFormOptionalFieldsCvv | BTUICardFormOptionalFieldsPostalCode | BTUICardFormOptionalFieldsPhoneNumber +}; + +typedef NS_ENUM(NSUInteger, BTUICardFormField) { + BTUICardFormFieldNumber = 0, + BTUICardFormFieldExpiration, + BTUICardFormFieldCvv, + BTUICardFormFieldPostalCode, + BTUICardFormFieldPhoneNumber, +}; + +@protocol BTUICardFormViewDelegate; + +@interface BTUICardFormView : BTUIThemedView + +@property (nonatomic, weak) IBOutlet id delegate; + +@property (nonatomic, assign, readonly) BOOL valid; + +/** + @brief The card number. + + @discussion If you set a card number longer than is allowed by the card type, + it will not be set. +*/ +@property (nonatomic, copy) NSString *number; + +/** + @brief The card CVV + + @note this field is only visible when specified in `optionalFields` +*/ +@property (nonatomic, copy) NSString *cvv; + +/** + @brief The card billing address postal code for AVS verifications + + @note this field is only visible when specified in `optionalFields` +*/ +@property (nonatomic, copy) NSString *postalCode; + +/** + @brief The card expiration month +*/ +@property (nonatomic, copy, readonly) NSString *expirationMonth; + +/** + @brief The card expiration year +*/ +@property (nonatomic, copy, readonly) NSString *expirationYear; + +/** + @brief A phone number +*/ +@property (nonatomic, copy, readonly) NSString *phoneNumber; + +/** + @brief Sets the card form view's expiration date + + @param expirationDate The expiration date. Passing in `nil` will clear the + card form's expiry field. +*/ +- (void)setExpirationDate:(NSDate *)expirationDate; + +/** + @brief Sets the card form view's expiration date + + @param expirationMonth The expiration month + @param expirationYear The expiration year. Two-digit years are assumed to be 20xx. +*/ +- (void)setExpirationMonth:(NSInteger)expirationMonth year:(NSInteger)expirationYear; + +/** + @brief Immediately present a top level error message to the user. + + @param message The error message to present +*/ +- (void)showTopLevelError:(NSString *)message; + +/** + @brief Immediately present a field-level error to the user. + + @note We do not support field-level error descriptions. This method highlights the field to indicate invalidity. + @param field The invalid field +*/ +- (void)showErrorForField:(BTUICardFormField)field; + +/** + @brief Configure whether to support complete alphanumeric postal codes. Defaults to YES + @note If NO, allows only digit entry. +*/ +@property (nonatomic, assign) BOOL alphaNumericPostalCode; + +/** + @brief Which fields should be included. Defaults to BTUICardFormOptionalFieldsAll +*/ +@property (nonatomic, assign) BTUICardFormOptionalFields optionalFields; + +/** + @brief Whether to provide feedback to the user via vibration. Defaults to YES +*/ +@property (nonatomic, assign) BOOL vibrate; + + +@end + +/** + @brief Delegate protocol for receiving updates about the card form +*/ +@protocol BTUICardFormViewDelegate + +@optional + +/** + @brief The card form data has updated. +*/ +- (void)cardFormViewDidChange:(BTUICardFormView *)cardFormView; + +- (void)cardFormViewDidBeginEditing:(BTUICardFormView *)cardFormView; + +- (void)cardFormViewDidEndEditing:(BTUICardFormView *)cardFormView; + +@end diff --git a/Pods/Braintree/BraintreeUI/Public/BTUICardHint.h b/Pods/Braintree/BraintreeUI/Public/BTUICardHint.h new file mode 100644 index 0000000..0c4e04b --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BTUICardHint.h @@ -0,0 +1,54 @@ +#import +#import "BTUIPaymentOptionType.h" +#import "BTUIThemedView.h" + +/** + @brief `BTCardHint` has two display modes: one emphasizes the card type, and the second emphasizes the CVV location. +*/ +typedef NS_ENUM(NSInteger, BTCardHintDisplayMode) { + /// Emphasize the card's type. + BTCardHintDisplayModeCardType, + /// Emphasize the CVV's location. + BTCardHintDisplayModeCVVHint, +}; + +/** + @class BTUICardHint + @discussion A View that displays a card icon in order to provide users with a hint as to what card type + has been detected or where the CVV can be found on that card. +*/ +@interface BTUICardHint : BTUIThemedView + +/** + @brief The card type to display. +*/ +@property (nonatomic, assign) BTUIPaymentOptionType cardType; + +/** + @brief Whether to emphasize the card type or the CVV. +*/ +@property (nonatomic, assign) BTCardHintDisplayMode displayMode; + +/** + @brief Whether it is highlighted with the tint color +*/ +@property (nonatomic, assign) BOOL highlighted; + +/** + @brief Set highlight with animation +*/ +- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated; + +/** + @brief Update the current cardType with an optional visual animation + @see cardType +*/ +- (void)setCardType:(BTUIPaymentOptionType)cardType animated:(BOOL)animated; + +/** + @brief Update the current displayMode with an optional visual animation + @see displayMode +*/ +- (void)setDisplayMode:(BTCardHintDisplayMode)displayMode animated:(BOOL)animated; + +@end diff --git a/Pods/Braintree/BraintreeUI/Public/BTUICoinbaseButton.h b/Pods/Braintree/BraintreeUI/Public/BTUICoinbaseButton.h new file mode 100644 index 0000000..a933787 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BTUICoinbaseButton.h @@ -0,0 +1,9 @@ +#import + +@class BTUI; + +@interface BTUICoinbaseButton : UIControl + +@property (nonatomic, strong) BTUI *theme; + +@end diff --git a/Pods/Braintree/BraintreeUI/Public/BTUIPayPalButton.h b/Pods/Braintree/BraintreeUI/Public/BTUIPayPalButton.h new file mode 100644 index 0000000..45ac489 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BTUIPayPalButton.h @@ -0,0 +1,11 @@ +#import + +@class BTUI, BTUIPayPalWordmarkVectorArtView; + +@interface BTUIPayPalButton : UIControl + +@property (nonatomic, strong) BTUI *theme; + +@property (nonatomic, strong) BTUIPayPalWordmarkVectorArtView *payPalWordmark; + +@end diff --git a/Pods/Braintree/BraintreeUI/Public/BTUIPaymentMethodView.h b/Pods/Braintree/BraintreeUI/Public/BTUIPaymentMethodView.h new file mode 100644 index 0000000..9aee3f5 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BTUIPaymentMethodView.h @@ -0,0 +1,26 @@ +#import "BTUIPaymentOptionType.h" +#import "BTUIThemedView.h" +#import + +/** + @brief A view that indicates the currently selected payment method, be it a credit card or a PayPal account. +*/ +@interface BTUIPaymentMethodView : BTUIThemedView + +/** + @brief The type of payment method to display. + */ +@property (nonatomic, assign) BTUIPaymentOptionType type; + +/** + @brief An optional string description of the payment method. + @discussion For example, you could say "ending in 02" for a credit card. + */ +@property (nonatomic, copy) NSString *detailDescription; + +/** + @brief When true, all content is hidden and a loading spinner is displayed. + */ +@property (nonatomic, assign, getter = isProcessing) BOOL processing; + +@end diff --git a/Pods/Braintree/BraintreeUI/Public/BTUIPaymentOptionType.h b/Pods/Braintree/BraintreeUI/Public/BTUIPaymentOptionType.h new file mode 100644 index 0000000..6331635 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BTUIPaymentOptionType.h @@ -0,0 +1,21 @@ +/** + @brief Credit card types +*/ +typedef NS_ENUM(NSInteger, BTUIPaymentOptionType) { + BTUIPaymentOptionTypeUnknown = 0, + BTUIPaymentOptionTypeAMEX, + BTUIPaymentOptionTypeDinersClub, + BTUIPaymentOptionTypeDiscover, + BTUIPaymentOptionTypeMasterCard, + BTUIPaymentOptionTypeVisa, + BTUIPaymentOptionTypeJCB, + BTUIPaymentOptionTypeLaser, + BTUIPaymentOptionTypeMaestro, + BTUIPaymentOptionTypeUnionPay, + BTUIPaymentOptionTypeSolo, + BTUIPaymentOptionTypeSwitch, + BTUIPaymentOptionTypeUKMaestro, + BTUIPaymentOptionTypePayPal, + BTUIPaymentOptionTypeCoinbase, + BTUIPaymentOptionTypeVenmo, +}; diff --git a/Pods/Braintree/BraintreeUI/Public/BTUISummaryView.h b/Pods/Braintree/BraintreeUI/Public/BTUISummaryView.h new file mode 100644 index 0000000..bdc0047 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BTUISummaryView.h @@ -0,0 +1,24 @@ +#import +#import "BTUIThemedView.h" + +/** + @brief Informational view that displays a summary of the shopping cart or other relevant data for checkout experience that user is agreing too. +*/ + @interface BTUISummaryView : BTUIThemedView + +/** + @brief The text to display as the primary description of the purchase. +*/ +@property (nonatomic, copy) NSString *slug; + +/** + @brief The text to display as the secondary summary of the purchase. +*/ +@property (nonatomic, copy) NSString *summary; + +/** + @brief The textual representation of the dollar amount for the purchase including the currency symbol +*/ +@property (nonatomic, copy) NSString *amount; + +@end diff --git a/Pods/Braintree/BraintreeUI/Public/BTUIThemedView.h b/Pods/Braintree/BraintreeUI/Public/BTUIThemedView.h new file mode 100644 index 0000000..9498186 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BTUIThemedView.h @@ -0,0 +1,6 @@ +#import +#import "BTUI.h" + +@interface BTUIThemedView : UIView +@property (nonatomic, strong) BTUI *theme; +@end diff --git a/Pods/Braintree/BraintreeUI/Public/BTUIVectorArtView.h b/Pods/Braintree/BraintreeUI/Public/BTUIVectorArtView.h new file mode 100644 index 0000000..0d024cc --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BTUIVectorArtView.h @@ -0,0 +1,23 @@ +#import + +/** + @class BTUIVectorArtView + @brief Subclassed to easily draw vector art into a scaled UIView. + @discussion Useful for using generated UIBezierPath code from + [PaintCode](http://www.paintcodeapp.com/) verbatim. +*/ +@interface BTUIVectorArtView : UIView + +/** + @brief Subclass and implement this method to draw within a context pre-scaled to the view's size. +*/ +- (void)drawArt; + +/** + @brief This property informs the BTVectorArtView drawRect method of the dimensions of the artwork. +*/ +@property (nonatomic, assign) CGSize artDimensions; + +- (UIImage *)imageOfSize:(CGSize)size; + +@end diff --git a/Pods/Braintree/BraintreeUI/Public/BTUIVenmoButton.h b/Pods/Braintree/BraintreeUI/Public/BTUIVenmoButton.h new file mode 100644 index 0000000..515bd4b --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BTUIVenmoButton.h @@ -0,0 +1,9 @@ +#import + +@class BTUI; + +@interface BTUIVenmoButton : UIControl + +@property (nonatomic, strong) BTUI *theme; + +@end diff --git a/Pods/Braintree/BraintreeUI/Public/BraintreeUI.h b/Pods/Braintree/BraintreeUI/Public/BraintreeUI.h new file mode 100644 index 0000000..9cc1673 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/BraintreeUI.h @@ -0,0 +1,25 @@ +#import + +//! Project version number for BraintreeUI. +FOUNDATION_EXPORT double BraintreeUIVersionNumber; + +//! Project version string for BraintreeUI. +FOUNDATION_EXPORT const unsigned char BraintreeUIVersionString[]; + +#if __has_include("BraintreeCore.h") +#import "BraintreeCore.h" +#else +#import +#endif +#import "BTDropInViewController.h" +#import "BTPaymentButton.h" +#import "BTPaymentRequest.h" +#import "BTUICardFormView.h" +#import "BTUICardHint.h" +#import "BTUICoinbaseButton.h" +#import "BTUICTAControl.h" +#import "BTUIPaymentMethodView.h" +#import "BTUIPayPalButton.h" +#import "BTUISummaryView.h" +#import "BTUIVenmoButton.h" +#import "UIColor+BTUI.h" diff --git a/Pods/Braintree/BraintreeUI/Public/UIColor+BTUI.h b/Pods/Braintree/BraintreeUI/Public/UIColor+BTUI.h new file mode 100644 index 0000000..427fb6e --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Public/UIColor+BTUI.h @@ -0,0 +1,11 @@ +#import + +@interface UIColor (BTUI) + ++ (instancetype)bt_colorWithBytesR:(NSInteger)r G:(NSInteger)g B:(NSInteger)b A:(NSInteger)a; ++ (instancetype)bt_colorWithBytesR:(NSInteger)r G:(NSInteger)g B:(NSInteger)b; ++ (instancetype)bt_colorFromHex:(NSString *)hex alpha:(CGFloat)alpha; + +- (instancetype)bt_adjustedBrightness:(CGFloat)adjustment; + +@end diff --git a/Pods/Braintree/BraintreeUI/Theme/BTUI.m b/Pods/Braintree/BraintreeUI/Theme/BTUI.m new file mode 100644 index 0000000..940a940 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Theme/BTUI.m @@ -0,0 +1,300 @@ +#import "BTUI.h" +#import "BTUIUtil.h" +#import "UIColor+BTUI.h" + +#import "BTUIMasterCardVectorArtView.h" +#import "BTUIJCBVectorArtView.h" +#import "BTUIMaestroVectorArtView.h" +#import "BTUIVisaVectorArtView.h" +#import "BTUIDiscoverVectorArtView.h" +#import "BTUIUnknownCardVectorArtView.h" +#import "BTUIDinersClubVectorArtView.h" +#import "BTUIAmExVectorArtView.h" +#import "BTUIPayPalMonogramCardView.h" +#import "BTUICoinbaseMonogramCardView.h" +#import "BTUIVenmoMonogramCardView.h" +#import "BTUIUnionPayVectorArtView.h" + +@implementation BTUI + ++ (BTUI *)braintreeTheme { + static BTUI *_sharedBraintreeTheme; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _sharedBraintreeTheme = [[BTUI alloc] init]; + }); + return _sharedBraintreeTheme; +} + +- (UIColor *)idealGray { + return [UIColor bt_colorWithBytesR:128 G:128 B:128]; +} + +- (UIColor *)viewBackgroundColor { + return [UIColor bt_colorFromHex:@"f3f4f6" alpha:1.0f]; +} + +- (UIColor *)callToActionColor { + return [UIColor bt_colorWithBytesR:7 G:158 B:222]; +} + +- (UIColor *)callToActionColorHighlighted { + return [UIColor colorWithRed:0.375 green:0.635 blue:0.984 alpha:1.000]; +} + +- (UIColor *)disabledButtonColor { + return [UIColor bt_colorFromHex:@"#BCBFC4" alpha:1.0f]; +} + +- (UIColor *)titleColor { + return [UIColor bt_colorWithBytesR:46 G:51 B:58]; +} + +- (UIColor *)detailColor { + return [UIColor bt_colorWithBytesR:98 G:102 B:105]; +} + +- (UIColor *)borderColor { + return [UIColor bt_colorWithBytesR:216 G:216 B:216]; +} + +- (UIColor *)textFieldTextColor { + return [UIColor bt_colorWithBytesR:26 G:26 B:26]; +} + +- (UIColor *)textFieldPlaceholderColor { + return [self idealGray]; +} + +- (UIColor *)sectionHeaderTextColor { + return [self idealGray]; +} + +- (UIColor *)textFieldFloatLabelTextColor { + return [self sectionHeaderTextColor]; +} + +- (UIColor *)defaultTintColor { + return [self palBlue]; +} + +- (UIColor *)cardHintBorderColor { + return [UIColor bt_colorWithBytesR:0 G:0 B:0 A:20]; +} + +- (UIColor *)errorBackgroundColor { + return [UIColor bt_colorWithBytesR:250 G:229 B:232]; +} + +- (UIColor *)errorForegroundColor { + return [UIColor bt_colorWithBytesR:208 G:2 B:27]; +} + +#pragma mark PayPal Colors + +- (UIColor *)payBlue { + return [UIColor bt_colorFromHex:@"003087" alpha:1.0f]; +} + +- (UIColor *)palBlue { + return [UIColor bt_colorFromHex:@"009CDE" alpha:1.0f]; +} + +- (UIColor *)payPalButtonBlue { + return [UIColor bt_colorWithBytesR:12 G:141 B:196]; +} + +- (UIColor *)payPalButtonActiveBlue { + return [UIColor bt_colorWithBytesR:1 G:156 B:222]; +} + +#pragma mark Venmo Color + +- (UIColor *)venmoPrimaryBlue { + return [UIColor bt_colorFromHex:@"3D95CE" alpha:1.0f]; +} + +#pragma mark Coinbase Color + +- (UIColor *)coinbasePrimaryBlue { + return [UIColor colorWithRed: 0.053 green: 0.433 blue: 0.7 alpha: 1]; +} + +#pragma mark Adjustments + +- (CGFloat)highlightedBrightnessAdjustment { + return 0.6; +} + +#pragma mark - Appearance + +- (CGFloat)cornerRadius { + return 4.0f; +} + +- (CGFloat)borderWidth { + CGFloat screenScale = [UIScreen mainScreen].scale; + return 1 / screenScale; +} + +- (CGFloat)formattedEntryKerning { + return 8.0f; +} + +- (CGFloat)horizontalMargin { + return 17.0f; +} + +- (CGFloat)paymentButtonMinHeight { + return 44.0f; +} + +- (CGFloat)paymentButtonMaxHeight { + return 60.0f; +} + +- (CGFloat)paymentButtonWordMarkHeight { + return 18.0f; +} + + +#pragma mark - Type + +- (UIFont *)controlFont { + return [UIFont fontWithName:@"HelveticaNeue-Light" size:14.0f]; +} + +- (UIFont *)controlTitleFont { + return [UIFont fontWithName:@"HelveticaNeue-Bold" size:17.0f]; +} + +- (UIFont *)controlDetailFont { + return [UIFont fontWithName:@"HelveticaNeue" size:17.0f]; +} + +- (UIFont *)textFieldFont { + return [UIFont fontWithName:@"HelveticaNeue" size:17.0f]; +} + +- (UIFont *)textFieldFloatLabelFont { + return [UIFont fontWithName:@"HelveticaNeue" size:12.0f]; +} + +- (UIFont *)sectionHeaderFont { + return [UIFont fontWithName:@"HelveticaNeue" size:14.0f]; +} + +#pragma mark - String Attributes + +- (NSDictionary *)textFieldTextAttributes { + return @{NSFontAttributeName: self.textFieldFont, + NSForegroundColorAttributeName: self.textFieldTextColor}; +} + +- (NSDictionary *)textFieldPlaceholderAttributes { + return @{NSFontAttributeName: self.textFieldFont, + NSForegroundColorAttributeName: self.textFieldPlaceholderColor}; +} + +#pragma mark Transitions + +- (CGFloat)quickTransitionDuration { + return 0.1f; +} + +- (CGFloat)transitionDuration { + return 0.2f; +} + +- (CGFloat)minimumVisibilityTime { + return 0.5f; +} + +#pragma mark Icons + ++ (BTUIPaymentOptionType)paymentOptionTypeForPaymentInfoType:(NSString *)typeString { + if ([typeString isEqualToString:@"Visa"]) { + return BTUIPaymentOptionTypeVisa; + } else if ([typeString isEqualToString:@"MasterCard"]) { + return BTUIPaymentOptionTypeMasterCard; + } else if ([typeString isEqualToString:@"Coinbase"]) { + return BTUIPaymentOptionTypeCoinbase; + } else if ([typeString isEqualToString:@"PayPal"]) { + return BTUIPaymentOptionTypePayPal; + } else if ([typeString isEqualToString:@"DinersClub"]) { + return BTUIPaymentOptionTypeDinersClub; + } else if ([typeString isEqualToString:@"JCB"]) { + return BTUIPaymentOptionTypeJCB; + } else if ([typeString isEqualToString:@"Maestro"]) { + return BTUIPaymentOptionTypeMaestro; + } else if ([typeString isEqualToString:@"Discover"]) { + return BTUIPaymentOptionTypeDiscover; + } else if ([typeString isEqualToString:@"UKMaestro"]) { + return BTUIPaymentOptionTypeUKMaestro; + } else if ([typeString isEqualToString:@"AMEX"]) { + return BTUIPaymentOptionTypeAMEX; + } else if ([typeString isEqualToString:@"Solo"]) { + return BTUIPaymentOptionTypeSolo; + } else if ([typeString isEqualToString:@"Laser"]) { + return BTUIPaymentOptionTypeLaser; + } else if ([typeString isEqualToString:@"Switch"]) { + return BTUIPaymentOptionTypeSwitch; + } else if ([typeString isEqualToString:@"UnionPay"]) { + return BTUIPaymentOptionTypeUnionPay; + } else if ([typeString isEqualToString:@"Venmo"]) { + return BTUIPaymentOptionTypeVenmo; + } else { + return BTUIPaymentOptionTypeUnknown; + } +} + +- (BTUIVectorArtView *)vectorArtViewForPaymentInfoType:(NSString *)typeString { + return [self vectorArtViewForPaymentOptionType:[BTUI paymentOptionTypeForPaymentInfoType:typeString]]; +} + +- (BTUIVectorArtView *)vectorArtViewForPaymentOptionType:(BTUIPaymentOptionType)type { + switch (type) { + case BTUIPaymentOptionTypeVisa: + return [BTUIVisaVectorArtView new]; + case BTUIPaymentOptionTypeMasterCard: + return [BTUIMasterCardVectorArtView new]; + case BTUIPaymentOptionTypeCoinbase: + return [BTUICoinbaseMonogramCardView new]; + case BTUIPaymentOptionTypePayPal: + return [BTUIPayPalMonogramCardView new]; + case BTUIPaymentOptionTypeDinersClub: + return [BTUIDinersClubVectorArtView new]; + case BTUIPaymentOptionTypeJCB: + return [BTUIJCBVectorArtView new]; + case BTUIPaymentOptionTypeMaestro: + return [BTUIMaestroVectorArtView new]; + case BTUIPaymentOptionTypeDiscover: + return [BTUIDiscoverVectorArtView new]; + case BTUIPaymentOptionTypeUKMaestro: + return [BTUIMaestroVectorArtView new]; + case BTUIPaymentOptionTypeAMEX: + return [BTUIAmExVectorArtView new]; + case BTUIPaymentOptionTypeVenmo: + return [BTUIVenmoMonogramCardView new]; + case BTUIPaymentOptionTypeUnionPay: + return [BTUIUnionPayVectorArtView new]; + case BTUIPaymentOptionTypeSolo: + case BTUIPaymentOptionTypeLaser: + case BTUIPaymentOptionTypeSwitch: + case BTUIPaymentOptionTypeUnknown: + return [BTUIUnknownCardVectorArtView new]; + } +} + +#pragma mark Utilties + ++ (UIActivityIndicatorViewStyle)activityIndicatorViewStyleForBarTintColor:(UIColor *)color { + CGFloat r, g, b; + [color getRed:&r green:&g blue:&b alpha:NULL]; + CGFloat perceivedBrightnessBasedOnWeightedDistanceIn3DRGBSpace = sqrtf(r * r * .241 + g * g * .691 + b * b * .068); + + return perceivedBrightnessBasedOnWeightedDistanceIn3DRGBSpace > 0.5 ? UIActivityIndicatorViewStyleGray : UIActivityIndicatorViewStyleWhite; +} + +@end + diff --git a/Pods/Braintree/BraintreeUI/Theme/UIColor+BTUI.m b/Pods/Braintree/BraintreeUI/Theme/UIColor+BTUI.m new file mode 100644 index 0000000..df64f4f --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Theme/UIColor+BTUI.m @@ -0,0 +1,34 @@ +#import "UIColor+BTUI.h" + +@implementation UIColor (BTUI) + ++ (instancetype)bt_colorWithBytesR:(NSInteger)r G:(NSInteger)g B:(NSInteger)b A:(NSInteger)a { + return [[self class] colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a/255.0f]; +} + ++ (instancetype)bt_colorWithBytesR:(NSInteger)r G:(NSInteger)g B:(NSInteger)b { + return [[self class] bt_colorWithBytesR:r G:g B:b A:255.0f]; +} + +- (instancetype)bt_adjustedBrightness:(CGFloat)adjustment { + CGFloat h, s, b, a; + if ([self getHue:&h saturation:&s brightness:&b alpha:&a]) { + CGFloat newB = MAX(0.0f, MIN(1.0f, adjustment * b)); + return [[self class] colorWithHue:h saturation:s brightness:newB alpha:a]; + } else { + return nil; + } +} + ++ (instancetype)bt_colorFromHex:(NSString *)hex alpha:(CGFloat)alpha { + uint value = 0; + NSScanner *scanner = [NSScanner scannerWithString:hex]; + [scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"#"]]; + [scanner scanHexInt:&value]; + return [UIColor colorWithRed:((value >> 16) & 255) / 255.0f + green:((value >> 8) & 255) / 255.0f + blue:(value & 255) / 255.0f + alpha:alpha]; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Apple Pay/BTMockApplePayPaymentAuthorizationView.h b/Pods/Braintree/BraintreeUI/Views/Apple Pay/BTMockApplePayPaymentAuthorizationView.h new file mode 100644 index 0000000..6819a66 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Apple Pay/BTMockApplePayPaymentAuthorizationView.h @@ -0,0 +1,16 @@ +#import + +@protocol BTMockApplePayPaymentAuthorizationViewDelegate; + +@interface BTMockApplePayPaymentAuthorizationView : UIView + +- (instancetype)initWithDelegate:(id)delegate; + +@end + +@protocol BTMockApplePayPaymentAuthorizationViewDelegate + +- (void)mockApplePayPaymentAuthorizationViewDidSucceed:(BTMockApplePayPaymentAuthorizationView *)view; +- (void)mockApplePayPaymentAuthorizationViewDidCancel:(BTMockApplePayPaymentAuthorizationView *)view; + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Apple Pay/BTMockApplePayPaymentAuthorizationView.m b/Pods/Braintree/BraintreeUI/Views/Apple Pay/BTMockApplePayPaymentAuthorizationView.m new file mode 100644 index 0000000..badfaa2 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Apple Pay/BTMockApplePayPaymentAuthorizationView.m @@ -0,0 +1,98 @@ +#import "BTMockApplePayPaymentAuthorizationView.h" + +@interface BTMockApplePayPaymentAuthorizationView () +@property (nonatomic, weak) id delegate; +@property (nonatomic, strong) UITableView *tableView; +@end + +NSString *const BTMockApplePayPaymentAuthorizationControlCell = @"BTMockApplePayPaymentAuthorizationControlCell"; + +@implementation BTMockApplePayPaymentAuthorizationView + +- (instancetype)initWithDelegate:(id)delegate { + self = [super init]; + if (self) { + self.delegate = delegate; + + self.tableView = [[UITableView alloc] initWithFrame:self.frame + style:UITableViewStyleGrouped]; + self.tableView.translatesAutoresizingMaskIntoConstraints = NO; + [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:BTMockApplePayPaymentAuthorizationControlCell]; + self.tableView.dataSource = self; + self.tableView.delegate = self; + + [self addSubview:self.tableView]; + + NSDictionary *views = @{ @"tableView": self.tableView }; + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[tableView]|" + options:0 + metrics:nil + views:views]]; + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[tableView]|" + options:0 + metrics:nil + views:views]]; + } + return self; +} + +#pragma mark Table View Data Source + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + NSParameterAssert(indexPath.section == 0); + NSParameterAssert(indexPath.row < 2); + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:BTMockApplePayPaymentAuthorizationControlCell forIndexPath:indexPath]; + + if (!cell) { + cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:BTMockApplePayPaymentAuthorizationControlCell]; + } + + cell.selectionStyle = UITableViewCellSelectionStyleBlue; + + switch (indexPath.row) { + case 0: + cell.textLabel.text = @"💳 Succeed (4111111111111111)"; + break; + case 1: + cell.textLabel.text = @"⛔️ Cancel"; + break; + + default: + break; + } + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + NSParameterAssert(indexPath.section == 0); + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + + switch (indexPath.row) { + case 0: + [self.delegate mockApplePayPaymentAuthorizationViewDidSucceed:self]; + break; + case 1: + [self.delegate mockApplePayPaymentAuthorizationViewDidCancel:self]; + default: + break; + } +} + +- (NSString *)tableView:(__unused UITableView *)tableView titleForHeaderInSection:(__unused NSInteger)section { + NSParameterAssert(section == 0); + + return @"Apple Pay - Mock Mode"; +} + +- (NSInteger)tableView:(__unused UITableView *)tableView numberOfRowsInSection:(__unused NSInteger)section { + NSParameterAssert(section == 0); + return 2; +} + +- (NSInteger)numberOfSectionsInTableView:(__unused UITableView *)tableView { + return 1; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Apple Pay/BTMockApplePayPaymentAuthorizationViewController.h b/Pods/Braintree/BraintreeUI/Views/Apple Pay/BTMockApplePayPaymentAuthorizationViewController.h new file mode 100644 index 0000000..86fd5a6 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Apple Pay/BTMockApplePayPaymentAuthorizationViewController.h @@ -0,0 +1,24 @@ +#import +@import PassKit; + +@protocol BTMockApplePayPaymentAuthorizationViewControllerDelegate; + +@interface BTMockApplePayPaymentAuthorizationViewController : UIViewController + +@property (nonatomic, weak) id delegate; + +- (instancetype)initWithPaymentRequest:(PKPaymentRequest *)request NS_AVAILABLE_IOS(8_0); + ++ (BOOL)canMakePayments; + +@end + +@protocol BTMockApplePayPaymentAuthorizationViewControllerDelegate + +- (void)mockApplePayPaymentAuthorizationViewController:(BTMockApplePayPaymentAuthorizationViewController *)viewController + didAuthorizePayment:(PKPayment *)payment + completion:(void (^)(PKPaymentAuthorizationStatus status))completion NS_AVAILABLE_IOS(8_0); + +- (void)mockApplePayPaymentAuthorizationViewControllerDidFinish:(BTMockApplePayPaymentAuthorizationViewController *)viewController; + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Apple Pay/BTMockApplePayPaymentAuthorizationViewController.m b/Pods/Braintree/BraintreeUI/Views/Apple Pay/BTMockApplePayPaymentAuthorizationViewController.m new file mode 100644 index 0000000..303609f --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Apple Pay/BTMockApplePayPaymentAuthorizationViewController.m @@ -0,0 +1,73 @@ +#import "BTMockApplePayPaymentAuthorizationViewController.h" + +#import "BTMockApplePayPaymentAuthorizationView.h" +#import "BTLogger_Internal.h" + +@interface BTMockApplePayPaymentAuthorizationViewController () + +@end + +@implementation BTMockApplePayPaymentAuthorizationViewController + +- (instancetype)initWithPaymentRequest:(PKPaymentRequest *)request { + self = [super init]; + if (self) { + [[BTLogger sharedLogger] debug:@"Initializing BTMockApplePayPaymentAuthorizationViewController with PKRequest merchantIdentifier: %@; items: %@", request.merchantIdentifier, request.paymentSummaryItems ]; + } + return self; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + BTMockApplePayPaymentAuthorizationView *authorizationView = [[BTMockApplePayPaymentAuthorizationView alloc] initWithDelegate:self]; + authorizationView.translatesAutoresizingMaskIntoConstraints = NO; + + [self.view addSubview:authorizationView]; + + NSDictionary *views = @{ @"authorizationView": authorizationView }; + [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[authorizationView]|" + options:0 + metrics:nil + views:views]]; + [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[authorizationView]|" + options:0 + metrics:nil + views:views]]; +} + ++ (BOOL)canMakePayments { + NSOperatingSystemVersion v; + v.majorVersion = 8; + v.minorVersion = 1; + v.patchVersion = 0; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 8.0, watchOS 2.0, *)) { +#endif + return [[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)] && [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:v]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + } + return NO; +#endif +} + +- (void)cancel:(__unused id)sender { + [self.delegate mockApplePayPaymentAuthorizationViewControllerDidFinish:self]; +} + +#pragma mark Mock Payment Authorization View Delegate + +- (void)mockApplePayPaymentAuthorizationViewDidCancel:(__unused BTMockApplePayPaymentAuthorizationView *)view { + [self.delegate mockApplePayPaymentAuthorizationViewControllerDidFinish:self]; +} + +- (void)mockApplePayPaymentAuthorizationViewDidSucceed:(__unused BTMockApplePayPaymentAuthorizationView *)view NS_AVAILABLE_IOS(8_0) { + [self.delegate mockApplePayPaymentAuthorizationViewController:self + didAuthorizePayment:nil + completion:^(__unused PKPaymentAuthorizationStatus status) { + [self.delegate mockApplePayPaymentAuthorizationViewControllerDidFinish:self]; + }]; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/BTUIViewUtil.h b/Pods/Braintree/BraintreeUI/Views/BTUIViewUtil.h new file mode 100644 index 0000000..2f9cd7e --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/BTUIViewUtil.h @@ -0,0 +1,17 @@ +#import + +#import "BTUICardType.h" +#import "BTUIPaymentOptionType.h" + +/** + @class BTUIViewUtil + @brief Utilities used by other views +*/ +@interface BTUIViewUtil : NSObject + ++ (BTUIPaymentOptionType)paymentMethodTypeForCardType:(BTUICardType *)cardType; ++ (NSString *)nameForPaymentMethodType:(BTUIPaymentOptionType)paymentMethodType; + ++ (void)vibrate; + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/BTUIViewUtil.m b/Pods/Braintree/BraintreeUI/Views/BTUIViewUtil.m new file mode 100644 index 0000000..d554351 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/BTUIViewUtil.m @@ -0,0 +1,76 @@ +#import "BTUIViewUtil.h" +@import AudioToolbox; + +@implementation BTUIViewUtil + ++ (BTUIPaymentOptionType)paymentMethodTypeForCardType:(BTUICardType *)cardType { + + if (cardType == nil) { + return BTUIPaymentOptionTypeUnknown; + } + + if ([cardType.brand isEqualToString:BTUILocalizedString(CARD_TYPE_AMERICAN_EXPRESS)]) { + return BTUIPaymentOptionTypeAMEX; + } else if ([cardType.brand isEqualToString:BTUILocalizedString(CARD_TYPE_VISA)]) { + return BTUIPaymentOptionTypeVisa; + } else if ([cardType.brand isEqualToString:BTUILocalizedString(CARD_TYPE_MASTER_CARD)]) { + return BTUIPaymentOptionTypeMasterCard; + } else if ([cardType.brand isEqualToString:BTUILocalizedString(CARD_TYPE_DISCOVER)]) { + return BTUIPaymentOptionTypeDiscover; + } else if ([cardType.brand isEqualToString:BTUILocalizedString(CARD_TYPE_JCB)]) { + return BTUIPaymentOptionTypeJCB; + } else if ([cardType.brand isEqualToString:BTUILocalizedString(CARD_TYPE_MAESTRO)]) { + return BTUIPaymentOptionTypeMaestro; + } else if ([cardType.brand isEqualToString:BTUILocalizedString(CARD_TYPE_DINERS_CLUB)]) { + return BTUIPaymentOptionTypeDinersClub; + } else if ([cardType.brand isEqualToString:BTUILocalizedString(CARD_TYPE_UNION_PAY)]) { + return BTUIPaymentOptionTypeUnionPay; + } else { + return BTUIPaymentOptionTypeUnknown; + } +} + + ++ (NSString *)nameForPaymentMethodType:(BTUIPaymentOptionType)paymentMethodType { + switch (paymentMethodType) { + case BTUIPaymentOptionTypeUnknown: + return @"Card"; + case BTUIPaymentOptionTypeAMEX: + return BTUILocalizedString(CARD_TYPE_AMERICAN_EXPRESS); + case BTUIPaymentOptionTypeDinersClub: + return BTUILocalizedString(CARD_TYPE_DINERS_CLUB); + case BTUIPaymentOptionTypeDiscover: + return BTUILocalizedString(CARD_TYPE_DISCOVER); + case BTUIPaymentOptionTypeMasterCard: + return BTUILocalizedString(CARD_TYPE_MASTER_CARD); + case BTUIPaymentOptionTypeVisa: + return BTUILocalizedString(CARD_TYPE_VISA); + case BTUIPaymentOptionTypeJCB: + return BTUILocalizedString(CARD_TYPE_JCB); + case BTUIPaymentOptionTypeLaser: + return BTUILocalizedString(CARD_TYPE_LASER); + case BTUIPaymentOptionTypeMaestro: + return BTUILocalizedString(CARD_TYPE_MAESTRO); + case BTUIPaymentOptionTypeUnionPay: + return BTUILocalizedString(CARD_TYPE_UNION_PAY); + case BTUIPaymentOptionTypeSolo: + return BTUILocalizedString(CARD_TYPE_SOLO); + case BTUIPaymentOptionTypeSwitch: + return BTUILocalizedString(CARD_TYPE_SWITCH); + case BTUIPaymentOptionTypeUKMaestro: + return BTUILocalizedString(CARD_TYPE_MAESTRO); + case BTUIPaymentOptionTypePayPal: + return BTUILocalizedString(PAYPAL_CARD_BRAND); + case BTUIPaymentOptionTypeCoinbase: + return BTUILocalizedString(PAYMENT_METHOD_TYPE_COINBASE); + case BTUIPaymentOptionTypeVenmo: + return BTUILocalizedString(PAYMENT_METHOD_TYPE_VENMO); + } + +} + ++ (void)vibrate { + AudioServicesPlayAlertSound(kSystemSoundID_Vibrate); +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIHorizontalButtonStackCollectionViewFlowLayout.h b/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIHorizontalButtonStackCollectionViewFlowLayout.h new file mode 100644 index 0000000..509f3be --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIHorizontalButtonStackCollectionViewFlowLayout.h @@ -0,0 +1,5 @@ +#import + +@interface BTUIHorizontalButtonStackCollectionViewFlowLayout : UICollectionViewFlowLayout + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIHorizontalButtonStackCollectionViewFlowLayout.m b/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIHorizontalButtonStackCollectionViewFlowLayout.m new file mode 100644 index 0000000..3a21fd3 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIHorizontalButtonStackCollectionViewFlowLayout.m @@ -0,0 +1,65 @@ +#import "BTUIHorizontalButtonStackCollectionViewFlowLayout.h" +#import "BTUIHorizontalButtonStackSeparatorLineView.h" + + +NSString *BTHorizontalButtonStackCollectionViewFlowLayoutLineSeparatorDecoratorViewKind = @"BTHorizontalButtonStackCollectionViewFlowLayoutLineSeparatorDecoratorViewKind"; + +@interface BTUIHorizontalButtonStackCollectionViewFlowLayout () +@property (nonatomic, strong) NSMutableArray *cachedLayoutAttributes; +@end + +@implementation BTUIHorizontalButtonStackCollectionViewFlowLayout + +- (id)init { + self = [super init]; + if (self) { + [self registerClass:[BTUIHorizontalButtonStackSeparatorLineView class] forDecorationViewOfKind:BTHorizontalButtonStackCollectionViewFlowLayoutLineSeparatorDecoratorViewKind]; + } + return self; +} + +- (void)prepareLayout { + NSAssert(self.collectionView.numberOfSections == 1, @"Must have 1 section"); + + [self calculateAndCacheLayoutAttributes]; +} + +- (CGSize)collectionViewContentSize { + /// The collection view should never scroll + return self.collectionView.frame.size; +} + +- (NSArray *)layoutAttributesForElementsInRect:(__unused CGRect)rect { + return [self.cachedLayoutAttributes copy]; +} + +#pragma mark - Helpers + +- (void)calculateAndCacheLayoutAttributes { + self.cachedLayoutAttributes = [NSMutableArray array]; + + NSInteger numberOfButtons = [self.collectionView numberOfItemsInSection:0]; + CGFloat totalWidth = CGRectGetWidth(self.collectionView.frame); + CGFloat totalHeight = CGRectGetHeight(self.collectionView.frame); + CGSize buttonSize = CGSizeMake(totalWidth / numberOfButtons, totalHeight); + + for (NSInteger i = 0; i < numberOfButtons; i++) { + NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0]; + UICollectionViewLayoutAttributes *cellLayoutAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; + CGRect cellFrame = CGRectMake(buttonSize.width * i, 0, buttonSize.width, buttonSize.height); + cellLayoutAttributes.frame = cellFrame; + [self.cachedLayoutAttributes addObject:cellLayoutAttributes]; + } + + if (numberOfButtons > 1) { + NSArray *layoutAttributesWithoutLastElement = [self.cachedLayoutAttributes subarrayWithRange:NSMakeRange(0, [self.cachedLayoutAttributes count] > 0 ? [self.cachedLayoutAttributes count] - 1 : 0)]; + for (UICollectionViewLayoutAttributes *attributes in layoutAttributesWithoutLastElement) { + UICollectionViewLayoutAttributes *separatorAttributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:BTHorizontalButtonStackCollectionViewFlowLayoutLineSeparatorDecoratorViewKind + withIndexPath:attributes.indexPath]; + separatorAttributes.frame = CGRectMake(attributes.frame.origin.x + attributes.frame.size.width, attributes.frame.origin.y, 1/2.0f, attributes.frame.size.height); + [self.cachedLayoutAttributes addObject:separatorAttributes]; + } + } +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIHorizontalButtonStackSeparatorLineView.h b/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIHorizontalButtonStackSeparatorLineView.h new file mode 100644 index 0000000..3e2c93a --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIHorizontalButtonStackSeparatorLineView.h @@ -0,0 +1,7 @@ +#import + +#import "BTUI.h" + +@interface BTUIHorizontalButtonStackSeparatorLineView : UICollectionReusableView +@property (nonatomic, strong) BTUI *theme; +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIHorizontalButtonStackSeparatorLineView.m b/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIHorizontalButtonStackSeparatorLineView.m new file mode 100644 index 0000000..ae5c83a --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIHorizontalButtonStackSeparatorLineView.m @@ -0,0 +1,59 @@ +#import "BTUIHorizontalButtonStackSeparatorLineView.h" + +@interface BTUIHorizontalButtonStackSeparatorLineView () +@property (nonatomic, strong) UIView *line; +@end + +@implementation BTUIHorizontalButtonStackSeparatorLineView + +- (id)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + self.theme = [BTUI braintreeTheme]; + self.opaque = NO; + self.backgroundColor = [UIColor clearColor]; + + self.line = [[UIView alloc] initWithFrame:CGRectZero]; + self.line.translatesAutoresizingMaskIntoConstraints = NO; + [self updateThemeAttributes]; + [self addSubview:self.line]; + } + return self; +} + +- (void)updateThemeAttributes { + self.line.backgroundColor = self.theme.borderColor; +} + +- (void)setTheme:(BTUI *)theme { + _theme = theme; + [self updateThemeAttributes]; +} + +- (void)updateConstraints { + NSDictionary *views = @{ @"line": self.line }; + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[line]|" + options:0 + metrics:nil + views:views]]; + + [self addConstraint:[NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeHeight + relatedBy:NSLayoutRelationEqual + toItem:self.line + attribute:NSLayoutAttributeHeight + multiplier:2.0f + constant:0.0f]]; + + [self addConstraint:[NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeCenterY + relatedBy:NSLayoutRelationEqual + toItem:self.line + attribute:NSLayoutAttributeCenterY + multiplier:1.0f + constant:0.0f]]; + + [super updateConstraints]; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIPaymentButtonCollectionViewCell.h b/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIPaymentButtonCollectionViewCell.h new file mode 100644 index 0000000..d59de8d --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIPaymentButtonCollectionViewCell.h @@ -0,0 +1,5 @@ +#import + +@interface BTUIPaymentButtonCollectionViewCell : UICollectionViewCell +@property (nonatomic, strong) UIControl *paymentButton; +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIPaymentButtonCollectionViewCell.m b/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIPaymentButtonCollectionViewCell.m new file mode 100644 index 0000000..7c831db --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Collection Views/BTUIPaymentButtonCollectionViewCell.m @@ -0,0 +1,62 @@ +#import "BTUIPaymentButtonCollectionViewCell.h" + +@interface BTUIPaymentButtonCollectionViewCell () +@property (nonatomic, strong) NSMutableArray *paymentButtonConstraints; +@end + +@implementation BTUIPaymentButtonCollectionViewCell + +- (id)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + self.contentView.userInteractionEnabled = NO; + self.paymentButtonConstraints = [NSMutableArray array]; + } + return self; +} + +- (void)setPaymentButton:(UIControl *)paymentButton { + if (self.paymentButtonConstraints) { + [self removeConstraints:self.paymentButtonConstraints]; + [self.paymentButtonConstraints removeAllObjects]; + } + [self.paymentButton removeFromSuperview]; + + _paymentButton = paymentButton; + [self.contentView addSubview:paymentButton]; + + paymentButton.userInteractionEnabled = NO; + + [self setNeedsUpdateConstraints]; +} + +- (void)updateConstraints { + if (self.paymentButton) { + NSDictionary *views = @{ @"paymentButton": self.paymentButton }; + [self.paymentButtonConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[paymentButton]|" + options:0 + metrics:nil + views:views]]; + [self.paymentButtonConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[paymentButton]|" + options:0 + metrics:nil + views:views]]; + [self addConstraints:self.paymentButtonConstraints]; + } + [super updateConstraints]; +} + +- (void)setHighlighted:(BOOL)highlighted { + [super setHighlighted:highlighted]; + + [self.paymentButton setHighlighted:highlighted]; +} + +- (void)setSelected:(BOOL)selected { + [super setSelected:selected]; + + [self.paymentButton setSelected:selected]; +} + +@end + diff --git a/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIFloatLabel.h b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIFloatLabel.h new file mode 100644 index 0000000..aa515d0 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIFloatLabel.h @@ -0,0 +1,10 @@ +#import "BTUIThemedView.h" + +@interface BTUIFloatLabel : BTUIThemedView + +@property (nonatomic, readonly, strong) UILabel *label; + +- (void)showWithAnimation:(BOOL)shouldAnimate; +- (void)hideWithAnimation:(BOOL)shouldAnimate; + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIFloatLabel.m b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIFloatLabel.m new file mode 100644 index 0000000..9c228c6 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIFloatLabel.m @@ -0,0 +1,125 @@ +#import "BTUIFloatLabel.h" + +@interface BTUIFloatLabel () +@property (nonatomic, readwrite, strong) UILabel *label; +@property (nonatomic, strong) NSArray *verticalConstraints; +@end + +@implementation BTUIFloatLabel + +- (id)init { + self = [super init]; + if (self) { + [self setupSubviews]; + } + return self; +} + +- (id)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self setupSubviews]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + [self setupSubviews]; + } + return self; +} + +- (void)setupSubviews { + self.label = [[UILabel alloc] init]; + self.label.translatesAutoresizingMaskIntoConstraints = NO; + self.label.font = self.theme.textFieldFloatLabelFont; + self.label.textColor = self.theme.textFieldFloatLabelTextColor; + self.label.backgroundColor = [UIColor clearColor]; + self.label.opaque = NO; + self.label.numberOfLines = 1; + self.label.adjustsFontSizeToFitWidth = YES; + [self addSubview:self.label]; + + self.verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[label]|" + options:0 + metrics:nil + views:[self viewBindings]]; +} + +- (void)updateConstraints { + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[label]|" + options:0 + metrics:nil + views:[self viewBindings]]]; + [self addConstraints:self.verticalConstraints]; + + [super updateConstraints]; +} + +- (void)showWithAnimation:(BOOL)shouldAnimate { + void (^animations)(void) = ^{ + self.label.alpha = 1.0f; + [self layoutIfNeeded]; + }; + + [self removeConstraints:self.verticalConstraints]; + self.verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[label]|" + options:0 + metrics:nil + views:[self viewBindings]]; + [self setNeedsUpdateConstraints]; + + if (shouldAnimate) { + [UIView animateWithDuration:self.theme.quickTransitionDuration + delay:0.0f + options:UIViewAnimationOptionCurveEaseOut + animations:animations + completion:nil]; + } else { + animations(); + } +} + +- (void)hideWithAnimation:(BOOL)shouldAnimate { + void (^animations)(void) = ^{ + self.label.alpha = 0.0f; + [self setNeedsUpdateConstraints]; + [self layoutIfNeeded]; + }; + + [self removeConstraints:self.verticalConstraints]; + self.verticalConstraints = @[ [NSLayoutConstraint constraintWithItem:self.label + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationEqual + toItem:self + attribute:NSLayoutAttributeCenterY + multiplier:1.0f + constant:0.0f] ]; + [self setNeedsUpdateConstraints]; + if (shouldAnimate) { + [UIView animateWithDuration:self.theme.quickTransitionDuration + delay:0.0f + options:UIViewAnimationOptionCurveEaseOut + animations:animations + completion:nil]; + } else { + animations(); + } +} + +#pragma mark - Theme + +- (void)setTheme:(BTUI *)theme { + [super setTheme:theme]; + + self.label.font = self.theme.textFieldFloatLabelFont; + self.label.textColor = self.theme.textFieldFloatLabelTextColor; +} + +- (NSDictionary *)viewBindings { + return @{ @"label": self.label }; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIFormField.h b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIFormField.h new file mode 100644 index 0000000..a3a910d --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIFormField.h @@ -0,0 +1,46 @@ +#import +#import "BTUIThemedView.h" + +@protocol BTUIFormFieldDelegate; + +/** + @class BTUIFormField + @brief A form field is a UI component for entering a text value + + @discussion This is the parent class of all card form fields, + and handles display but not formatting, validation, or + relaying of events + + @see BTUIFormField() +*/ +@interface BTUIFormField : BTUIThemedView + +- (void)updateAppearance; + +@property (nonatomic, weak) id delegate; +@property (nonatomic, assign) BOOL vibrateOnInvalidInput; +@property (nonatomic, assign, readonly) BOOL valid; +@property (nonatomic, assign, readonly) BOOL entryComplete; +@property (nonatomic, assign) BOOL displayAsValid; +@property (nonatomic, assign) BOOL bottomBorder; +@property (nonatomic, assign, readwrite) BOOL backspace; + +/** + @brief The text displayed by the field +*/ +@property (nonatomic, copy) NSString *text; + +@end + + +@protocol BTUIFormFieldDelegate + +- (void)formFieldDidChange:(BTUIFormField *)formField; +- (void)formFieldDidDeleteWhileEmpty:(BTUIFormField *)formField; + +@optional +- (BOOL)formFieldShouldReturn:(BTUIFormField *)formField; +- (void)formFieldDidBeginEditing:(BTUIFormField *)formField; +- (void)formFieldDidEndEditing:(BTUIFormField *)formField; + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIFormField.m b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIFormField.m new file mode 100644 index 0000000..9a8fed3 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIFormField.m @@ -0,0 +1,418 @@ +#import "BTUIFormField_Protected.h" +#import "BTUIViewUtil.h" +#import "BTUITextField.h" +#import "BTUIFloatLabel.h" + +@import QuartzCore; + +static const CGFloat formFieldTopMargin = 7; +static const CGFloat formFieldLabelHeight = 15; +static const CGFloat formFieldVerticalSpace = 1; +static const CGFloat formFieldTextFieldHeight = 20; +static const CGFloat formFieldBottomMargin = 11; + +@interface BTUIFormField () + +@property (nonatomic, strong) BTUIFloatLabel *floatLabel; +@property (nonatomic, copy) NSString *previousTextFieldText; +@property (nonatomic, strong) NSMutableArray *layoutConstraints; + +@end + +@implementation BTUIFormField + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + self.displayAsValid = YES; + BTUITextField *textField = [BTUITextField new]; + textField.editDelegate = self; + _textField = textField; + self.textField.translatesAutoresizingMaskIntoConstraints = NO; + self.textField.borderStyle = UITextBorderStyleNone; + self.textField.backgroundColor = [UIColor clearColor]; + self.textField.opaque = NO; + self.textField.adjustsFontSizeToFitWidth = YES; + self.textField.returnKeyType = UIReturnKeyNext; + + self.floatLabel = [[BTUIFloatLabel alloc] init]; + self.floatLabel.translatesAutoresizingMaskIntoConstraints = NO; + [self.floatLabel hideWithAnimation:NO]; + + self.accessoryView = [[UIView alloc] init]; + self.accessoryView.backgroundColor = [UIColor clearColor]; + self.accessoryView.hidden = YES; + + [self.textField addTarget:self action:@selector(fieldContentDidChange) forControlEvents:UIControlEventEditingChanged]; + [self.textField addTarget:self action:@selector(editingDidBegin) forControlEvents:UIControlEventEditingDidBegin]; + [self.textField addTarget:self action:@selector(editingDidEnd) forControlEvents:UIControlEventEditingDidEnd]; + + self.textField.delegate = self; + + [self addSubview:self.textField]; + [self addSubview:self.floatLabel]; + [self addSubview:self.accessoryView]; + + [self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tappedField)]]; + + [self setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical]; + self.opaque = NO; + + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(orientationChange) + name:UIDeviceOrientationDidChangeNotification + object:nil]; + } + return self; +} + +- (CGSize)intrinsicContentSize { + CGFloat height = formFieldTopMargin + formFieldLabelHeight + formFieldVerticalSpace + formFieldTextFieldHeight + formFieldBottomMargin; + return CGSizeMake(UIViewNoIntrinsicMetric, height); +} + +- (void)setAccessoryView:(UIView *)accessoryView { + _accessoryView = accessoryView; + self.accessoryView.userInteractionEnabled = NO; + self.accessoryView.translatesAutoresizingMaskIntoConstraints = NO; +} + +- (void)setDisplayAsValid:(BOOL)displayAsValid { + if (self.vibrateOnInvalidInput && self.textField.isFirstResponder && _displayAsValid && !displayAsValid) { + [BTUIViewUtil vibrate]; + } + + _displayAsValid = displayAsValid; + [self updateAppearance]; + [self setNeedsDisplay]; +} + +- (void)orientationChange { + [self setNeedsDisplay]; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +#pragma mark - Validity "abstract" methods + +- (BOOL)valid { + return YES; +} + +- (BOOL)entryComplete { + NSUInteger index = [self.textField offsetFromPosition:self.textField.beginningOfDocument toPosition:self.textField.selectedTextRange.start]; + return index == self.textField.text.length && self.valid; +} + +- (BOOL)becomeFirstResponder { + return [self.textField becomeFirstResponder]; +} + +- (BOOL)resignFirstResponder { + return [super resignFirstResponder] || [self.textField resignFirstResponder]; +} + +#pragma mark - Theme + +- (void)setTheme:(BTUI *)theme { + [super setTheme:theme]; + NSMutableDictionary *d = [NSMutableDictionary dictionaryWithDictionary:self.theme.textFieldTextAttributes]; + d[NSKernAttributeName] = @0; + self.textField.defaultTextAttributes = self.theme.textFieldTextAttributes; + self.floatLabel.theme = theme; +} + +- (void)setThemedPlaceholder:(NSString *)placeholder { + self.floatLabel.label.text = placeholder; + self.textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:placeholder ?: @"" + attributes:self.theme.textFieldPlaceholderAttributes]; +} + +- (void)setThemedAttributedPlaceholder:(NSAttributedString *)placeholder { + NSMutableAttributedString *mutableFloatLabel = [[NSMutableAttributedString alloc] initWithAttributedString:placeholder]; + [mutableFloatLabel beginEditing]; + [mutableFloatLabel removeAttribute:NSForegroundColorAttributeName range:NSMakeRange(0, [mutableFloatLabel length])]; + [mutableFloatLabel removeAttribute:NSBackgroundColorAttributeName range:NSMakeRange(0, [mutableFloatLabel length])]; + [mutableFloatLabel removeAttribute:NSFontAttributeName range:NSMakeRange(0, [mutableFloatLabel length])]; + [mutableFloatLabel endEditing]; + self.floatLabel.label.attributedText = mutableFloatLabel; + + NSMutableAttributedString *mutablePlaceholder = [[NSMutableAttributedString alloc] initWithAttributedString:placeholder]; + [mutablePlaceholder beginEditing]; + [mutablePlaceholder addAttributes:self.theme.textFieldPlaceholderAttributes range:NSMakeRange(0, [mutablePlaceholder length])]; + [mutablePlaceholder endEditing]; + + self.textField.attributedPlaceholder = mutablePlaceholder; +} + +#pragma mark - Drawing + +- (void)updateAppearance { + UIColor *textColor; + NSString *currentAccessibilityLabel = self.textField.accessibilityLabel; + if (!self.displayAsValid){ + textColor = self.theme.errorForegroundColor; + self.backgroundColor = self.theme.errorBackgroundColor; + if (currentAccessibilityLabel != nil) { + self.textField.accessibilityLabel = [self addInvalidAccessibilityToString:currentAccessibilityLabel]; + } + } else { + textColor = self.theme.textFieldTextColor; + self.backgroundColor = [UIColor clearColor]; + if (currentAccessibilityLabel != nil) { + self.textField.accessibilityLabel = [self stripInvalidAccessibilityFromString:currentAccessibilityLabel]; + } + } + + NSMutableAttributedString *mutableText = [[NSMutableAttributedString alloc] initWithAttributedString:self.textField.attributedText]; + [mutableText addAttributes:@{NSForegroundColorAttributeName: textColor} range:NSMakeRange(0, mutableText.length)]; + + UITextRange *currentRange = self.textField.selectedTextRange; + + self.textField.attributedText = mutableText; + + // Reassign current selection range, since it gets cleared after attributedText assignment + self.textField.selectedTextRange = currentRange; +} + +- (void)drawRect:(CGRect)rect { + + // Draw borders + + CGContextRef context = UIGraphicsGetCurrentContext(); + if (!self.displayAsValid) { + [self.theme.errorForegroundColor setFill]; + + CGPathRef path = CGPathCreateWithRect(CGRectMake(rect.origin.x, CGRectGetMaxY(rect) - 0.5f, rect.size.width, 0.5f), NULL); + CGContextAddPath(context, path); + CGPathRelease(path); + + path = CGPathCreateWithRect(CGRectMake(rect.origin.x, 0, rect.size.width, 0.5f), NULL); + CGContextAddPath(context, path); + + CGContextDrawPath(context, kCGPathFill); + CGPathRelease(path); + } else if (self.bottomBorder) { + CGFloat horizontalMargin = [self.theme horizontalMargin]; + CGPathRef path = CGPathCreateWithRect(CGRectMake(rect.origin.x + horizontalMargin, CGRectGetMaxY(rect) - 0.5f, rect.size.width - horizontalMargin, 0.5f), NULL); + CGContextAddPath(context, path); + [self.theme.borderColor setFill]; + CGContextDrawPath(context, kCGPathFill); + CGPathRelease(path); + } +} + +- (void)setBottomBorder:(BOOL)bottomBorder { + _bottomBorder = bottomBorder; + [self setNeedsDisplay]; +} + +- (void)updateConstraints { + + NSDictionary *metrics = @{@"horizontalMargin": @([self.theme horizontalMargin]), + @"accessoryViewWidth": @44, + @"formFieldTopMargin": @(formFieldTopMargin), + @"formFieldLabelHeight": @(formFieldLabelHeight), + @"formFieldVerticalSpace": @(formFieldVerticalSpace), + @"formFieldTextFieldHeight": @(formFieldTextFieldHeight), + @"formFieldBottomMargin": @(formFieldBottomMargin) + }; + NSDictionary *views = @{ @"textField": self.textField, + @"floatLabel": self.floatLabel, + @"accessoryView": self.accessoryView }; + + if (self.layoutConstraints != nil) { + [self removeConstraints:self.layoutConstraints]; + } + self.layoutConstraints = [NSMutableArray array]; + + // Pin accessory view to right with constant width + + [self.layoutConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[accessoryView]-(horizontalMargin)-|" + options:NSLayoutFormatAlignAllCenterY + metrics:metrics + views:views]]; + + + // Horizontally Pin Float Label and accessory view + [self.layoutConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(horizontalMargin)-[floatLabel]-(horizontalMargin)-[accessoryView]-(horizontalMargin)-|" options:0 metrics:metrics views:views]]; + + // Horizontally Pin text field and accessory view + [self.layoutConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(horizontalMargin)-[textField]-(horizontalMargin)-[accessoryView]-(horizontalMargin)-|" options:0 metrics:metrics views:views]]; + + [self.layoutConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[accessoryView(==accessoryViewWidth)]" options:0 metrics:metrics views:views]]; + + [self.layoutConstraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(formFieldTopMargin)-[floatLabel(==formFieldLabelHeight)]-(formFieldVerticalSpace)-[textField(==formFieldTextFieldHeight)]-(formFieldBottomMargin)-|" options:0 metrics:metrics views:views]]; + [self.layoutConstraints addObject:[NSLayoutConstraint constraintWithItem:self.accessoryView + attribute:NSLayoutAttributeCenterY + relatedBy:NSLayoutRelationEqual + toItem:self + attribute:NSLayoutAttributeCenterY + multiplier:1.0f + constant:0]]; + NSArray *contraintsToAdd = [self.layoutConstraints copy]; + [self addConstraints:contraintsToAdd]; + [super updateConstraints]; + +} + +- (void)didDeleteBackward { + if (self.previousTextFieldText.length == 0 && self.textField.text.length == 0) { + [self.delegate formFieldDidDeleteWhileEmpty:self]; + } +} + + +- (void)updateFloatLabelTextColor { + if ([self.textField isFirstResponder]) { + self.floatLabel.label.textColor = self.tintColor; + } else { + self.floatLabel.label.textColor = self.theme.textFieldFloatLabelTextColor; + } +} + +- (void)tintColorDidChange { + [self updateFloatLabelTextColor]; +} + +#pragma mark - UITextFieldDelegate methods + +- (void)textFieldDidBeginEditing:(__unused UITextField *)textField { + [self updateFloatLabelTextColor]; + if ([self.delegate respondsToSelector:@selector(formFieldDidBeginEditing:)]) { + [self.delegate formFieldDidBeginEditing:self]; + } +} + +- (void)textFieldDidEndEditing:(__unused UITextField *)textField { + [self updateFloatLabelTextColor]; + if ([self.delegate respondsToSelector:@selector(formFieldDidEndEditing:)]) { + [self.delegate formFieldDidEndEditing:self]; + } +} + +#pragma mark - BTUITextFieldEditDelegate methods + +- (void)textFieldWillDeleteBackward:(__unused BTUITextField *)textField { + // _backspace indicates that the backspace key was typed. + _backspace = YES; + +} + +- (void)textFieldDidDeleteBackward:(BTUITextField *)textField originalText:(__unused NSString *)originalText { + if (originalText.length == 0) { + [self.delegate formFieldDidDeleteWhileEmpty:self]; + } + + if (textField.text.length == 0) { + [self.floatLabel hideWithAnimation:YES]; + } +} + +- (void)textField:(__unused BTUITextField *)textField willInsertText:(__unused NSString *)text { + _backspace = NO; +} + +- (void)textField:(BTUITextField *)textField didInsertText:(__unused NSString *)text { + if (textField.text.length > 0) { + [self.floatLabel showWithAnimation:YES]; + } +} + +- (void)setAccessoryHighlighted:(BOOL)highlight { + if (self.accessoryView) { + if ([self.accessoryView respondsToSelector:@selector(setHighlighted:animated:)]) { + SEL selector = @selector(setHighlighted:animated:); + BOOL animated = YES; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self.accessoryView methodSignatureForSelector:selector]]; + [invocation setSelector:selector]; + [invocation setTarget:self.accessoryView]; + [invocation setArgument:&highlight atIndex:2]; + [invocation setArgument:&animated atIndex:3]; + [invocation invoke]; + } + } +} + +#pragma mark - Custom accessors + +- (void)setText:(NSString *)text { + BOOL shouldChange = [self.textField.delegate textField:self.textField + shouldChangeCharactersInRange:NSMakeRange(0, self.textField.text.length) + replacementString:text]; + if (shouldChange) { + [self.textField.delegate textFieldDidBeginEditing:self.textField]; + [self.textField.editDelegate textField:self.textField willInsertText:text]; + self.textField.text = text; + [self fieldContentDidChange]; + [self.textField.editDelegate textField:self.textField didInsertText:text]; + [self.textField.delegate textFieldDidEndEditing:self.textField]; + + } +} + +- (NSString *)text { + return self.textField.text; +} + +#pragma mark - Delegate methods and handlers + +- (void)fieldContentDidChange { + // To be implemented by subclass +} + +- (void)editingDidBegin { + [self setAccessoryHighlighted:YES]; +} + +- (void)editingDidEnd { + [self setAccessoryHighlighted:NO]; +} + + +- (BOOL)textField:(__unused UITextField *)textField shouldChangeCharactersInRange:(__unused NSRange)range replacementString:(__unused NSString *)newText { + // To be implemented by subclass + return YES; +} + +- (BOOL)textFieldShouldReturn:(__unused UITextField *)textField { + if ([self.delegate respondsToSelector:@selector(formFieldShouldReturn:)]) { + return [self.delegate formFieldShouldReturn:self]; + } else { + return YES; + } +} + +- (void)tappedField { + [self.textField becomeFirstResponder]; +} + +#pragma mark UIKeyInput + +- (void)insertText:(NSString *)text { + [self.textField insertText:text]; +} + +- (void)deleteBackward { + [self.textField deleteBackward]; +} + +- (BOOL)hasText { + return [self.textField hasText]; +} + +#pragma mark Accessibility Helpers + +- (NSString *)stripInvalidAccessibilityFromString:(NSString *)str { + return [str stringByReplacingOccurrencesOfString:@"Invalid: " withString:@""]; +} + +- (NSString *)addInvalidAccessibilityToString:(NSString *)str { + return [NSString stringWithFormat:@"Invalid: %@", [self stripInvalidAccessibilityFromString:str]]; +} + +@end + diff --git a/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIFormField_Protected.h b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIFormField_Protected.h new file mode 100644 index 0000000..ed0b95e --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIFormField_Protected.h @@ -0,0 +1,26 @@ +#import +#import "BTUIFormField.h" +#import "BTUITextField.h" + +/** + @brief Private class extension for implementors of BTUIFormField subclasses. +*/ +@interface BTUIFormField () + +@property (nonatomic, strong, readonly) BTUITextField *textField; + +@property (nonatomic, strong) UIView *accessoryView; + +/** + @brief Override in your subclass to implement behavior on content change +*/ +- (void)fieldContentDidChange; + +/** + @brief Sets placeholder text with the appropriate theme style +*/ +- (void)setThemedPlaceholder:(NSString *)placeholder; +- (void)setThemedAttributedPlaceholder:(NSAttributedString *)placeholder; + +@end + diff --git a/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIScrollView.h b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIScrollView.h new file mode 100644 index 0000000..e0cc067 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIScrollView.h @@ -0,0 +1,29 @@ +#import + +@protocol BTUIScrollViewScrollRectToVisibleDelegate; + +/** + @class BTUIScrollView + @brief Subclass of UIScrollView that disables default iOS "autoscrolling" to text fields by overriding the scrollRectToVisible method with a call to a delegate. +*/ +@interface BTUIScrollView : UIScrollView + +/** + @brief Delegate that, if set, receives messages when scrollRectToVisible is called + @note If nil, scrollRectToVisible is simply a no-op. +*/ +@property (nonatomic, weak) id scrollRectToVisibleDelegate; + +/** + @brief The "default" scrollRectToVisible implementation +*/ +- (void)defaultScrollRectToVisible:(CGRect)rect animated:(BOOL)animated; + +@end + + +@protocol BTUIScrollViewScrollRectToVisibleDelegate + +- (void)scrollView:(BTUIScrollView *)scrollView requestsScrollRectToVisible:(__unused CGRect)rect animated:(__unused BOOL)animated; + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIScrollView.m b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIScrollView.m new file mode 100644 index 0000000..8a508de --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIScrollView.m @@ -0,0 +1,21 @@ +#import "BTUIScrollView.h" + +@implementation BTUIScrollView + +- (void)defaultScrollRectToVisible:(CGRect)rect animated:(BOOL)animated +{ + [super scrollRectToVisible:rect animated:animated]; +} + +- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated +{ + if (self.scrollRectToVisibleDelegate != nil) { + [self.scrollRectToVisibleDelegate scrollView:self requestsScrollRectToVisible:rect animated:animated]; + } +} + +- (BOOL)touchesShouldCancelInContentView:(__unused UIView *)view { + return YES; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUITextField.h b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUITextField.h new file mode 100644 index 0000000..164705a --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUITextField.h @@ -0,0 +1,58 @@ +#import + +@protocol BTUITextFieldEditDelegate; + +/** + @class BTUITextField + @brief A specialized text field that provides more granular callbacks than a standard + @discussion UITextField as the user edits text +*/ +@interface BTUITextField : UITextField + +/** + @brief The specialized delegate for receiving callbacks about editing +*/ +@property (nonatomic, weak) id editDelegate; + +@end + +/** + @brief A protocol for receiving callbacks when a user edits text in a `BTUITextField` +*/ +@protocol BTUITextFieldEditDelegate + +@optional + +/** + @brief The editDelegate receives this message when the user deletes a character, but before the deletion is applied to the `text` + + @param textField The text field +*/ +- (void)textFieldWillDeleteBackward:(BTUITextField *)textField; + +/** + @brief The editDelegate receives this message after the user deletes a character + + @param textField The text field + @param originalText The `text` of the text field before applying the deletion +*/ +- (void)textFieldDidDeleteBackward:(BTUITextField *)textField + originalText:(NSString *)originalText; + +/** + @brief The editDelegate receives this message when the user enters text, but before the text is inserted + + @param textField The text field + @param text The text that will be inserted +*/ +- (void)textField:(BTUITextField *)textField willInsertText:(NSString *)text; + +/** + @brief The editDelegate receives this message after the user enters text + + @param textField The text field + @param text The text that was inserted +*/ +- (void)textField:(BTUITextField *)textField didInsertText:(NSString *)text; + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUITextField.m b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUITextField.m new file mode 100644 index 0000000..6c9c42d --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUITextField.m @@ -0,0 +1,100 @@ +#import "BTUITextField.h" + +@interface BTUITextField () +@property (nonatomic, copy) NSString *previousText; +@end + +@implementation BTUITextField + +- (instancetype)init { + if (self = [super init]) { + if ([UIDevice currentDevice].systemVersion.intValue == 9) { + [self addTarget:self action:@selector(iOS9_changed) forControlEvents:UIControlEventEditingChanged]; + self.delegate = self; + } + } + return self; +} + +- (void)iOS9_changed { + // We only want to notify when this text field's text length has increased + if (self.previousText.length >= self.text.length) { + self.previousText = self.text; + return; + } + self.previousText = self.text; + + NSString *insertedText = [self.text substringWithRange:NSMakeRange(self.previousText.length, self.text.length - self.previousText.length)]; + + if ([self.editDelegate respondsToSelector:@selector(textField:willInsertText:)]) { + // Sets _backspace = NO; in the BTUIFormField or BTUIFormField subclass + [self.editDelegate textField:self willInsertText:insertedText]; + } + + self.previousText = self.text; + + if ([self.editDelegate respondsToSelector:@selector(textField:didInsertText:)]) { + [self.editDelegate textField:self didInsertText:insertedText]; + } +} + +- (BOOL)keyboardInputShouldDelete:(__unused UITextField *)textField { + if ([self.editDelegate respondsToSelector:@selector(textFieldWillDeleteBackward:)]) { + [self.editDelegate textFieldWillDeleteBackward:self]; + } + + BOOL shouldDelete = YES; + + if ([UITextField instancesRespondToSelector:_cmd]) { + BOOL (*keyboardInputShouldDelete)(id, SEL, UITextField *) = (BOOL (*)(id, SEL, UITextField *))[UITextField instanceMethodForSelector:_cmd]; + + if (keyboardInputShouldDelete) { + shouldDelete = keyboardInputShouldDelete(self, _cmd, textField); + } + } + + BOOL isIos8 = ([[[UIDevice currentDevice] systemVersion] intValue] == 8); + BOOL isLessThanIos8_3 = ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.3f); + + // iOS 8.0-8.2 has a bug where deleteBackward is not called even when this method returns YES and the character is deleted + // As a result, we do so manually but return NO in order to prevent UITextField from double-calling the delegate method + // (textFieldDidDeleteBackwards:originalText:) + if (isIos8 && isLessThanIos8_3) { + [self deleteBackward]; + shouldDelete = NO; + } + + return shouldDelete; +} + +- (void)deleteBackward +{ + BOOL shouldDismiss = [self.text length] == 0; + NSString *originalText = self.text; + + [super deleteBackward]; + + if (shouldDismiss) { + if ([self.delegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) { + [self.delegate textField:self shouldChangeCharactersInRange:NSMakeRange(0, 0) replacementString:@""]; + } + } + + if ([self.editDelegate respondsToSelector:@selector(textFieldDidDeleteBackward:originalText:)]) { + [self.editDelegate textFieldDidDeleteBackward:self originalText:originalText]; + } +} + +- (void)insertText:(NSString *)text { + if ([self.editDelegate respondsToSelector:@selector(textField:willInsertText:)]) { + [self.editDelegate textField:self willInsertText:text]; + } + + [super insertText:text]; + + if ([self.editDelegate respondsToSelector:@selector(textField:didInsertText:)]) { + [self.editDelegate textField:self didInsertText:text]; + } +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIThemedView.m b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIThemedView.m new file mode 100644 index 0000000..dd9a343 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIThemedView.m @@ -0,0 +1,30 @@ +#import "BTUIThemedView.h" + +@implementation BTUIThemedView + +- (id)init { + self = [super init]; + if (self) { + _theme = [BTUI braintreeTheme]; + } + return self; +} + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + _theme = [BTUI braintreeTheme]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + _theme = [BTUI braintreeTheme]; + } + return self; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIVectorArtView.m new file mode 100644 index 0000000..01d0949 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Custom Views/BTUIVectorArtView.m @@ -0,0 +1,32 @@ +#import "BTUIVectorArtView.h" +@import QuartzCore; + +@implementation BTUIVectorArtView + +- (void)drawRect:(CGRect)rect +{ + CGContextRef ctx = UIGraphicsGetCurrentContext(); + CGContextSaveGState(ctx); + CGFloat scaleFactor = MIN(rect.size.width/self.artDimensions.width, rect.size.height/self.artDimensions.height); + CGContextScaleCTM(ctx, scaleFactor, scaleFactor); + CGContextTranslateCTM(ctx, rect.origin.x, rect.origin.y); + + [self drawArt]; + + CGContextRestoreGState(ctx); +} + +- (void)drawArt { + // Subclass overrides this +} + + +- (UIImage *)imageOfSize:(CGSize)size { + UIGraphicsBeginImageContextWithOptions(size, NO, 0); + [self drawRect:CGRectMake(0, 0, size.width, size.height)]; + UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return img; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardCvvField.h b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardCvvField.h new file mode 100644 index 0000000..f840642 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardCvvField.h @@ -0,0 +1,10 @@ +#import "BTUIFormField.h" +#import "BTUICardType.h" + +@interface BTUICardCvvField : BTUIFormField + +@property (nonatomic, strong) BTUICardType *cardType; + +@property (nonatomic, copy) NSString *cvv; + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardCvvField.m b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardCvvField.m new file mode 100644 index 0000000..2a76930 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardCvvField.m @@ -0,0 +1,102 @@ +#import "BTUICardCvvField.h" +#import "BTUIFormField_Protected.h" +#import "BTUICardHint.h" +#import "BTUIUtil.h" +#import "BTUIViewUtil.h" +#import "BTUILocalizedString.h" + +#define kMinimumCvvLength 3 +#define kMaximumCvvLength 4 + +@interface BTUICardCvvField () +@property (nonatomic, readonly) NSUInteger validLength; +@property (nonatomic, strong) BTUICardHint *hint; +@end + +@implementation BTUICardCvvField + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self setThemedPlaceholder:BTUILocalizedString(CVV_FIELD_PLACEHOLDER)]; + self.textField.accessibilityLabel = BTUILocalizedString(CVV_FIELD_PLACEHOLDER); + self.textField.keyboardType = UIKeyboardTypeNumberPad; + self.textField.delegate = self; + + self.hint = [BTUICardHint new]; + self.hint.displayMode = BTCardHintDisplayModeCVVHint; + self.accessoryView = self.hint; + self.accessoryView.translatesAutoresizingMaskIntoConstraints = NO; + [self addSubview:self.accessoryView]; + } + return self; +} + +- (void)setCardType:(BTUICardType *)cardType { + _cardType = cardType; + self.displayAsValid = [self.textField isFirstResponder] || self.textField.text.length == 0 || self.valid; + BTUIPaymentOptionType type = [BTUIViewUtil paymentMethodTypeForCardType:cardType]; + [self.hint setCardType:type animated:YES]; + + if (type == BTUIPaymentOptionTypeUnionPay) { + [self setThemedPlaceholder:@"CVVM"]; + } else { + [self setThemedPlaceholder:BTUILocalizedString(CVV_FIELD_PLACEHOLDER)]; + } + + [self updateAppearance]; +} + +- (BOOL)valid { + BOOL noCardTypeOKLength = (self.cardType == nil && self.cvv.length <= kMaximumCvvLength && self.cvv.length >= kMinimumCvvLength); + BOOL validLengthForCardType = (self.cardType != nil && self.cvv.length == self.cardType.validCvvLength); + return noCardTypeOKLength || validLengthForCardType; +} + + +- (BOOL)entryComplete { + NSUInteger index = [self.textField offsetFromPosition:self.textField.beginningOfDocument toPosition:self.textField.selectedTextRange.start]; + BOOL cursorAtEnd = (index == self.textField.text.length); + + if (self.cardType == nil) { + return cursorAtEnd && self.cvv.length == kMaximumCvvLength; + } else { + return self.valid; + } +} + +- (BOOL)textField:(__unused UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { + return string.length + range.location <= self.validLength; +} + +- (NSUInteger)validLength { + return self.cardType == nil ? kMaximumCvvLength : self.cardType.validCvvLength; +} + +- (void)setCvv:(NSString *)cvv { + _cvv = cvv; + self.text = cvv; +} + +#pragma mark - Handlers + +- (void)fieldContentDidChange { + self.displayAsValid = YES; + _cvv = [BTUIUtil stripNonDigits:self.textField.text]; + [self.delegate formFieldDidChange:self]; +} + +- (void)textFieldDidBeginEditing:(UITextField *)textField { + [super textFieldDidBeginEditing:textField]; + self.displayAsValid = YES; + [self.hint setHighlighted:YES animated:YES]; +} + +- (void)textFieldDidEndEditing:(UITextField *)textField { + [super textFieldDidEndEditing:textField]; + self.displayAsValid = self.textField.text.length == 0 || self.valid; + [self.hint setHighlighted:NO animated:YES]; +} + + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardExpiryField.h b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardExpiryField.h new file mode 100644 index 0000000..54074fc --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardExpiryField.h @@ -0,0 +1,14 @@ +#import "BTUIFormField.h" + +@interface BTUICardExpiryField : BTUIFormField + +@property (nonatomic, strong, readonly) NSString *expirationMonth; +@property (nonatomic, strong, readonly) NSString *expirationYear; + +/** + @brief The expiration date in MMYYYY format. +*/ +@property (nonatomic, copy) NSString *expirationDate; + +@end + diff --git a/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardExpiryField.m b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardExpiryField.m new file mode 100644 index 0000000..fb6c67c --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardExpiryField.m @@ -0,0 +1,188 @@ +#import "BTUICardExpiryField.h" +#import "BTUIFormField_Protected.h" +#import "BTUIUtil.h" +#import "BTUICardExpirationValidator.h" +#import "BTUICardExpiryFormat.h" +#import "BTUILocalizedString.h" + +#define BTUICardExpiryFieldYYYYPrefix @"20" +#define BTUICardExpiryFieldComponentSeparator @"/" + +#define BTUICardExpiryPlaceholderFourDigitYear BTUILocalizedString(EXPIRY_PLACEHOLDER_FOUR_DIGIT_YEAR) +#define BTUICardExpiryPlaceholderTwoDigitYear BTUILocalizedString(EXPIRY_PLACEHOLDER_TWO_DIGIT_YEAR) + +@interface BTUICardExpiryField () +@end + +@implementation BTUICardExpiryField + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self updatePlaceholder]; + self.textField.keyboardType = UIKeyboardTypeNumberPad; + self.textField.delegate = self; + } + return self; +} + +- (BOOL)valid { + if (!self.expirationYear || !self.expirationMonth) { + return NO; + } + return [BTUICardExpirationValidator month:self.expirationMonth.intValue year:self.expirationYear.intValue validForDate:[NSDate date]]; +} + +- (void)setExpirationDate:(NSString *)expirationDate { + [self setText:expirationDate]; + } + +- (NSString *)expirationDate { + if (!self.expirationMonth || !self.expirationYear) return nil; + + return [NSString stringWithFormat:@"%@%@", self.expirationMonth, self.expirationYear]; +} + +#pragma mark - Handlers + +- (void)fieldContentDidChange { + _expirationMonth = nil; + _expirationYear = nil; + + NSString *formattedValue; + NSUInteger formattedCursorLocation; + + BTUICardExpiryFormat *format = [[BTUICardExpiryFormat alloc] init]; + format.value = self.textField.text; + format.cursorLocation = [self.textField offsetFromPosition:self.textField.beginningOfDocument toPosition:self.textField.selectedTextRange.start]; + format.backspace = self.backspace; + [format formattedValue:&formattedValue cursorLocation:&formattedCursorLocation]; + + // Important: Reset the state of self.backspace. + // Otherwise, the user won't be able to do the following: + // Enter "11/16", then backspace to + // "1", and then type e.g. "2". Instead of showing: + // "12/" (as it should), the form would instead remain stuck at + // "1". + self.backspace = NO; + // This is because UIControlEventEditingChanged is *not* sent after the "/" is removed. + // We can't trigger UIControlEventEditingChanged here (after removing a "/") because that would cause an infinite loop. + + NSMutableAttributedString *result = [[NSMutableAttributedString alloc] initWithString:formattedValue attributes:self.theme.textFieldTextAttributes]; + [self kernExpiration:result]; + self.textField.attributedText = result; + + UITextPosition *newPosition = [self.textField positionFromPosition:self.textField.beginningOfDocument offset:formattedCursorLocation]; + UITextRange *newRange = [self.textField textRangeFromPosition:newPosition toPosition:newPosition]; + self.textField.selectedTextRange = newRange; + + NSArray *expirationComponents = [self expirationComponents:self.textField.text]; + if(expirationComponents.count == 2 && (self.textField.text.length == 5 || self.textField.text.length == 7)) { + _expirationMonth = expirationComponents[0]; + _expirationYear = expirationComponents[1]; + } + + [self updatePlaceholder]; + + self.displayAsValid = ((self.textField.text.length != 5 && self.textField.text.length != 7) || self.valid); + + [self.delegate formFieldDidChange:self]; +} + +- (void)textFieldDidBeginEditing:(UITextField *)textField { + [super textFieldDidBeginEditing:textField]; + self.displayAsValid = YES; +} + +- (void)textFieldDidEndEditing:(UITextField *)textField { + [super textFieldDidEndEditing:textField]; + self.displayAsValid = self.textField.text.length == 0 || self.valid; +} + +- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)newText { + NSString *numericNewText = [BTUIUtil stripNonDigits:newText]; + if (![numericNewText isEqualToString:newText]) { + return NO; + } + NSString *updatedText = [textField.text stringByReplacingCharactersInRange:range withString:numericNewText]; + + return [self dateIsValid:updatedText]; +} + +- (BOOL)entryComplete { + return [super entryComplete] && ![self.expirationYear isEqualToString:BTUICardExpiryFieldYYYYPrefix]; +} + +#pragma mark Helper + +- (void)updatePlaceholder { + NSString *placeholder = [self dateCouldEndWithFourDigitYear:self.textField.text] ? BTUILocalizedString(EXPIRY_PLACEHOLDER_FOUR_DIGIT_YEAR) : BTUILocalizedString(EXPIRY_PLACEHOLDER_TWO_DIGIT_YEAR); + [self setThemedPlaceholder:placeholder]; + self.textField.accessibilityLabel = placeholder; +} + +- (void)setThemedPlaceholder:(NSString *)placeholder { + NSMutableAttributedString *attributedPlaceholder = [[NSMutableAttributedString alloc] initWithString:placeholder ?: @"" + attributes:self.theme.textFieldPlaceholderAttributes]; + [self kernExpiration:attributedPlaceholder]; + [self setThemedAttributedPlaceholder:attributedPlaceholder]; +} + +- (BOOL)dateCouldEndWithFourDigitYear:(NSString *)expirationDate { + NSArray *expirationComponents = [self expirationComponents:expirationDate]; + NSString *yearComponent = [expirationComponents count] >= 2 ? expirationComponents[1] : nil; + return (yearComponent && yearComponent.length >= 2 && [[yearComponent substringToIndex:2] isEqualToString:BTUICardExpiryFieldYYYYPrefix]); +} + +- (NSArray *)expirationComponents:(NSString *)expirationDate { + return [expirationDate componentsSeparatedByString:BTUICardExpiryFieldComponentSeparator]; +} + +- (void)kernExpiration:(NSMutableAttributedString *)input { + [input removeAttribute:NSKernAttributeName range:NSMakeRange(0, input.length)]; + + [input beginEditing]; + if (input.length > 2) { + [input addAttribute:NSKernAttributeName value:@(self.theme.formattedEntryKerning/2) range:NSMakeRange(1, 1)]; + if (input.length > 3) { + [input addAttribute:NSKernAttributeName value:@(self.theme.formattedEntryKerning/2) range:NSMakeRange(2, 1)]; + } + } + [input endEditing]; +} + +// Returns YES if date is either a valid date or can have digits appended to make one. It does not contain any expiration +// date validation. +- (BOOL)dateIsValid:(NSString *)date { + NSArray *dateComponents = [date componentsSeparatedByString:BTUICardExpiryFieldComponentSeparator]; + + NSString *yearComponent; + if (dateComponents.count >= 2) { + yearComponent = dateComponents[1]; + } else { + yearComponent = date.length >= 4 ? [date substringWithRange:NSMakeRange(2, date.length - 2)] : nil; + } + + BOOL couldEndWithFourDigitYear = yearComponent && yearComponent.length >= 2 && [[yearComponent substringToIndex:2] isEqualToString:BTUICardExpiryFieldYYYYPrefix]; + if (couldEndWithFourDigitYear ? date.length > 7 : date.length > 5) { + return NO; + } + + NSString *updatedNumberText = [BTUIUtil stripNonDigits:date]; + + NSString *monthStr = [updatedNumberText substringToIndex:MIN((NSUInteger)2, updatedNumberText.length)]; + if (monthStr.length > 0) { + NSInteger month = [monthStr integerValue]; + if(month < 0 || 12 < month) { + return NO; + } + if(monthStr.length >= 2 && month == 0) { + return NO; + } + } + + return YES; +} + + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardNumberField.h b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardNumberField.h new file mode 100644 index 0000000..1c156bd --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardNumberField.h @@ -0,0 +1,9 @@ +#import "BTUIFormField.h" +#import "BTUICardType.h" + +@interface BTUICardNumberField : BTUIFormField + +@property (nonatomic, strong, readonly) BTUICardType *cardType; +@property (nonatomic, strong) NSString *number; + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardNumberField.m b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardNumberField.m new file mode 100644 index 0000000..be0b028 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardNumberField.m @@ -0,0 +1,105 @@ +#import "BTUICardNumberField.h" +#import "BTUIFormField_Protected.h" +#import "BTUIUtil.h" +#import "BTUICardHint.h" +#import "BTUIViewUtil.h" +#import "BTUILocalizedString.h" + +@implementation BTUICardNumberField + +@synthesize number = _number; + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self setThemedPlaceholder:BTUILocalizedString(CARD_NUMBER_PLACEHOLDER)]; + self.textField.accessibilityLabel = BTUILocalizedString(CARD_NUMBER_PLACEHOLDER); + self.textField.keyboardType = UIKeyboardTypeNumberPad; + _number = @""; + + BTUICardHint *hint = [BTUICardHint new]; + [hint setCardType:BTUIPaymentOptionTypeUnknown]; + self.accessoryView = hint; + self.accessoryView.translatesAutoresizingMaskIntoConstraints = NO; + [self addSubview:self.accessoryView]; + } + return self; +} + +- (BOOL)valid { + return [self.cardType validNumber:self.number]; +} + +- (BOOL)entryComplete { + return [super entryComplete] && [self.cardType validAndNecessarilyCompleteNumber:self.number]; +} + +- (void)setNumber:(NSString *)number { + self.text = number; + _number = self.textField.text; +} + +- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { + NSUInteger newLength = textField.text.length - range.length + string.length; + NSUInteger maxLength = self.cardType == nil ? [BTUICardType maxNumberLength] : self.cardType.maxNumberLength; + return newLength <= maxLength; +} + +- (void)fieldContentDidChange { + _number = [BTUIUtil stripNonDigits:self.textField.text]; + BTUICardType *oldCardType = _cardType; + _cardType = [BTUICardType cardTypeForNumber:_number]; + if (self.cardType != nil) { + UITextRange *r = self.textField.selectedTextRange; + NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithAttributedString:[self.cardType formatNumber:_number kerning:self.theme.formattedEntryKerning]]; + [text addAttributes:self.theme.textFieldTextAttributes range:NSMakeRange(0, text.length)]; + self.textField.attributedText = text; + self.textField.selectedTextRange = r; + } + if (self.cardType != oldCardType) { + [self updateCardHint]; + } + + self.displayAsValid = self.valid || (!self.isValidLength && self.isPotentiallyValid); + + [self updateAppearance]; + [self setNeedsDisplay]; + + [self.delegate formFieldDidChange:self]; +} + +- (void)textFieldDidBeginEditing:(UITextField *)textField { + [super textFieldDidBeginEditing:textField]; + self.displayAsValid = self.valid || (!self.isValidLength && self.isPotentiallyValid); + [self updateAppearance]; +} + +- (void)textFieldDidEndEditing:(UITextField *)textField { + [super textFieldDidEndEditing:textField]; + self.displayAsValid = _number.length == 0 || (_cardType != nil && [_cardType validNumber:_number]); + [self updateAppearance]; +} + +#pragma mark - Private Helpers + +- (BOOL)isValidCardType { + return self.cardType != nil || _number.length == 0; +} + +- (BOOL)isPotentiallyValid { + return [BTUICardType possibleCardTypesForNumber:self.number].count > 0; +} + +- (BOOL)isValidLength { + return self.cardType != nil && [self.cardType completeNumber:_number]; +} + +- (void)updateCardHint { + BTUIPaymentOptionType paymentMethodType = [BTUIViewUtil paymentMethodTypeForCardType:self.cardType]; + BTUICardHint *hint =(BTUICardHint *)self.accessoryView; + [hint setCardType:paymentMethodType animated:YES]; +} + + + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardPhoneNumberField.h b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardPhoneNumberField.h new file mode 100644 index 0000000..059483e --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardPhoneNumberField.h @@ -0,0 +1,7 @@ +#import "BTUIFormField.h" + +@interface BTUICardPhoneNumberField : BTUIFormField + +@property (nonatomic, copy) NSString *phoneNumber; + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardPhoneNumberField.m b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardPhoneNumberField.m new file mode 100644 index 0000000..190cae0 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardPhoneNumberField.m @@ -0,0 +1,47 @@ +#import "BTUICardPhoneNumberField.h" +#import "BTUIFormField_Protected.h" +#import "BTUILocalizedString.h" +@import Contacts; + +@implementation BTUICardPhoneNumberField + +#define MAX_PHONE_NUMBER_DIGITS 11 + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self setThemedPlaceholder:BTUILocalizedString(PHONE_NUMBER_PLACEHOLDER)]; + self.textField.accessibilityLabel = BTUILocalizedString(PHONE_NUMBER_PLACEHOLDER); + self.textField.keyboardType = UIKeyboardTypeNumberPad; + } + return self; +} + +- (BOOL)valid { + return self.textField.text.length == MAX_PHONE_NUMBER_DIGITS; +} + +- (NSString *)phoneNumber { + return self.textField.text; +} + +- (void)setPhoneNumber:(NSString *)phoneNumber { + self.textField.text = phoneNumber; +} + +- (void)fieldContentDidChange { + if ([self.delegate respondsToSelector:@selector(formFieldDidChange:)]) { + [self.delegate formFieldDidChange:self]; + } +} + +- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { + NSUInteger oldLength = [textField.text length]; + NSUInteger replacementLength = [string length]; + NSUInteger rangeLength = range.length; + + NSUInteger newLength = oldLength - rangeLength + replacementLength; + return newLength <= MAX_PHONE_NUMBER_DIGITS; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardPostalCodeField.h b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardPostalCodeField.h new file mode 100644 index 0000000..6f02d9c --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardPostalCodeField.h @@ -0,0 +1,8 @@ +#import "BTUIFormField.h" + +@interface BTUICardPostalCodeField : BTUIFormField + +@property (nonatomic, strong) NSString *postalCode; +@property (nonatomic, assign) BOOL nonDigitsSupported; + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardPostalCodeField.m b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardPostalCodeField.m new file mode 100644 index 0000000..e8104e9 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Form Fields/BTUICardPostalCodeField.m @@ -0,0 +1,64 @@ +#import "BTUICardPostalCodeField.h" +#import "BTUIFormField_Protected.h" +#import "BTUILocalizedString.h" +#import "BTUIUtil.h" + +@implementation BTUICardPostalCodeField + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self setThemedPlaceholder:BTUILocalizedString(POSTAL_CODE_PLACEHOLDER)]; + self.textField.accessibilityLabel = BTUILocalizedString(POSTAL_CODE_PLACEHOLDER); + self.nonDigitsSupported = NO; + self.textField.autocorrectionType = UITextAutocorrectionTypeNo; + self.textField.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters; + self.textField.returnKeyType = UIReturnKeyDone; + } + return self; +} + +- (void)setPostalCode:(NSString *)postalCode { + if (!self.nonDigitsSupported) { + NSString *numericPostalCode = [BTUIUtil stripNonDigits:postalCode]; + if (![numericPostalCode isEqualToString:postalCode]) return; + } + _postalCode = postalCode; + self.text = postalCode; +} + +- (void)setNonDigitsSupported:(BOOL)nonDigitsSupported { + _nonDigitsSupported = nonDigitsSupported; + self.textField.autocorrectionType = UITextAutocorrectionTypeNo; + self.textField.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters; + self.textField.keyboardType = _nonDigitsSupported ? UIKeyboardTypeNumbersAndPunctuation : UIKeyboardTypeNumberPad; +} + +- (BOOL)entryComplete { + // Never allow auto-advancing out of postal code field since there is no way to know that the + // input value constitutes a complete postal code. + return NO; +} + +- (BOOL)valid { + return self.postalCode.length > 0; +} + +- (void)fieldContentDidChange { + _postalCode = [self.textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + self.displayAsValid = YES; + [super fieldContentDidChange]; + [self.delegate formFieldDidChange:self]; +} + +- (void)textFieldDidBeginEditing:(UITextField *)textField { + self.displayAsValid = YES; + [super textFieldDidBeginEditing:textField]; +} + +- (void)textFieldDidEndEditing:(UITextField *)textField { + self.displayAsValid = YES; + [super textFieldDidEndEditing:textField]; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Forms/BTUICardFormView.m b/Pods/Braintree/BraintreeUI/Views/Forms/BTUICardFormView.m new file mode 100644 index 0000000..2fe8ec5 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Forms/BTUICardFormView.m @@ -0,0 +1,366 @@ +#import "BTUICardFormView.h" +#import "BTUICardNumberField.h" +#import "BTUICardExpiryField.h" +#import "BTUICardCvvField.h" +#import "BTUICardPhoneNumberField.h" +#import "BTUICardPostalCodeField.h" +#import "BTUI.h" +#import "BTUILocalizedString.h" +#import "BTUIViewUtil.h" + +@interface BTUICardFormView () + +@property (nonatomic, strong) BTUICardNumberField *numberField; +@property (nonatomic, strong) BTUICardExpiryField *expiryField; +@property (nonatomic, strong) BTUICardCvvField *cvvField; +@property (nonatomic, strong) BTUICardPostalCodeField *postalCodeField; +@property (nonatomic, strong) BTUICardPhoneNumberField *phoneNumberField; + +@property (nonatomic, strong) NSArray *fields; +@property (nonatomic, strong) NSArray *dynamicConstraints; +@property (nonatomic, assign, readwrite) BOOL valid; +@property (nonatomic, assign) BTUIPaymentOptionType lastPaymentMethodType; + +@end + +@implementation BTUICardFormView + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self setup]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + [self setup]; + } + return self; +} + +- (CGSize)intrinsicContentSize { + CGFloat height = 0; + for (BTUIFormField *field in self.fields) { + height += field.intrinsicContentSize.height; + } + // subtract (number of field adjacencies) * (number of pixels overlap per adjacency) + height -= (self.fields.count - 1) * 1; + + return CGSizeMake(UIViewNoIntrinsicMetric, height); +} + +#pragma mark - Getters/setters + +- (void)showErrorForField:(__unused BTUICardFormField)field { + switch (field) { + case BTUICardFormFieldNumber: + self.numberField.displayAsValid = NO; + break; + case BTUICardFormFieldExpiration: + self.expiryField.displayAsValid = NO; + break; + case BTUICardFormFieldCvv: + self.cvvField.displayAsValid = NO; + break; + case BTUICardFormFieldPostalCode: + self.postalCodeField.displayAsValid = NO; + break; + case BTUICardFormFieldPhoneNumber: + self.phoneNumberField.displayAsValid = NO; + break; + } +} + +- (void)showTopLevelError:(NSString *)message { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + NSString *localizedOK = BTUILocalizedString(TOP_LEVEL_ERROR_ALERT_VIEW_OK_BUTTON_TEXT); + [[[UIAlertView alloc] initWithTitle:message + message:nil + delegate:nil + cancelButtonTitle:localizedOK + otherButtonTitles:nil] show]; +#pragma clang diagnostic pop +} + +- (void)setAlphaNumericPostalCode:(BOOL)alphaNumericPostalCode { + _alphaNumericPostalCode = alphaNumericPostalCode; + self.postalCodeField.nonDigitsSupported = alphaNumericPostalCode; +} + +- (void)setOptionalFields:(BTUICardFormOptionalFields)optionalFields { + _optionalFields = optionalFields; + + NSArray *defaultFields = @[self.numberField, self.expiryField]; + NSMutableArray *fields = [defaultFields mutableCopy]; + + self.cvvField.hidden = self.postalCodeField.hidden = self.phoneNumberField.hidden = YES; + if (optionalFields & BTUICardFormOptionalFieldsPostalCode) { + [fields addObject:self.postalCodeField]; + self.postalCodeField.hidden = NO; + } + if (optionalFields & BTUICardFormOptionalFieldsCvv) { + [fields addObject:self.cvvField]; + self.cvvField.hidden = NO; + } + if (optionalFields & BTUICardFormOptionalFieldsPhoneNumber) { + [fields addObject:self.phoneNumberField]; + self.phoneNumberField.hidden = NO; + } + + // Set bottom border for fields + for (NSUInteger i = 0; i < fields.count - 1; i++) { + [fields[i] setBottomBorder:YES]; + } + [[fields lastObject] setBottomBorder:NO]; + + self.fields = fields; + + [self invalidateIntrinsicContentSize]; +} + +- (void)setExpirationDate:(NSDate *)expirationDate { + static NSDateFormatter *dateFormatter; + if (!dateFormatter) { + dateFormatter = [[NSDateFormatter alloc] init]; + // The expiry field only allows digit chars to be entered + dateFormatter.dateFormat = @"MMyyyy"; + } + + NSString *expirationDateString = [dateFormatter stringFromDate:expirationDate]; + [self.expiryField setText:expirationDateString]; +} + +- (void)setExpirationMonth:(NSInteger)expirationMonth year:(NSInteger)expirationYear { + NSString *expirationMonthString = expirationMonth < 10 ? [NSString stringWithFormat:@"0%ld", (long)expirationMonth] : [NSString stringWithFormat:@"%ld", (long)expirationMonth]; + NSString *expirationYearString = expirationYear < 100 ? [NSString stringWithFormat:@"20%ld", (long)expirationYear] : [NSString stringWithFormat:@"%ld", (long)expirationYear]; + self.expiryField.text = [NSString stringWithFormat:@"%@%@", expirationMonthString, expirationYearString]; +} + +- (NSString *)phoneNumber { + return self.phoneNumberField.text.length > 0 ? self.phoneNumberField.text : nil; +} + +- (void)setup { + self.opaque = NO; + self.backgroundColor = [UIColor whiteColor]; + + self.dynamicConstraints = @[]; + + _numberField = [[BTUICardNumberField alloc] init]; + self.numberField.translatesAutoresizingMaskIntoConstraints = NO; + self.numberField.delegate = self; + [self addSubview:self.numberField]; + + _expiryField = [[BTUICardExpiryField alloc] init]; + self.expiryField.translatesAutoresizingMaskIntoConstraints = NO; + self.expiryField.delegate = self; + [self addSubview:self.expiryField]; + + _cvvField = [[BTUICardCvvField alloc] init]; + self.cvvField.translatesAutoresizingMaskIntoConstraints = NO; + self.cvvField.delegate = self; + [self addSubview:self.cvvField]; + + _postalCodeField = [[BTUICardPostalCodeField alloc] init]; + self.postalCodeField.translatesAutoresizingMaskIntoConstraints = NO; + self.postalCodeField.delegate = self; + [self addSubview:self.postalCodeField]; + [self setAlphaNumericPostalCode:YES]; + + self.phoneNumberField = [[BTUICardPhoneNumberField alloc] init]; + self.phoneNumberField.translatesAutoresizingMaskIntoConstraints = NO; + self.phoneNumberField.delegate = self; + [self addSubview:self.phoneNumberField]; + + self.vibrate = YES; + self.optionalFields = BTUICardFormOptionalFieldsAll; + + for (UIView *v in self.fields) { + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[v]|" options:0 metrics:@{} views:@{@"v": v}]]; + } + + + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[v]" + options:0 + metrics:0 + views:@{@"v": self.numberField}]]; + +} + +- (void)updateConstraints { + [self removeConstraints:self.dynamicConstraints]; + + NSMutableArray *newContraints = [NSMutableArray array]; + for (NSUInteger i = 0; i < self.fields.count - 1; i++) { + BTUIFormField *fieldAbove = self.fields[i]; + BTUIFormField *fieldBelow = self.fields[i+1]; + [newContraints addObjectsFromArray:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[v]-(-1)-[v2]" + options:0 + metrics:0 + views:@{@"v": fieldAbove, @"v2": fieldBelow }]]; + } + + self.dynamicConstraints = newContraints; + [self addConstraints:self.dynamicConstraints]; + + [super updateConstraints]; + +} + +#pragma mark - Theme + +- (void)setTheme:(BTUI *)theme { + [super setTheme:theme]; + + _numberField.theme = theme; + _expiryField.theme = theme; + _cvvField.theme = theme; + _postalCodeField.theme = theme; +} + +#pragma mark - Drawing + +- (void)drawRect:(CGRect)rect { + CGContextRef context = UIGraphicsGetCurrentContext(); + [self.theme.borderColor setFill]; + + // Top + CGPathRef path = CGPathCreateWithRect(CGRectMake(rect.origin.x, 0, rect.size.width, 0.5f), NULL); + CGContextAddPath(context, path); + CGPathRelease(path); + + // Bottom + path = CGPathCreateWithRect(CGRectMake(rect.origin.x, CGRectGetMaxY(rect) - 0.5f, rect.size.width, 0.5f), NULL); + CGContextAddPath(context, path); + + CGContextDrawPath(context, kCGPathFill); + CGPathRelease(path); +} + +#pragma mark - Validity + +- (BOOL)valid { + _valid = YES; + for (BTUIFormField *f in self.fields) { + if (!f.valid) { + _valid = NO; + } + } + return _valid; +} + +- (void)setVibrate:(BOOL)vibrate { + _vibrate = vibrate; + for (BTUIFormField *f in self.fields) { + f.vibrateOnInvalidInput = vibrate; + } +} + +#pragma mark - Value getters + +- (NSString *)number { + return self.numberField.number; +} + +- (void)setNumber:(NSString *)number { + self.numberField.number = number; +} + +- (NSString *)expirationMonth { + return self.expiryField.expirationMonth; +} + +- (NSString *)expirationYear { + return self.expiryField.expirationYear; +} + +- (NSString *)cvv { + return self.optionalFields & BTUICardFormOptionalFieldsCvv ? self.cvvField.cvv : nil; +} + +- (void)setCvv:(NSString *)cvv { + self.cvvField.cvv = cvv; +} + +- (NSString *)postalCode { + return self.optionalFields & BTUICardFormOptionalFieldsPostalCode ? self.postalCodeField.postalCode : nil; +} + +- (void)setPostalCode:(NSString *)postalCode { + self.postalCodeField.postalCode = postalCode; +} + +#pragma mark - Field delegate implementations + +- (void)formFieldDidChange:(BTUIFormField *)field { + if (field == self.numberField) { + self.cvvField.cardType = self.numberField.cardType; + } + [self advanceToNextInvalidFieldFrom:field]; + // Trigger KVO + self.valid = self.valid; + if ([self.delegate respondsToSelector:@selector(cardFormViewDidChange:)]) { + [self.delegate cardFormViewDidChange:self]; + } +} + +- (void)formFieldDidBeginEditing:(__unused BTUIFormField *)field { + if ([self.delegate respondsToSelector:@selector(cardFormViewDidBeginEditing:)]) { + [self.delegate cardFormViewDidBeginEditing:self]; + } +} + +- (void)formFieldDidEndEditing:(__unused BTUIFormField *)field { + if ([self.delegate respondsToSelector:@selector(cardFormViewDidEndEditing:)]) { + [self.delegate cardFormViewDidEndEditing:self]; + } +} + +- (void)formFieldDidDeleteWhileEmpty:(BTUIFormField *)formField { + [self switchToPreviousField:formField]; +} + +- (BOOL)formFieldShouldReturn:(BTUIFormField *)formField { + [formField resignFirstResponder]; + return NO; +} + +#pragma mark - Auto-advancing + +- (void)advanceToNextInvalidFieldFrom:(BTUIFormField *)field { + if (field.entryComplete) { + NSUInteger fieldIndex = [self.fields indexOfObject:field]; + NSUInteger startIndex = (fieldIndex + 1) % self.fields.count; + + for (NSUInteger i = startIndex ; i != fieldIndex; i = (i + 1) % self.fields.count) { + BTUIFormField *ithField = self.fields[i]; + if (!ithField.valid) { + [ithField becomeFirstResponder]; + break; + } + } + } +} + +- (void)switchToPreviousField:(BTUIFormField *)field { + NSUInteger fieldIndex = [self.fields indexOfObject:field]; + if (fieldIndex == 0) { + return; + } + NSInteger previousIndex = (fieldIndex - 1); + if (previousIndex < 0) { + return; + } + BTUIFormField *previousField = self.fields[previousIndex]; + [previousField becomeFirstResponder]; + if (previousField.text.length > 0) { + [previousField deleteBackward]; + } +} + + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUICTAControl.m b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUICTAControl.m new file mode 100644 index 0000000..41df424 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUICTAControl.m @@ -0,0 +1,151 @@ +#import "BTUI.h" +#import "BTUICTAControl.h" +#import "UIColor+BTUI.h" + +@interface BTUICTAControl() +@property (nonatomic, strong) UILabel *label; +@property (nonatomic, strong) UIActivityIndicatorView *activityIndicator; +@end + +@implementation BTUICTAControl + +- (id)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self setupView]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + [self setupView]; + } + return self; +} + +#pragma mark View Lifecycle + +- (void)setupView { + self.theme = [BTUI braintreeTheme]; + self.backgroundColor = self.tintColor; + + self.label = [[UILabel alloc] init]; + [self.label setTranslatesAutoresizingMaskIntoConstraints:NO]; + + self.label.textColor = [UIColor whiteColor]; + self.label.font = [UIFont systemFontOfSize:17.0f]; + self.label.textAlignment = NSTextAlignmentCenter; + + [self addSubview:self.label]; + + self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; + self.activityIndicator.translatesAutoresizingMaskIntoConstraints = NO; + [self addSubview:self.activityIndicator]; + + [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]]; + [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0.0f]]; + + self.isAccessibilityElement = YES; + self.accessibilityTraits = UIAccessibilityTraitButton; + + [self updateText]; +} + +- (void)showLoadingState: (__unused BOOL)loadingState{ + if (loadingState) { + self.label.hidden = YES; + [self.activityIndicator startAnimating]; + } else { + self.label.hidden = NO; + [self.activityIndicator stopAnimating]; + } +} + +- (void)updateConstraints { + [self addConstraints:@[[NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeCenterX + relatedBy:NSLayoutRelationEqual + toItem:self.label + attribute:NSLayoutAttributeCenterX + multiplier:1.0f + constant:0.0f], + + [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeCenterY + relatedBy:NSLayoutRelationEqual + toItem:self.label + attribute:NSLayoutAttributeCenterY + multiplier:1.0f + constant:0.0f], + + [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeWidth + relatedBy:NSLayoutRelationEqual + toItem:self.label + attribute:NSLayoutAttributeWidth + multiplier:1.0f + constant:0.0f], + + [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeHeight + relatedBy:NSLayoutRelationEqual + toItem:self.label + attribute:NSLayoutAttributeHeight + multiplier:1.0f + constant:0.0f], + ]]; + [super updateConstraints]; +} + +#pragma mark Highlight Presentation + +- (void)setHighlighted:(BOOL)highlighted { + [super setHighlighted:highlighted]; + UIColor *newColor = highlighted ? [self.tintColor bt_adjustedBrightness:self.theme.highlightedBrightnessAdjustment] : self.tintColor; + [UIView animateWithDuration:self.theme.quickTransitionDuration animations:^{ + [self setBackgroundColor:newColor]; + }]; +} + +- (void)setEnabled:(BOOL)enabled { + [super setEnabled:enabled]; + UIColor *newColor = enabled ? self.tintColor : self.theme.disabledButtonColor; + [UIView animateWithDuration:self.theme.quickTransitionDuration animations:^{ + [self setBackgroundColor:newColor]; + }]; +} + + +#pragma mark Public Parameters + +- (void)setDisplayAmount:(NSString *)displayAmount { + _displayAmount = displayAmount; + [self updateText]; +} + +- (void)setCallToAction:(NSString *)callToAction { + _callToAction = callToAction; + [self updateText]; +} + +#pragma mark State Management + +- (void)updateText { + if (self.displayAmount) { + self.label.text = [NSString stringWithFormat:@"%@ - %@", self.displayAmount, self.callToAction]; + } else { + self.label.text = [NSString stringWithFormat:@"%@", self.callToAction]; + } + self.accessibilityLabel = self.label.text; +} + +#pragma mark - Theme + +- (void)tintColorDidChange { + self.highlighted = self.highlighted; + self.enabled = self.enabled; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUICardHint.m b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUICardHint.m new file mode 100644 index 0000000..1d05a6c --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUICardHint.m @@ -0,0 +1,185 @@ +#import "BTUICardHint.h" + +#import "BTUI.h" + +#import "BTUICVVFrontVectorArtView.h" +#import "BTUICVVBackVectorArtView.h" + +@interface BTUICardHint () +@property (nonatomic, strong) UIView *hintVectorArtView; +@property (nonatomic, strong) NSArray *hintVectorArtViewConstraints; +@end + +@implementation BTUICardHint + +- (id)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self setupView]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + [self setupView]; + } + return self; +} + +- (void)setupView { + self.layer.borderColor = self.theme.cardHintBorderColor.CGColor; + self.layer.borderWidth = 1.0f; + self.layer.cornerRadius = 2.0f; + + self.hintVectorArtView = [[BTUI braintreeTheme] vectorArtViewForPaymentOptionType:BTUIPaymentOptionTypeUnknown]; + [self.hintVectorArtView setTranslatesAutoresizingMaskIntoConstraints:NO]; + [self addSubview:self.hintVectorArtView]; + + [self addConstraint:[NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeWidth + relatedBy:NSLayoutRelationEqual + toItem:self + attribute:NSLayoutAttributeHeight + multiplier:87.0f/55.0f + constant:0.0f]]; + + [self setNeedsLayout]; +} + +- (void)updateConstraints { + if (self.hintVectorArtViewConstraints) { + [self removeConstraints:self.hintVectorArtViewConstraints]; + } + + self.hintVectorArtViewConstraints = @[[NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeWidth + relatedBy:NSLayoutRelationEqual + toItem:self.hintVectorArtView + attribute:NSLayoutAttributeWidth + multiplier:1.0f + constant:1.0f], + + [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeCenterX + relatedBy:NSLayoutRelationEqual + toItem:self.hintVectorArtView + attribute:NSLayoutAttributeCenterX + multiplier:1.0f + constant:0.0f], + + [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeCenterY + relatedBy:NSLayoutRelationEqual + toItem:self.hintVectorArtView + attribute:NSLayoutAttributeCenterY + multiplier:1.0f + constant:0.0f] ]; + + [self addConstraints:self.hintVectorArtViewConstraints]; + + [super updateConstraints]; +} + +- (void)updateViews { + UIView *cardVectorArtView; + switch (self.displayMode) { + case BTCardHintDisplayModeCardType: + cardVectorArtView = [[BTUI braintreeTheme] vectorArtViewForPaymentOptionType:self.cardType]; + break; + case BTCardHintDisplayModeCVVHint: + if (self.cardType == BTUIPaymentOptionTypeAMEX) { + cardVectorArtView = [BTUICVVFrontVectorArtView new]; + } else { + cardVectorArtView = [BTUICVVBackVectorArtView new]; + } + break; + } + + [self.hintVectorArtView removeFromSuperview]; + self.hintVectorArtView = cardVectorArtView; + [self.hintVectorArtView setTranslatesAutoresizingMaskIntoConstraints:NO]; + [self addSubview:self.hintVectorArtView]; + [self setHighlighted:self.highlighted]; + + [self setNeedsUpdateConstraints]; + [self setNeedsLayout]; +} + +- (void)setCardType:(BTUIPaymentOptionType)cardType { + _cardType = cardType; + [self updateViews]; +} + +- (void)setCardType:(BTUIPaymentOptionType)cardType animated:(BOOL)animated { + if (cardType == self.cardType) { + return; + } + if (animated) { + [UIView transitionWithView:self + duration:0.2f + options:UIViewAnimationOptionTransitionCrossDissolve + animations:^{ + [self setCardType:cardType]; + } completion:nil]; + } else { + [self setCardType:cardType]; + } +} + +- (void)setDisplayMode:(BTCardHintDisplayMode)displayMode { + _displayMode = displayMode; + [self updateViews]; +} + +- (void)setDisplayMode:(BTCardHintDisplayMode)displayMode animated:(BOOL)animated { + if (animated) { + [UIView transitionWithView:self + duration:0.2f + options:UIViewAnimationOptionTransitionFlipFromLeft + animations:^{ + [self setDisplayMode:displayMode]; + } completion:nil]; + } else { + [self updateViews]; + } +} + +#pragma mark - Highlighting + +- (void)setHighlighted:(BOOL)highlighted { + [self setHighlighted:highlighted animated:NO]; +} + +- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated { + _highlighted = highlighted; + UIColor *c = highlighted ? self.tintColor : nil; + [self setHighlightColor:c animated:animated]; +} + +- (void)setHighlightColor:(UIColor *)color animated:(BOOL)animated { + if (![self.hintVectorArtView respondsToSelector:@selector(setHighlightColor:)]) { + return; + } + if (animated) { + [UIView transitionWithView:self.hintVectorArtView + duration:self.theme.quickTransitionDuration + options:UIViewAnimationOptionTransitionCrossDissolve + animations:^{ + [self.hintVectorArtView performSelector:@selector(setHighlightColor:) withObject:color]; + [self.hintVectorArtView setNeedsDisplay]; + } + completion:nil + ]; + } else { + [self.hintVectorArtView performSelector:@selector(setHighlightColor:) withObject:color]; + [self.hintVectorArtView setNeedsDisplay]; + } +} + +- (void)tintColorDidChange { + [self setHighlighted:self.highlighted animated:YES]; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUICoinbaseButton.m b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUICoinbaseButton.m new file mode 100644 index 0000000..d27a938 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUICoinbaseButton.m @@ -0,0 +1,87 @@ +#import "BTUICoinbaseButton.h" + +#import "BTUI.h" +#import "UIColor+BTUI.h" + +#import "BTUICoinbaseWordmarkVectorArtView.h" +#import "BTUILocalizedString.h" + +@interface BTUICoinbaseButton () +@property (nonatomic, strong) BTUICoinbaseWordmarkVectorArtView *coinbaseWordmark; +@end + +@implementation BTUICoinbaseButton + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self setupView]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + [self setupView]; + } + return self; +} + +- (void)setupView { + self.theme = [BTUI braintreeTheme]; + self.userInteractionEnabled = YES; + self.clipsToBounds = YES; + self.opaque = NO; + self.backgroundColor = [UIColor whiteColor]; + self.accessibilityLabel = [BTUILocalizedString PAYMENT_METHOD_TYPE_COINBASE]; + + self.coinbaseWordmark = [[BTUICoinbaseWordmarkVectorArtView alloc] init]; + self.coinbaseWordmark.userInteractionEnabled = NO; + self.coinbaseWordmark.translatesAutoresizingMaskIntoConstraints = NO; + self.coinbaseWordmark.color = [self.theme coinbasePrimaryBlue]; + + [self addSubview:self.coinbaseWordmark]; +} + +- (void)updateConstraints { + NSDictionary *metrics = @{ @"minHeight": @([self.theme paymentButtonMinHeight]), + @"maxHeight": @([self.theme paymentButtonMaxHeight]), + @"minWidth": @(200), + @"required": @(UILayoutPriorityRequired), + @"high": @(UILayoutPriorityDefaultHigh), + @"breathingRoom": @(10) }; + NSDictionary *views = @{ @"self": self , + @"coinbaseWordmark": self.coinbaseWordmark }; + + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[coinbaseWordmark]|" + options:0 + metrics:metrics + views:views]]; + + [self addConstraint:[NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeCenterX + relatedBy:NSLayoutRelationEqual + toItem:self.coinbaseWordmark + attribute:NSLayoutAttributeCenterX + multiplier:1.0f + constant:0.0f]]; + + [super updateConstraints]; +} + +- (void)setHighlighted:(BOOL)highlighted { + [UIView animateWithDuration:0.08f + delay:0.0f + options:UIViewAnimationOptionBeginFromCurrentState animations:^{ + if (highlighted) { + self.backgroundColor = [UIColor colorWithWhite:0.92f alpha:1.0f]; + } else { + self.backgroundColor = [UIColor whiteColor]; + } + } + completion:nil]; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUIPayPalButton.m b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUIPayPalButton.m new file mode 100644 index 0000000..f734224 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUIPayPalButton.m @@ -0,0 +1,84 @@ +#import "BTUI.h" +#import "BTUIPayPalButton.h" +#import "BTUIPayPalWordmarkVectorArtView.h" + +@implementation BTUIPayPalButton + +#define PAYPAL_BUTTON_COLOR [UIColor colorWithRed:0 green:156/255.0 blue:222/255.0 alpha:1] +#define PAYPAL_BUTTON_HIGHLIGHTED [UIColor colorWithRed:0 green:138/255.0 blue:197/255.0 alpha:1] + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self setupView]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + [self setupView]; + } + return self; +} + +- (void)setupView { + self.theme = [BTUI braintreeTheme]; + self.userInteractionEnabled = YES; + self.clipsToBounds = YES; + self.opaque = NO; + self.backgroundColor = PAYPAL_BUTTON_COLOR; + + self.payPalWordmark = [[BTUIPayPalWordmarkVectorArtView alloc] initWithPadding]; + self.payPalWordmark.userInteractionEnabled = NO; + self.payPalWordmark.translatesAutoresizingMaskIntoConstraints = NO; + + [self addSubview:self.payPalWordmark]; +} + +- (void)updateConstraints { + NSDictionary *metrics = @{ @"minHeight": @([self.theme paymentButtonMinHeight]), + @"maxHeight": @([self.theme paymentButtonMaxHeight]), + @"minWidth": @(200), + @"required": @(UILayoutPriorityRequired), + @"high": @(UILayoutPriorityDefaultHigh), + @"breathingRoom": @(10) }; + NSDictionary *views = @{ @"self": self , + @"payPalWordmark": self.payPalWordmark }; + + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[payPalWordmark]|" + options:0 + metrics:metrics + views:views]]; + + [self addConstraint:[NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeCenterX + relatedBy:NSLayoutRelationEqual + toItem:self.payPalWordmark + attribute:NSLayoutAttributeCenterX + multiplier:1.0f + constant:0.0f]]; + + [super updateConstraints]; +} + +- (CGSize)intrinsicContentSize { + return CGSizeMake(UIViewNoIntrinsicMetric, 44); +} + +- (void)setHighlighted:(BOOL)highlighted { + [UIView animateWithDuration:0.08f + delay:0.0f + options:UIViewAnimationOptionBeginFromCurrentState animations:^{ + if (highlighted) { + self.backgroundColor = PAYPAL_BUTTON_HIGHLIGHTED; + } else { + self.backgroundColor = PAYPAL_BUTTON_COLOR; + } + } + completion:nil]; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUIPayPalCompactButton.h b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUIPayPalCompactButton.h new file mode 100644 index 0000000..0b15fd4 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUIPayPalCompactButton.h @@ -0,0 +1,5 @@ +#import "BTUIPayPalButton.h" + +@interface BTUIPayPalCompactButton : BTUIPayPalButton + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUIPayPalCompactButton.m b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUIPayPalCompactButton.m new file mode 100644 index 0000000..aadee03 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUIPayPalCompactButton.m @@ -0,0 +1,49 @@ +#import "BTUIPayPalCompactButton.h" +#import "BTUIPayPalWordmarkCompactVectorArtView.h" + +@interface BTUIPayPalCompactButton () +@end + +@implementation BTUIPayPalCompactButton + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self setupView]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + [self setupView]; + } + return self; +} + +- (void)setupView { + self.backgroundColor = [UIColor whiteColor]; + + self.payPalWordmark = [[BTUIPayPalWordmarkCompactVectorArtView alloc] initWithPadding]; + self.payPalWordmark.userInteractionEnabled = NO; + self.payPalWordmark.translatesAutoresizingMaskIntoConstraints = NO; + + [self addSubview:self.payPalWordmark]; +} + +- (void)setHighlighted:(BOOL)highlighted { + [UIView animateWithDuration:0.08f + delay:0.0f + options:UIViewAnimationOptionBeginFromCurrentState animations:^{ + if (highlighted) { + self.backgroundColor = [UIColor colorWithWhite:0.92f alpha:1.0f]; + } else { + self.backgroundColor = [UIColor whiteColor]; + } + } + completion:nil]; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUIPaymentMethodView.m b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUIPaymentMethodView.m new file mode 100644 index 0000000..7518186 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUIPaymentMethodView.m @@ -0,0 +1,229 @@ +#import "BTUI.h" +#import "BTUICardType.h" +#import "BTUIPaymentMethodView.h" +#import "BTUIUnknownCardVectorArtView.h" +#import "BTUIViewUtil.h" + +typedef NS_ENUM(NSInteger, BTPaymentMethodViewState) { + BTPaymentMethodViewStateNormal, + BTPaymentMethodViewStateProcessing, +}; + +@interface BTUIPaymentMethodView () + +@property (nonatomic, assign) BTPaymentMethodViewState contentState; + +@property (nonatomic, strong) UIView *iconView; +@property (nonatomic, strong) UILabel *typeLabel; +@property (nonatomic, strong) UILabel *detailDescriptionLabel; +@property (nonatomic, strong) UIActivityIndicatorView *activityIndicatorView; + +@property (nonatomic, strong) UIView *topBorder; +@property (nonatomic, strong) UIView *bottomBorder; + +@property (nonatomic, strong) NSArray *centeredLogoConstraints; +@property (nonatomic, strong) NSArray *logoEmailConstraints; + +@end + +@implementation BTUIPaymentMethodView + +- (instancetype)init { + self = [self initWithFrame:CGRectZero]; + return self; +} + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self setupViews]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + [self setupViews]; + } + return self; +} + ++ (BOOL)requiresConstraintBasedLayout { + return YES; +} + +- (void)setupViews { + + self.clipsToBounds = YES; + + self.iconView = [BTUIUnknownCardVectorArtView new]; + [self.iconView setTranslatesAutoresizingMaskIntoConstraints:NO]; + + self.typeLabel = [[UILabel alloc] init]; + [self.typeLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; + self.typeLabel.font = [self.theme controlTitleFont]; + [self.typeLabel setTextColor:[self.theme titleColor]]; + [self.typeLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; + [self.typeLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; + + self.detailDescriptionLabel = [[UILabel alloc] init]; + [self.detailDescriptionLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; + self.detailDescriptionLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; + self.detailDescriptionLabel.font = [self.theme controlDetailFont]; + [self.detailDescriptionLabel setTextColor:[self.theme detailColor]]; + + // Activity Indicators + self.activityIndicatorView = [[UIActivityIndicatorView alloc] init]; + self.activityIndicatorView.hidden = YES; + [self.activityIndicatorView setTranslatesAutoresizingMaskIntoConstraints:NO]; + + self.topBorder = [[UIView alloc] init]; + self.topBorder.backgroundColor = [self.theme borderColor]; + self.topBorder.translatesAutoresizingMaskIntoConstraints = NO; + + self.bottomBorder = [[UIView alloc] init]; + self.bottomBorder.backgroundColor = [self.theme borderColor]; + self.bottomBorder.translatesAutoresizingMaskIntoConstraints = NO; + + [self addSubview:self.iconView]; + [self addSubview:self.typeLabel]; + [self addSubview:self.detailDescriptionLabel]; + [self addSubview:self.activityIndicatorView]; + [self addSubview:self.topBorder]; + [self addSubview:self.bottomBorder]; + + // Setup initial state + self.contentState = BTPaymentMethodViewStateNormal; + + // Setup views based on initial state + [self updateSubviews]; +} + +- (void)updateConstraints { + [self removeConstraints:self.constraints]; + + NSDictionary *views = @{ @"topBorder": self.topBorder, + @"bottomBorder": self.bottomBorder, + @"methodTypeView": self.typeLabel, + @"emailView": self.detailDescriptionLabel, + @"activityIndicatorView": self.activityIndicatorView, + @"iconView": self.iconView }; + NSDictionary *metrics = @{ @"logoWidth": @30, + @"pad": @12, + @"sp": @5, + @"activityIndicatorViewSize": @60, + @"iconViewHeight": @21, + @"borderWidth": @(self.theme.borderWidth * 1) }; + + NSLayoutConstraint *constraint; + + // Minimum height + constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:40.0f]; + constraint.priority = UILayoutPriorityRequired; + [self addConstraint:constraint]; + + // Maximum height + constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationLessThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:60.0f]; + constraint.priority = UILayoutPriorityRequired; + [self addConstraint:constraint]; + + // Minimum width + constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:260.0f]; + constraint.priority = UILayoutPriorityRequired; + [self addConstraint:constraint]; + + // Centered activity indicator + [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicatorView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0f constant:0.0f]]; + [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicatorView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0f constant:0.0f]]; + + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[activityIndicatorView(==activityIndicatorViewSize)]" options:0 metrics:metrics views:views]]; + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[activityIndicatorView(==activityIndicatorViewSize)]" options:0 metrics:metrics views:views]]; + + // Full Width Borders + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[topBorder]|" options:0 metrics:metrics views:views]]; + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topBorder(==borderWidth)]" options:0 metrics:metrics views:views]]; + + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[bottomBorder]|" options:0 metrics:metrics views:views]]; + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[bottomBorder(==borderWidth)]|" options:0 metrics:metrics views:views]]; + + // Icon & type + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[iconView(==iconViewHeight)]" + options:0 + metrics:metrics + views:views]]; + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(pad)-[iconView]-sp-[methodTypeView]" + options:NSLayoutFormatAlignAllCenterY + metrics:metrics + views:views]]; + + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[methodTypeView]-sp-[emailView]" + options:NSLayoutFormatAlignAllBaseline + metrics:metrics + views:views]]; + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[emailView]-(pad)-|" + options:NSLayoutFormatAlignAllBaseline + metrics:metrics + views:views]]; + [self addConstraint:[NSLayoutConstraint constraintWithItem:self.iconView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1 constant:0.0f]]; + + [super updateConstraints]; +} + +- (void)updateSubviews { + switch (self.contentState) { + case BTPaymentMethodViewStateNormal: + self.typeLabel.text = [BTUIViewUtil nameForPaymentMethodType:self.type]; + self.detailDescriptionLabel.text = self.detailDescription; + [self.iconView removeFromSuperview]; + self.iconView = [self.theme vectorArtViewForPaymentOptionType:self.type]; + [self.iconView setTranslatesAutoresizingMaskIntoConstraints:NO]; + [self addSubview:self.iconView]; + + self.backgroundColor = [UIColor whiteColor]; + self.layer.borderColor = [self.theme borderColor].CGColor; + self.iconView.alpha = 1.0f; + self.typeLabel.alpha = 1.0f; + self.detailDescriptionLabel.alpha = 1.0f; + self.activityIndicatorView.alpha = 0.0f; + [self.activityIndicatorView stopAnimating]; + break; + case BTPaymentMethodViewStateProcessing: + self.backgroundColor = [UIColor whiteColor]; + self.layer.borderColor = [self.theme borderColor].CGColor; + self.iconView.alpha = 0.0f; + self.typeLabel.alpha = 0.0f; + self.detailDescriptionLabel.alpha = 0.0f; + self.activityIndicatorView.alpha = 1.0f; + [self.activityIndicatorView startAnimating]; + break; + default: + break; + } + + [self setNeedsUpdateConstraints]; + [self setNeedsLayout]; +} + +#pragma mark - + +- (void)setDetailDescription:(NSString *)paymentMethodDescription { + _detailDescription = paymentMethodDescription; + [self updateSubviews]; +} + +- (void)setType:(BTUIPaymentOptionType)type { + _type = type; + [self updateSubviews]; +} + +- (void)setProcessing:(BOOL)processing { + _processing = processing; + + self.contentState = processing ? BTPaymentMethodViewStateProcessing : BTPaymentMethodViewStateNormal; + [UIView animateWithDuration:0.3f animations:^{ + [self updateSubviews]; + }]; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUISummaryView.m b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUISummaryView.m new file mode 100644 index 0000000..f6a42cb --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUISummaryView.m @@ -0,0 +1,130 @@ +#import "BTUISummaryView.h" +#import "BTUI.h" + +@interface BTUISummaryView () +@property (nonatomic, strong) UILabel *slugLabel; +@property (nonatomic, strong) UILabel *summaryLabel; +@property (nonatomic, strong) UILabel *amountLabel; +@end + +@implementation BTUISummaryView + +- (id)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self setupView]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + [self setupView]; + } + return self; +} + +- (void)setupView { + self.backgroundColor = [UIColor whiteColor]; + + // Create subviews + self.slugLabel = [[UILabel alloc] init]; + self.slugLabel.lineBreakMode = NSLineBreakByWordWrapping; + self.slugLabel.numberOfLines = 0; + + self.summaryLabel = [[UILabel alloc] init]; + self.summaryLabel.lineBreakMode = NSLineBreakByWordWrapping; + self.summaryLabel.numberOfLines = 0; + + self.amountLabel = [[UILabel alloc] init]; + [self.amountLabel setContentCompressionResistancePriority:1000 forAxis:UILayoutConstraintAxisHorizontal]; + [self.amountLabel setContentHuggingPriority:1000 forAxis:UILayoutConstraintAxisHorizontal]; + + [self setTheme:self.theme]; + + // Configure subviews + [self.slugLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; + [self.summaryLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; + [self.amountLabel setTranslatesAutoresizingMaskIntoConstraints:NO]; + + // Add subviews + [self addSubview:self.slugLabel]; + [self addSubview:self.summaryLabel]; + [self addSubview:self.amountLabel]; + + // Set content + [self updateText]; +} + +- (void)setTheme:(BTUI *)theme { + [super setTheme:theme]; + self.slugLabel.font = self.theme.controlTitleFont; + self.summaryLabel.font = self.theme.controlFont; + self.amountLabel.font = self.theme.controlTitleFont; +} + +- (void)updateConstraints { + NSDictionary *views = @{@"view": self, + @"slugLabel": self.slugLabel, + @"summaryLabel": self.summaryLabel, + @"amountLabel": self.amountLabel }; + NSDictionary *metrics = @{@"height": @65.0f, + @"topPadding": @10.0f, + @"middlePadding": @2, + @"horizontalMargin": @(self.theme.horizontalMargin)}; + + // View Constraints + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[view(>=height)]" + options:0 + metrics:metrics + views:views]]; + + // Slug and Amount Label Constraints + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(horizontalMargin)-[slugLabel]-[amountLabel]-(horizontalMargin)-|" + options:0 + metrics:metrics + views:views]]; + + // Summary Label Constraints + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(horizontalMargin)-[summaryLabel]-(horizontalMargin)-|" + options:0 + metrics:metrics + views:views]]; + + // Vertical Constraints + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(topPadding)-[slugLabel]-(middlePadding)-[summaryLabel]-(topPadding)-|" + options:0 + metrics:metrics + views:views]]; + + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(topPadding)-[amountLabel]" + options:0 + metrics:metrics + views:views]]; + + [super updateConstraints]; +} + +- (void)setSlug:(NSString *)slug { + _slug = slug; + [self updateText]; +} + +- (void)setSummary:(NSString *)summary { + _summary = summary; + [self updateText]; +} + +- (void)setAmount:(NSString *)amount { + _amount = amount; + [self updateText]; +} + +- (void)updateText { + self.slugLabel.text = self.slug; + self.summaryLabel.text = self.summary; + self.amountLabel.text = self.amount; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUIVenmoButton.m b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUIVenmoButton.m new file mode 100644 index 0000000..bf45c29 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Payments Components/BTUIVenmoButton.m @@ -0,0 +1,83 @@ +#import "BTUIVenmoWordmarkVectorArtView.h" +#import "BTUI.h" +#import "BTUIVenmoButton.h" +#import "UIColor+BTUI.h" + +@interface BTUIVenmoButton () +@property (nonatomic, strong) BTUIVenmoWordmarkVectorArtView *venmoWordmark; +@end + +@implementation BTUIVenmoButton + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self setupView]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + [self setupView]; + } + return self; +} + +- (void)setupView { + self.theme = [BTUI braintreeTheme]; + self.userInteractionEnabled = YES; + self.clipsToBounds = YES; + self.opaque = NO; + self.backgroundColor = [UIColor whiteColor]; + + self.venmoWordmark = [[BTUIVenmoWordmarkVectorArtView alloc] init]; + self.venmoWordmark.userInteractionEnabled = NO; + self.venmoWordmark.translatesAutoresizingMaskIntoConstraints = NO; + self.venmoWordmark.color = [self.theme venmoPrimaryBlue]; + + [self addSubview:self.venmoWordmark]; +} + +- (void)updateConstraints { + NSDictionary *metrics = @{ @"minHeight": @([self.theme paymentButtonMinHeight]), + @"maxHeight": @([self.theme paymentButtonMaxHeight]), + @"minWidth": @(200), + @"required": @(UILayoutPriorityRequired), + @"high": @(UILayoutPriorityDefaultHigh), + @"breathingRoom": @(10) }; + NSDictionary *views = @{ @"self": self , + @"venmoWordmark": self.venmoWordmark }; + + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[venmoWordmark]|" + options:0 + metrics:metrics + views:views]]; + + [self addConstraint:[NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeCenterX + relatedBy:NSLayoutRelationEqual + toItem:self.venmoWordmark + attribute:NSLayoutAttributeCenterX + multiplier:1.0f + constant:0.0f]]; + + [super updateConstraints]; +} + +- (void)setHighlighted:(BOOL)highlighted { + [UIView animateWithDuration:0.08f + delay:0.0f + options:UIViewAnimationOptionBeginFromCurrentState animations:^{ + if (highlighted) { + self.backgroundColor = [UIColor colorWithWhite:0.92f alpha:1.0f]; + } else { + self.backgroundColor = [UIColor whiteColor]; + } + } + completion:nil]; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIAmExVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIAmExVectorArtView.h new file mode 100644 index 0000000..14cc7c4 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIAmExVectorArtView.h @@ -0,0 +1,5 @@ +#import "BTUICardVectorArtView.h" + +@interface BTUIAmExVectorArtView : BTUICardVectorArtView + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIAmExVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIAmExVectorArtView.m new file mode 100644 index 0000000..1e8976d --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIAmExVectorArtView.m @@ -0,0 +1,343 @@ +#import "BTUIAmExVectorArtView.h" + +@implementation BTUIAmExVectorArtView + +- (void)drawArt { + //// Color Declarations + UIColor* color1 = [UIColor colorWithRed: 0.059 green: 0.469 blue: 0.655 alpha: 1]; + + //// Page-1 + { + //// AmEx + { + //// amex + { + //// _x34__x5F_COL_x5F_SQ + { + //// Express + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(54.98, 38.33)]; + [bezierPath addLineToPoint: CGPointMake(54.98, 36.35)]; + [bezierPath addCurveToPoint: CGPointMake(53.19, 34.8) controlPoint1: CGPointMake(54.98, 36.35) controlPoint2: CGPointMake(54.87, 34.8)]; + [bezierPath addLineToPoint: CGPointMake(50.58, 34.8)]; + [bezierPath addLineToPoint: CGPointMake(50.58, 38.33)]; + [bezierPath addLineToPoint: CGPointMake(47.9, 38.33)]; + [bezierPath addLineToPoint: CGPointMake(47.9, 28.14)]; + [bezierPath addLineToPoint: CGPointMake(54.4, 28.14)]; + [bezierPath addCurveToPoint: CGPointMake(57.8, 31.12) controlPoint1: CGPointMake(54.4, 28.14) controlPoint2: CGPointMake(57.8, 27.74)]; + [bezierPath addCurveToPoint: CGPointMake(56.3, 33.5) controlPoint1: CGPointMake(57.8, 32.88) controlPoint2: CGPointMake(56.3, 33.5)]; + [bezierPath addCurveToPoint: CGPointMake(57.58, 35.81) controlPoint1: CGPointMake(56.3, 33.5) controlPoint2: CGPointMake(57.58, 34.09)]; + [bezierPath addLineToPoint: CGPointMake(57.58, 38.33)]; + [bezierPath addLineToPoint: CGPointMake(54.98, 38.33)]; + [bezierPath moveToPoint: CGPointMake(50.58, 32.4)]; + [bezierPath addLineToPoint: CGPointMake(53.35, 32.4)]; + [bezierPath addCurveToPoint: CGPointMake(54.82, 31.43) controlPoint1: CGPointMake(54.15, 32.4) controlPoint2: CGPointMake(54.82, 31.97)]; + [bezierPath addCurveToPoint: CGPointMake(53.35, 30.47) controlPoint1: CGPointMake(54.82, 30.9) controlPoint2: CGPointMake(54.15, 30.47)]; + [bezierPath addLineToPoint: CGPointMake(50.58, 30.47)]; + [bezierPath addLineToPoint: CGPointMake(50.58, 32.4)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + bezierPath.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezierPath fill]; + + + //// Bezier 2 Drawing + UIBezierPath* bezier2Path = [UIBezierPath bezierPath]; + [bezier2Path moveToPoint: CGPointMake(37.11, 38.35)]; + [bezier2Path addLineToPoint: CGPointMake(34.77, 38.35)]; + [bezier2Path addLineToPoint: CGPointMake(31.93, 35.33)]; + [bezier2Path addLineToPoint: CGPointMake(29.08, 38.35)]; + [bezier2Path addLineToPoint: CGPointMake(27.45, 38.35)]; + [bezier2Path addLineToPoint: CGPointMake(19.11, 38.35)]; + [bezier2Path addLineToPoint: CGPointMake(19.11, 28.13)]; + [bezier2Path addLineToPoint: CGPointMake(27.45, 28.13)]; + [bezier2Path addLineToPoint: CGPointMake(28.86, 28.13)]; + [bezier2Path addLineToPoint: CGPointMake(31.93, 31.38)]; + [bezier2Path addLineToPoint: CGPointMake(35.02, 28.15)]; + [bezier2Path addLineToPoint: CGPointMake(37.08, 28.15)]; + [bezier2Path addLineToPoint: CGPointMake(37.08, 28.13)]; + [bezier2Path addLineToPoint: CGPointMake(43.58, 28.13)]; + [bezier2Path addCurveToPoint: CGPointMake(46.97, 31.13) controlPoint1: CGPointMake(43.58, 28.13) controlPoint2: CGPointMake(46.97, 27.77)]; + [bezier2Path addCurveToPoint: CGPointMake(42.38, 35.07) controlPoint1: CGPointMake(46.97, 34.14) controlPoint2: CGPointMake(45.85, 35.07)]; + [bezier2Path addLineToPoint: CGPointMake(39.76, 35.07)]; + [bezier2Path addLineToPoint: CGPointMake(39.76, 38.35)]; + [bezier2Path addLineToPoint: CGPointMake(37.11, 38.35)]; + [bezier2Path closePath]; + [bezier2Path moveToPoint: CGPointMake(33.76, 33.33)]; + [bezier2Path addLineToPoint: CGPointMake(37.08, 36.88)]; + [bezier2Path addLineToPoint: CGPointMake(37.08, 29.79)]; + [bezier2Path addLineToPoint: CGPointMake(33.76, 33.33)]; + [bezier2Path closePath]; + [bezier2Path moveToPoint: CGPointMake(21.81, 36.14)]; + [bezier2Path addLineToPoint: CGPointMake(27.45, 36.14)]; + [bezier2Path addLineToPoint: CGPointMake(30.1, 33.33)]; + [bezier2Path addLineToPoint: CGPointMake(27.45, 30.53)]; + [bezier2Path addLineToPoint: CGPointMake(21.81, 30.53)]; + [bezier2Path addLineToPoint: CGPointMake(21.81, 32.1)]; + [bezier2Path addLineToPoint: CGPointMake(27.31, 32.1)]; + [bezier2Path addLineToPoint: CGPointMake(27.31, 34.41)]; + [bezier2Path addLineToPoint: CGPointMake(21.81, 34.41)]; + [bezier2Path addLineToPoint: CGPointMake(21.81, 36.14)]; + [bezier2Path closePath]; + [bezier2Path moveToPoint: CGPointMake(39.76, 32.41)]; + [bezier2Path addLineToPoint: CGPointMake(42.53, 32.41)]; + [bezier2Path addCurveToPoint: CGPointMake(43.99, 31.45) controlPoint1: CGPointMake(43.33, 32.41) controlPoint2: CGPointMake(43.99, 31.98)]; + [bezier2Path addCurveToPoint: CGPointMake(42.53, 30.48) controlPoint1: CGPointMake(43.99, 30.91) controlPoint2: CGPointMake(43.33, 30.48)]; + [bezier2Path addLineToPoint: CGPointMake(39.76, 30.48)]; + [bezier2Path addLineToPoint: CGPointMake(39.76, 32.41)]; + [bezier2Path closePath]; + bezier2Path.miterLimit = 4; + + bezier2Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier2Path fill]; + + + //// Bezier 3 Drawing + UIBezierPath* bezier3Path = [UIBezierPath bezierPath]; + [bezier3Path moveToPoint: CGPointMake(73.25, 38.3)]; + [bezier3Path addLineToPoint: CGPointMake(68.48, 38.3)]; + [bezier3Path addLineToPoint: CGPointMake(68.48, 35.96)]; + [bezier3Path addLineToPoint: CGPointMake(72.66, 35.96)]; + [bezier3Path addCurveToPoint: CGPointMake(74.16, 35.15) controlPoint1: CGPointMake(72.66, 35.96) controlPoint2: CGPointMake(74.16, 36.13)]; + [bezier3Path addCurveToPoint: CGPointMake(71.89, 34.3) controlPoint1: CGPointMake(74.16, 34.23) controlPoint2: CGPointMake(71.89, 34.3)]; + [bezier3Path addCurveToPoint: CGPointMake(68.19, 31.26) controlPoint1: CGPointMake(71.89, 34.3) controlPoint2: CGPointMake(68.19, 34.61)]; + [bezier3Path addCurveToPoint: CGPointMake(71.53, 28.12) controlPoint1: CGPointMake(68.19, 27.93) controlPoint2: CGPointMake(71.53, 28.12)]; + [bezier3Path addLineToPoint: CGPointMake(76.68, 28.12)]; + [bezier3Path addLineToPoint: CGPointMake(76.68, 30.5)]; + [bezier3Path addLineToPoint: CGPointMake(72.54, 30.5)]; + [bezier3Path addCurveToPoint: CGPointMake(71.11, 31.23) controlPoint1: CGPointMake(72.54, 30.5) controlPoint2: CGPointMake(71.11, 30.23)]; + [bezier3Path addCurveToPoint: CGPointMake(73.05, 31.95) controlPoint1: CGPointMake(71.11, 32.07) controlPoint2: CGPointMake(73.05, 31.95)]; + [bezier3Path addCurveToPoint: CGPointMake(77.14, 34.73) controlPoint1: CGPointMake(73.05, 31.95) controlPoint2: CGPointMake(77.14, 31.66)]; + [bezier3Path addCurveToPoint: CGPointMake(73.57, 38.32) controlPoint1: CGPointMake(77.14, 38.03) controlPoint2: CGPointMake(74.51, 38.32)]; + [bezier3Path addCurveToPoint: CGPointMake(73.25, 38.3) controlPoint1: CGPointMake(73.37, 38.32) controlPoint2: CGPointMake(73.25, 38.3)]; + [bezier3Path closePath]; + bezier3Path.miterLimit = 4; + + bezier3Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier3Path fill]; + + + //// Bezier 4 Drawing + UIBezierPath* bezier4Path = [UIBezierPath bezierPath]; + [bezier4Path moveToPoint: CGPointMake(58.91, 38.3)]; + [bezier4Path addLineToPoint: CGPointMake(58.91, 28.12)]; + [bezier4Path addLineToPoint: CGPointMake(67.26, 28.12)]; + [bezier4Path addLineToPoint: CGPointMake(67.26, 30.49)]; + [bezier4Path addLineToPoint: CGPointMake(61.6, 30.49)]; + [bezier4Path addLineToPoint: CGPointMake(61.6, 32.06)]; + [bezier4Path addLineToPoint: CGPointMake(67.12, 32.06)]; + [bezier4Path addLineToPoint: CGPointMake(67.12, 34.37)]; + [bezier4Path addLineToPoint: CGPointMake(61.6, 34.37)]; + [bezier4Path addLineToPoint: CGPointMake(61.6, 36.1)]; + [bezier4Path addLineToPoint: CGPointMake(67.26, 36.1)]; + [bezier4Path addLineToPoint: CGPointMake(67.26, 38.3)]; + [bezier4Path addLineToPoint: CGPointMake(58.91, 38.3)]; + [bezier4Path closePath]; + bezier4Path.miterLimit = 4; + + bezier4Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier4Path fill]; + + + //// Bezier 5 Drawing + UIBezierPath* bezier5Path = [UIBezierPath bezierPath]; + [bezier5Path moveToPoint: CGPointMake(82.7, 38.3)]; + [bezier5Path addLineToPoint: CGPointMake(77.93, 38.3)]; + [bezier5Path addLineToPoint: CGPointMake(77.93, 35.96)]; + [bezier5Path addLineToPoint: CGPointMake(82.09, 35.96)]; + [bezier5Path addCurveToPoint: CGPointMake(83.61, 35.15) controlPoint1: CGPointMake(82.09, 35.96) controlPoint2: CGPointMake(83.61, 36.13)]; + [bezier5Path addCurveToPoint: CGPointMake(81.34, 34.3) controlPoint1: CGPointMake(83.61, 34.23) controlPoint2: CGPointMake(81.34, 34.3)]; + [bezier5Path addCurveToPoint: CGPointMake(77.64, 31.26) controlPoint1: CGPointMake(81.34, 34.3) controlPoint2: CGPointMake(77.64, 34.61)]; + [bezier5Path addCurveToPoint: CGPointMake(80.98, 28.12) controlPoint1: CGPointMake(77.64, 27.93) controlPoint2: CGPointMake(80.98, 28.12)]; + [bezier5Path addLineToPoint: CGPointMake(86.11, 28.12)]; + [bezier5Path addLineToPoint: CGPointMake(86.11, 30.5)]; + [bezier5Path addLineToPoint: CGPointMake(81.98, 30.5)]; + [bezier5Path addCurveToPoint: CGPointMake(80.56, 31.23) controlPoint1: CGPointMake(81.98, 30.5) controlPoint2: CGPointMake(80.56, 30.23)]; + [bezier5Path addCurveToPoint: CGPointMake(82.5, 31.95) controlPoint1: CGPointMake(80.56, 32.07) controlPoint2: CGPointMake(82.5, 31.95)]; + [bezier5Path addCurveToPoint: CGPointMake(86.59, 34.73) controlPoint1: CGPointMake(82.5, 31.95) controlPoint2: CGPointMake(86.59, 31.66)]; + [bezier5Path addCurveToPoint: CGPointMake(83.02, 38.32) controlPoint1: CGPointMake(86.59, 38.03) controlPoint2: CGPointMake(83.96, 38.32)]; + [bezier5Path addCurveToPoint: CGPointMake(82.7, 38.3) controlPoint1: CGPointMake(82.82, 38.32) controlPoint2: CGPointMake(82.7, 38.3)]; + [bezier5Path closePath]; + bezier5Path.miterLimit = 4; + + bezier5Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier5Path fill]; + } + + + //// American + { + //// Bezier 6 Drawing + UIBezierPath* bezier6Path = [UIBezierPath bezierPath]; + [bezier6Path moveToPoint: CGPointMake(45.31, 27.39)]; + [bezier6Path addLineToPoint: CGPointMake(45.31, 25.41)]; + [bezier6Path addCurveToPoint: CGPointMake(43.53, 23.85) controlPoint1: CGPointMake(45.31, 25.41) controlPoint2: CGPointMake(45.2, 23.85)]; + [bezier6Path addLineToPoint: CGPointMake(40.92, 23.85)]; + [bezier6Path addLineToPoint: CGPointMake(40.92, 27.39)]; + [bezier6Path addLineToPoint: CGPointMake(38.24, 27.39)]; + [bezier6Path addLineToPoint: CGPointMake(38.24, 17.19)]; + [bezier6Path addLineToPoint: CGPointMake(44.74, 17.19)]; + [bezier6Path addCurveToPoint: CGPointMake(48.14, 20.18) controlPoint1: CGPointMake(44.74, 17.19) controlPoint2: CGPointMake(48.14, 16.8)]; + [bezier6Path addCurveToPoint: CGPointMake(46.63, 22.56) controlPoint1: CGPointMake(48.14, 21.94) controlPoint2: CGPointMake(46.63, 22.56)]; + [bezier6Path addCurveToPoint: CGPointMake(47.94, 24.87) controlPoint1: CGPointMake(46.63, 22.56) controlPoint2: CGPointMake(47.94, 23.15)]; + [bezier6Path addLineToPoint: CGPointMake(47.94, 27.39)]; + [bezier6Path addLineToPoint: CGPointMake(45.31, 27.39)]; + [bezier6Path moveToPoint: CGPointMake(40.92, 21.45)]; + [bezier6Path addLineToPoint: CGPointMake(43.69, 21.45)]; + [bezier6Path addCurveToPoint: CGPointMake(45.15, 20.49) controlPoint1: CGPointMake(44.49, 21.45) controlPoint2: CGPointMake(45.15, 21.02)]; + [bezier6Path addCurveToPoint: CGPointMake(43.69, 19.52) controlPoint1: CGPointMake(45.15, 19.95) controlPoint2: CGPointMake(44.49, 19.52)]; + [bezier6Path addLineToPoint: CGPointMake(40.92, 19.52)]; + [bezier6Path addLineToPoint: CGPointMake(40.92, 21.45)]; + [bezier6Path closePath]; + bezier6Path.miterLimit = 4; + + bezier6Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier6Path fill]; + + + //// Bezier 7 Drawing + UIBezierPath* bezier7Path = [UIBezierPath bezierPath]; + [bezier7Path moveToPoint: CGPointMake(76.93, 27.39)]; + [bezier7Path addLineToPoint: CGPointMake(72.68, 20.57)]; + [bezier7Path addLineToPoint: CGPointMake(72.68, 27.39)]; + [bezier7Path addLineToPoint: CGPointMake(70.37, 27.39)]; + [bezier7Path addLineToPoint: CGPointMake(69.94, 27.39)]; + [bezier7Path addLineToPoint: CGPointMake(67.43, 27.39)]; + [bezier7Path addLineToPoint: CGPointMake(66.48, 25.25)]; + [bezier7Path addLineToPoint: CGPointMake(61.58, 25.25)]; + [bezier7Path addLineToPoint: CGPointMake(60.65, 27.39)]; + [bezier7Path addLineToPoint: CGPointMake(58.19, 27.39)]; + [bezier7Path addLineToPoint: CGPointMake(57.74, 27.39)]; + [bezier7Path addLineToPoint: CGPointMake(56.45, 27.39)]; + [bezier7Path addCurveToPoint: CGPointMake(52.85, 22.58) controlPoint1: CGPointMake(56.45, 27.39) controlPoint2: CGPointMake(52.85, 26.89)]; + [bezier7Path addCurveToPoint: CGPointMake(57.08, 17.11) controlPoint1: CGPointMake(52.85, 16.92) controlPoint2: CGPointMake(56.94, 17.14)]; + [bezier7Path addLineToPoint: CGPointMake(60.39, 17.19)]; + [bezier7Path addLineToPoint: CGPointMake(60.39, 19.49)]; + [bezier7Path addLineToPoint: CGPointMake(57.67, 19.52)]; + [bezier7Path addCurveToPoint: CGPointMake(55.69, 21.75) controlPoint1: CGPointMake(57.67, 19.52) controlPoint2: CGPointMake(55.9, 19.52)]; + [bezier7Path addCurveToPoint: CGPointMake(55.65, 22.46) controlPoint1: CGPointMake(55.66, 22) controlPoint2: CGPointMake(55.65, 22.24)]; + [bezier7Path addCurveToPoint: CGPointMake(58.85, 24.8) controlPoint1: CGPointMake(55.66, 25.91) controlPoint2: CGPointMake(58.75, 24.84)]; + [bezier7Path addLineToPoint: CGPointMake(62.17, 17.19)]; + [bezier7Path addLineToPoint: CGPointMake(65.92, 17.19)]; + [bezier7Path addLineToPoint: CGPointMake(69.94, 26.44)]; + [bezier7Path addLineToPoint: CGPointMake(69.94, 17.19)]; + [bezier7Path addLineToPoint: CGPointMake(73.73, 17.19)]; + [bezier7Path addLineToPoint: CGPointMake(77.92, 23.91)]; + [bezier7Path addLineToPoint: CGPointMake(77.92, 17.19)]; + [bezier7Path addLineToPoint: CGPointMake(80.62, 17.19)]; + [bezier7Path addLineToPoint: CGPointMake(80.62, 27.39)]; + [bezier7Path addLineToPoint: CGPointMake(76.93, 27.39)]; + [bezier7Path closePath]; + [bezier7Path moveToPoint: CGPointMake(62.73, 22.65)]; + [bezier7Path addLineToPoint: CGPointMake(65.33, 22.65)]; + [bezier7Path addLineToPoint: CGPointMake(64.05, 19.61)]; + [bezier7Path addLineToPoint: CGPointMake(62.73, 22.65)]; + [bezier7Path closePath]; + bezier7Path.miterLimit = 4; + + bezier7Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier7Path fill]; + + + //// Bezier 8 Drawing + UIBezierPath* bezier8Path = [UIBezierPath bezierPath]; + [bezier8Path moveToPoint: CGPointMake(23.92, 27.44)]; + [bezier8Path addLineToPoint: CGPointMake(23.92, 20.4)]; + [bezier8Path addLineToPoint: CGPointMake(20.56, 27.44)]; + [bezier8Path addLineToPoint: CGPointMake(18.36, 27.44)]; + [bezier8Path addLineToPoint: CGPointMake(14.99, 20.43)]; + [bezier8Path addLineToPoint: CGPointMake(14.99, 27.44)]; + [bezier8Path addLineToPoint: CGPointMake(12.65, 27.44)]; + [bezier8Path addLineToPoint: CGPointMake(12.29, 27.44)]; + [bezier8Path addLineToPoint: CGPointMake(9.7, 27.44)]; + [bezier8Path addLineToPoint: CGPointMake(8.77, 25.3)]; + [bezier8Path addLineToPoint: CGPointMake(3.88, 25.3)]; + [bezier8Path addLineToPoint: CGPointMake(2.93, 27.44)]; + [bezier8Path addLineToPoint: CGPointMake(0, 27.44)]; + [bezier8Path addLineToPoint: CGPointMake(4.45, 17.24)]; + [bezier8Path addLineToPoint: CGPointMake(8.22, 17.24)]; + [bezier8Path addLineToPoint: CGPointMake(12.29, 26.61)]; + [bezier8Path addLineToPoint: CGPointMake(12.29, 17.24)]; + [bezier8Path addLineToPoint: CGPointMake(16.52, 17.24)]; + [bezier8Path addLineToPoint: CGPointMake(19.47, 23.58)]; + [bezier8Path addLineToPoint: CGPointMake(22.4, 17.24)]; + [bezier8Path addLineToPoint: CGPointMake(26.63, 17.24)]; + [bezier8Path addLineToPoint: CGPointMake(26.63, 27.44)]; + [bezier8Path addLineToPoint: CGPointMake(23.92, 27.44)]; + [bezier8Path closePath]; + [bezier8Path moveToPoint: CGPointMake(5.02, 22.69)]; + [bezier8Path addLineToPoint: CGPointMake(7.63, 22.69)]; + [bezier8Path addLineToPoint: CGPointMake(6.32, 19.66)]; + [bezier8Path addLineToPoint: CGPointMake(5.02, 22.69)]; + [bezier8Path closePath]; + bezier8Path.miterLimit = 4; + + bezier8Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier8Path fill]; + + + //// Bezier 9 Drawing + UIBezierPath* bezier9Path = [UIBezierPath bezierPath]; + [bezier9Path moveToPoint: CGPointMake(28.49, 27.39)]; + [bezier9Path addLineToPoint: CGPointMake(28.49, 17.19)]; + [bezier9Path addLineToPoint: CGPointMake(36.85, 17.19)]; + [bezier9Path addLineToPoint: CGPointMake(36.85, 19.57)]; + [bezier9Path addLineToPoint: CGPointMake(31.18, 19.57)]; + [bezier9Path addLineToPoint: CGPointMake(31.18, 21.14)]; + [bezier9Path addLineToPoint: CGPointMake(36.7, 21.14)]; + [bezier9Path addLineToPoint: CGPointMake(36.7, 23.46)]; + [bezier9Path addLineToPoint: CGPointMake(31.18, 23.46)]; + [bezier9Path addLineToPoint: CGPointMake(31.18, 25.18)]; + [bezier9Path addLineToPoint: CGPointMake(36.85, 25.18)]; + [bezier9Path addLineToPoint: CGPointMake(36.85, 27.39)]; + [bezier9Path addLineToPoint: CGPointMake(28.49, 27.39)]; + [bezier9Path closePath]; + bezier9Path.miterLimit = 4; + + bezier9Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier9Path fill]; + + + //// Bezier 10 Drawing + UIBezierPath* bezier10Path = [UIBezierPath bezierPath]; + [bezier10Path moveToPoint: CGPointMake(49.24, 27.42)]; + [bezier10Path addLineToPoint: CGPointMake(49.24, 17.19)]; + [bezier10Path addLineToPoint: CGPointMake(51.94, 17.19)]; + [bezier10Path addLineToPoint: CGPointMake(51.94, 27.42)]; + [bezier10Path addLineToPoint: CGPointMake(49.24, 27.42)]; + [bezier10Path closePath]; + bezier10Path.miterLimit = 4; + + bezier10Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier10Path fill]; + } + } + } + } + } +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICVVBackVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICVVBackVectorArtView.h new file mode 100644 index 0000000..7ae91bd --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICVVBackVectorArtView.h @@ -0,0 +1,5 @@ +#import "BTUICardVectorArtView.h" + +@interface BTUICVVBackVectorArtView : BTUICardVectorArtView + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICVVBackVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICVVBackVectorArtView.m new file mode 100644 index 0000000..a54b825 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICVVBackVectorArtView.m @@ -0,0 +1,48 @@ +#import "BTUICVVBackVectorArtView.h" + +@implementation BTUICVVBackVectorArtView + +- (void)drawArt { + + //// Color Declarations + UIColor* color1 = [UIColor colorWithRed: 0.124 green: 0.132 blue: 0.138 alpha: 0.1]; + UIColor* color2 = self.highlightColor ?: color1; + UIColor* color3 = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + + //// Page-1 + { + //// CVV-Back + { + //// Rectangle Drawing + UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRect: CGRectMake(0, 8, 87, 12)]; + [color1 setFill]; + [rectanglePath fill]; + + + //// Rounded Rectangle Drawing + UIBezierPath* roundedRectanglePath = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(53, 30, 26, 18) cornerRadius: 9]; + [color2 setFill]; + [roundedRectanglePath fill]; + + + //// Rectangle 2 Drawing + UIBezierPath* rectangle2Path = [UIBezierPath bezierPathWithRect: CGRectMake(61, 36, 2, 6)]; + [color3 setFill]; + [rectangle2Path fill]; + + + //// Rectangle 3 Drawing + UIBezierPath* rectangle3Path = [UIBezierPath bezierPathWithRect: CGRectMake(65, 36, 2, 6)]; + [color3 setFill]; + [rectangle3Path fill]; + + + //// Rectangle 4 Drawing + UIBezierPath* rectangle4Path = [UIBezierPath bezierPathWithRect: CGRectMake(69, 36, 2, 6)]; + [color3 setFill]; + [rectangle4Path fill]; + } + } +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICVVFrontVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICVVFrontVectorArtView.h new file mode 100644 index 0000000..79f85f8 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICVVFrontVectorArtView.h @@ -0,0 +1,5 @@ +#import "BTUICardVectorArtView.h" + +@interface BTUICVVFrontVectorArtView : BTUICardVectorArtView + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICVVFrontVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICVVFrontVectorArtView.m new file mode 100644 index 0000000..4e1f435 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICVVFrontVectorArtView.m @@ -0,0 +1,341 @@ +#import "BTUICVVFrontVectorArtView.h" + +@implementation BTUICVVFrontVectorArtView + +- (void)drawArt { + + + //// Color Declarations + UIColor* color1 = [UIColor colorWithRed: 0.765 green: 0.77 blue: 0.756 alpha: 1]; + UIColor* color3 = self.highlightColor ?: color1; + UIColor* color2 = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 0.105]; + UIColor* color4 = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + + //// Page-1 + { + //// CVV-Front + { + //// Card-#-2 + { + //// CC-numbers + { + //// CC-number + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(6, 31)]; + [bezierPath addLineToPoint: CGPointMake(8, 31)]; + [bezierPath addLineToPoint: CGPointMake(8, 37)]; + [bezierPath addLineToPoint: CGPointMake(6, 37)]; + [bezierPath addLineToPoint: CGPointMake(6, 31)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + bezierPath.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezierPath fill]; + + + //// Bezier 2 Drawing + UIBezierPath* bezier2Path = [UIBezierPath bezierPath]; + [bezier2Path moveToPoint: CGPointMake(10, 31)]; + [bezier2Path addLineToPoint: CGPointMake(12, 31)]; + [bezier2Path addLineToPoint: CGPointMake(12, 37)]; + [bezier2Path addLineToPoint: CGPointMake(10, 37)]; + [bezier2Path addLineToPoint: CGPointMake(10, 31)]; + [bezier2Path closePath]; + bezier2Path.miterLimit = 4; + + bezier2Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier2Path fill]; + + + //// Bezier 3 Drawing + UIBezierPath* bezier3Path = [UIBezierPath bezierPath]; + [bezier3Path moveToPoint: CGPointMake(14, 31)]; + [bezier3Path addLineToPoint: CGPointMake(16, 31)]; + [bezier3Path addLineToPoint: CGPointMake(16, 37)]; + [bezier3Path addLineToPoint: CGPointMake(14, 37)]; + [bezier3Path addLineToPoint: CGPointMake(14, 31)]; + [bezier3Path closePath]; + bezier3Path.miterLimit = 4; + + bezier3Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier3Path fill]; + + + //// Bezier 4 Drawing + UIBezierPath* bezier4Path = [UIBezierPath bezierPath]; + [bezier4Path moveToPoint: CGPointMake(18, 31)]; + [bezier4Path addLineToPoint: CGPointMake(20, 31)]; + [bezier4Path addLineToPoint: CGPointMake(20, 37)]; + [bezier4Path addLineToPoint: CGPointMake(18, 37)]; + [bezier4Path addLineToPoint: CGPointMake(18, 31)]; + [bezier4Path closePath]; + bezier4Path.miterLimit = 4; + + bezier4Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier4Path fill]; + + + //// Bezier 5 Drawing + UIBezierPath* bezier5Path = [UIBezierPath bezierPath]; + [bezier5Path moveToPoint: CGPointMake(26, 31)]; + [bezier5Path addLineToPoint: CGPointMake(28, 31)]; + [bezier5Path addLineToPoint: CGPointMake(28, 37)]; + [bezier5Path addLineToPoint: CGPointMake(26, 37)]; + [bezier5Path addLineToPoint: CGPointMake(26, 31)]; + [bezier5Path closePath]; + bezier5Path.miterLimit = 4; + + bezier5Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier5Path fill]; + + + //// Bezier 6 Drawing + UIBezierPath* bezier6Path = [UIBezierPath bezierPath]; + [bezier6Path moveToPoint: CGPointMake(30, 31)]; + [bezier6Path addLineToPoint: CGPointMake(32, 31)]; + [bezier6Path addLineToPoint: CGPointMake(32, 37)]; + [bezier6Path addLineToPoint: CGPointMake(30, 37)]; + [bezier6Path addLineToPoint: CGPointMake(30, 31)]; + [bezier6Path closePath]; + bezier6Path.miterLimit = 4; + + bezier6Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier6Path fill]; + + + //// Bezier 7 Drawing + UIBezierPath* bezier7Path = [UIBezierPath bezierPath]; + [bezier7Path moveToPoint: CGPointMake(34, 31)]; + [bezier7Path addLineToPoint: CGPointMake(36, 31)]; + [bezier7Path addLineToPoint: CGPointMake(36, 37)]; + [bezier7Path addLineToPoint: CGPointMake(34, 37)]; + [bezier7Path addLineToPoint: CGPointMake(34, 31)]; + [bezier7Path closePath]; + bezier7Path.miterLimit = 4; + + bezier7Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier7Path fill]; + + + //// Bezier 8 Drawing + UIBezierPath* bezier8Path = [UIBezierPath bezierPath]; + [bezier8Path moveToPoint: CGPointMake(38, 31)]; + [bezier8Path addLineToPoint: CGPointMake(40, 31)]; + [bezier8Path addLineToPoint: CGPointMake(40, 37)]; + [bezier8Path addLineToPoint: CGPointMake(38, 37)]; + [bezier8Path addLineToPoint: CGPointMake(38, 31)]; + [bezier8Path closePath]; + bezier8Path.miterLimit = 4; + + bezier8Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier8Path fill]; + + + //// Bezier 9 Drawing + UIBezierPath* bezier9Path = [UIBezierPath bezierPath]; + [bezier9Path moveToPoint: CGPointMake(46, 31)]; + [bezier9Path addLineToPoint: CGPointMake(48, 31)]; + [bezier9Path addLineToPoint: CGPointMake(48, 37)]; + [bezier9Path addLineToPoint: CGPointMake(46, 37)]; + [bezier9Path addLineToPoint: CGPointMake(46, 31)]; + [bezier9Path closePath]; + bezier9Path.miterLimit = 4; + + bezier9Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier9Path fill]; + + + //// Bezier 10 Drawing + UIBezierPath* bezier10Path = [UIBezierPath bezierPath]; + [bezier10Path moveToPoint: CGPointMake(50, 31)]; + [bezier10Path addLineToPoint: CGPointMake(52, 31)]; + [bezier10Path addLineToPoint: CGPointMake(52, 37)]; + [bezier10Path addLineToPoint: CGPointMake(50, 37)]; + [bezier10Path addLineToPoint: CGPointMake(50, 31)]; + [bezier10Path closePath]; + bezier10Path.miterLimit = 4; + + bezier10Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier10Path fill]; + + + //// Bezier 11 Drawing + UIBezierPath* bezier11Path = [UIBezierPath bezierPath]; + [bezier11Path moveToPoint: CGPointMake(54, 31)]; + [bezier11Path addLineToPoint: CGPointMake(56, 31)]; + [bezier11Path addLineToPoint: CGPointMake(56, 37)]; + [bezier11Path addLineToPoint: CGPointMake(54, 37)]; + [bezier11Path addLineToPoint: CGPointMake(54, 31)]; + [bezier11Path closePath]; + bezier11Path.miterLimit = 4; + + bezier11Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier11Path fill]; + + + //// Bezier 12 Drawing + UIBezierPath* bezier12Path = [UIBezierPath bezierPath]; + [bezier12Path moveToPoint: CGPointMake(58, 31)]; + [bezier12Path addLineToPoint: CGPointMake(60, 31)]; + [bezier12Path addLineToPoint: CGPointMake(60, 37)]; + [bezier12Path addLineToPoint: CGPointMake(58, 37)]; + [bezier12Path addLineToPoint: CGPointMake(58, 31)]; + [bezier12Path closePath]; + bezier12Path.miterLimit = 4; + + bezier12Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier12Path fill]; + + + //// Bezier 13 Drawing + UIBezierPath* bezier13Path = [UIBezierPath bezierPath]; + [bezier13Path moveToPoint: CGPointMake(66, 31)]; + [bezier13Path addLineToPoint: CGPointMake(68, 31)]; + [bezier13Path addLineToPoint: CGPointMake(68, 37)]; + [bezier13Path addLineToPoint: CGPointMake(66, 37)]; + [bezier13Path addLineToPoint: CGPointMake(66, 31)]; + [bezier13Path closePath]; + bezier13Path.miterLimit = 4; + + bezier13Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier13Path fill]; + + + //// Bezier 14 Drawing + UIBezierPath* bezier14Path = [UIBezierPath bezierPath]; + [bezier14Path moveToPoint: CGPointMake(70, 31)]; + [bezier14Path addLineToPoint: CGPointMake(72, 31)]; + [bezier14Path addLineToPoint: CGPointMake(72, 37)]; + [bezier14Path addLineToPoint: CGPointMake(70, 37)]; + [bezier14Path addLineToPoint: CGPointMake(70, 31)]; + [bezier14Path closePath]; + bezier14Path.miterLimit = 4; + + bezier14Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier14Path fill]; + + + //// Bezier 15 Drawing + UIBezierPath* bezier15Path = [UIBezierPath bezierPath]; + [bezier15Path moveToPoint: CGPointMake(74, 31)]; + [bezier15Path addLineToPoint: CGPointMake(76, 31)]; + [bezier15Path addLineToPoint: CGPointMake(76, 37)]; + [bezier15Path addLineToPoint: CGPointMake(74, 37)]; + [bezier15Path addLineToPoint: CGPointMake(74, 31)]; + [bezier15Path closePath]; + bezier15Path.miterLimit = 4; + + bezier15Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier15Path fill]; + + + //// Bezier 16 Drawing + UIBezierPath* bezier16Path = [UIBezierPath bezierPath]; + [bezier16Path moveToPoint: CGPointMake(78, 31)]; + [bezier16Path addLineToPoint: CGPointMake(80, 31)]; + [bezier16Path addLineToPoint: CGPointMake(80, 37)]; + [bezier16Path addLineToPoint: CGPointMake(78, 37)]; + [bezier16Path addLineToPoint: CGPointMake(78, 31)]; + [bezier16Path closePath]; + bezier16Path.miterLimit = 4; + + bezier16Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier16Path fill]; + } + + + //// Rectangle Drawing + UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRect: CGRectMake(26, 43, 14, 2)]; + [color2 setFill]; + [rectanglePath fill]; + + + //// Rectangle 2 Drawing + UIBezierPath* rectangle2Path = [UIBezierPath bezierPathWithRect: CGRectMake(6, 47, 34, 2)]; + [color2 setFill]; + [rectangle2Path fill]; + + + //// Rounded Rectangle Drawing + UIBezierPath* roundedRectanglePath = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(56, 5, 26, 18) cornerRadius: 9]; + [color3 setFill]; + [roundedRectanglePath fill]; + + + //// Rectangle 3 Drawing + UIBezierPath* rectangle3Path = [UIBezierPath bezierPathWithRect: CGRectMake(62, 11, 2, 6)]; + [color4 setFill]; + [rectangle3Path fill]; + + + //// Rectangle 4 Drawing + UIBezierPath* rectangle4Path = [UIBezierPath bezierPathWithRect: CGRectMake(66, 11, 2, 6)]; + [color4 setFill]; + [rectangle4Path fill]; + + + //// Rectangle 5 Drawing + UIBezierPath* rectangle5Path = [UIBezierPath bezierPathWithRect: CGRectMake(70, 11, 2, 6)]; + [color4 setFill]; + [rectangle5Path fill]; + + + //// Rectangle 6 Drawing + UIBezierPath* rectangle6Path = [UIBezierPath bezierPathWithRect: CGRectMake(74, 11, 2, 6)]; + [color4 setFill]; + [rectangle6Path fill]; + } + + + //// Rounded Rectangle 2 Drawing + UIBezierPath* roundedRectangle2Path = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(6, 7, 14, 14) cornerRadius: 0.75]; + [color2 setFill]; + [roundedRectangle2Path fill]; + + + //// Rounded Rectangle 3 Drawing + UIBezierPath* roundedRectangle3Path = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(72, 41, 8, 8) cornerRadius: 0.75]; + [color2 setFill]; + [roundedRectangle3Path fill]; + } + } + } + + +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICardVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICardVectorArtView.h new file mode 100644 index 0000000..5bb8874 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICardVectorArtView.h @@ -0,0 +1,7 @@ +#import "BTUIVectorArtView.h" + +@interface BTUICardVectorArtView : BTUIVectorArtView + +@property (nonatomic, strong) UIColor *highlightColor; + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICardVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICardVectorArtView.m new file mode 100644 index 0000000..204eb0f --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICardVectorArtView.m @@ -0,0 +1,25 @@ +#import "BTUICardVectorArtView.h" + +@implementation BTUICardVectorArtView + +- (id)init { + self = [super init]; + if (self) { + self.artDimensions = CGSizeMake(87.0f, 55.0f); + self.opaque = NO; + } + return self; +} + +- (void)updateConstraints { + [self addConstraint:[NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeWidth + relatedBy:NSLayoutRelationEqual + toItem:self + attribute:NSLayoutAttributeHeight + multiplier:87.0f/55.0f + constant:0]]; + [super updateConstraints]; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICoinbaseMonogramCardView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICoinbaseMonogramCardView.h new file mode 100644 index 0000000..b300082 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICoinbaseMonogramCardView.h @@ -0,0 +1,5 @@ +#import "BTUICardVectorArtView.h" + +@interface BTUICoinbaseMonogramCardView : BTUICardVectorArtView + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICoinbaseMonogramCardView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICoinbaseMonogramCardView.m new file mode 100644 index 0000000..eb52ffd --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICoinbaseMonogramCardView.m @@ -0,0 +1,43 @@ +#import "BTUICoinbaseMonogramCardView.h" + +@implementation BTUICoinbaseMonogramCardView + +- (void)drawArt { + //// Color Declarations + UIColor* color1 = [UIColor colorWithRed: 0.053 green: 0.433 blue: 0.7 alpha: 1]; + + //// Assets + { + //// icon-coinbase + { + //// Rectangle Drawing + + + //// logo/coinbase-2 + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(24, 27.45)]; + [bezierPath addCurveToPoint: CGPointMake(47.38, 0) controlPoint1: CGPointMake(24, 8.33) controlPoint2: CGPointMake(35.54, 0)]; + [bezierPath addCurveToPoint: CGPointMake(61, 3.63) controlPoint1: CGPointMake(53.21, 0) controlPoint2: CGPointMake(57.74, 1.47)]; + [bezierPath addLineToPoint: CGPointMake(57.45, 11.37)]; + [bezierPath addCurveToPoint: CGPointMake(48.77, 8.82) controlPoint1: CGPointMake(55.28, 9.8) controlPoint2: CGPointMake(52.02, 8.82)]; + [bezierPath addCurveToPoint: CGPointMake(34.57, 27.45) controlPoint1: CGPointMake(41.66, 8.82) controlPoint2: CGPointMake(34.57, 14.51)]; + [bezierPath addCurveToPoint: CGPointMake(48.77, 45.98) controlPoint1: CGPointMake(34.57, 40.39) controlPoint2: CGPointMake(41.86, 45.98)]; + [bezierPath addCurveToPoint: CGPointMake(57.45, 43.43) controlPoint1: CGPointMake(52.02, 45.98) controlPoint2: CGPointMake(55.28, 45)]; + [bezierPath addLineToPoint: CGPointMake(61, 51.37)]; + [bezierPath addCurveToPoint: CGPointMake(47.38, 55) controlPoint1: CGPointMake(57.65, 53.63) controlPoint2: CGPointMake(53.21, 55)]; + [bezierPath addCurveToPoint: CGPointMake(24, 27.45) controlPoint1: CGPointMake(35.54, 55) controlPoint2: CGPointMake(24, 46.57)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + bezierPath.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezierPath fill]; + } + } + } +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICoinbaseWordmarkVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICoinbaseWordmarkVectorArtView.h new file mode 100644 index 0000000..84da317 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICoinbaseWordmarkVectorArtView.h @@ -0,0 +1,7 @@ +#import "BTUIVectorArtView.h" + +@interface BTUICoinbaseWordmarkVectorArtView : BTUIVectorArtView + +@property (nonatomic, strong) UIColor *color; + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICoinbaseWordmarkVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICoinbaseWordmarkVectorArtView.m new file mode 100644 index 0000000..d9f828c --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUICoinbaseWordmarkVectorArtView.m @@ -0,0 +1,191 @@ +#import "BTUICoinbaseWordmarkVectorArtView.h" + +@implementation BTUICoinbaseWordmarkVectorArtView + +- (instancetype)initWithCoder:(NSCoder *)coder +{ + self = [super initWithCoder:coder]; + if (self) { + [self doSetup]; + } + return self; +} + +- (id)init { + self = [super init]; + if (self) { + [self doSetup]; + } + return self; +} + +- (void)doSetup { + self.artDimensions = CGSizeMake(162, 88); + self.opaque = NO; + self.color = [UIColor colorWithRed: 0.053 green: 0.433 blue: 0.7 alpha: 1]; // Default color +} + +- (void)setColor:(UIColor *)color { + _color = color; + [self setNeedsDisplay]; +} + +- (void)drawArt { + //// Assets + { + //// button-coinbase + { + //// Rectangle Drawing + + + //// logo/coinbase-2 + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(20.22, 54)]; + [bezierPath addCurveToPoint: CGPointMake(12, 43.98) controlPoint1: CGPointMake(16.06, 54) controlPoint2: CGPointMake(12, 50.93)]; + [bezierPath addCurveToPoint: CGPointMake(20.22, 34) controlPoint1: CGPointMake(12, 37.03) controlPoint2: CGPointMake(16.06, 34)]; + [bezierPath addCurveToPoint: CGPointMake(25, 35.32) controlPoint1: CGPointMake(22.26, 34) controlPoint2: CGPointMake(23.86, 34.53)]; + [bezierPath addLineToPoint: CGPointMake(23.75, 38.14)]; + [bezierPath addCurveToPoint: CGPointMake(20.7, 37.21) controlPoint1: CGPointMake(22.99, 37.56) controlPoint2: CGPointMake(21.85, 37.21)]; + [bezierPath addCurveToPoint: CGPointMake(15.92, 43.95) controlPoint1: CGPointMake(18.21, 37.21) controlPoint2: CGPointMake(15.92, 39.24)]; + [bezierPath addCurveToPoint: CGPointMake(20.7, 50.72) controlPoint1: CGPointMake(15.92, 48.65) controlPoint2: CGPointMake(18.27, 50.72)]; + [bezierPath addCurveToPoint: CGPointMake(23.75, 49.79) controlPoint1: CGPointMake(21.85, 50.72) controlPoint2: CGPointMake(22.99, 50.36)]; + [bezierPath addLineToPoint: CGPointMake(25, 52.68)]; + [bezierPath addCurveToPoint: CGPointMake(20.22, 54) controlPoint1: CGPointMake(23.82, 53.5) controlPoint2: CGPointMake(22.26, 54)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(36.07, 54)]; + [bezierPath addCurveToPoint: CGPointMake(27.62, 44.12) controlPoint1: CGPointMake(30.61, 54) controlPoint2: CGPointMake(27.62, 49.74)]; + [bezierPath addCurveToPoint: CGPointMake(36.07, 34.27) controlPoint1: CGPointMake(27.62, 38.49) controlPoint2: CGPointMake(30.61, 34.27)]; + [bezierPath addCurveToPoint: CGPointMake(44.52, 44.12) controlPoint1: CGPointMake(41.53, 34.27) controlPoint2: CGPointMake(44.52, 38.49)]; + [bezierPath addCurveToPoint: CGPointMake(36.07, 54) controlPoint1: CGPointMake(44.52, 49.74) controlPoint2: CGPointMake(41.53, 54)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(31, 44)]; + [bezierPath addCurveToPoint: CGPointMake(36, 51) controlPoint1: CGPointMake(31, 48.08) controlPoint2: CGPointMake(32.97, 51)]; + [bezierPath addCurveToPoint: CGPointMake(41, 44) controlPoint1: CGPointMake(39.03, 51) controlPoint2: CGPointMake(41, 48.08)]; + [bezierPath addCurveToPoint: CGPointMake(36, 37) controlPoint1: CGPointMake(41, 39.92) controlPoint2: CGPointMake(39.03, 37)]; + [bezierPath addCurveToPoint: CGPointMake(31, 44) controlPoint1: CGPointMake(32.97, 37) controlPoint2: CGPointMake(31, 39.92)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(51, 32)]; + [bezierPath addCurveToPoint: CGPointMake(49, 30) controlPoint1: CGPointMake(49.89, 32) controlPoint2: CGPointMake(49, 31.1)]; + [bezierPath addCurveToPoint: CGPointMake(51, 28) controlPoint1: CGPointMake(49, 28.9) controlPoint2: CGPointMake(49.89, 28)]; + [bezierPath addCurveToPoint: CGPointMake(53, 30) controlPoint1: CGPointMake(52.11, 28) controlPoint2: CGPointMake(53, 28.9)]; + [bezierPath addCurveToPoint: CGPointMake(51, 32) controlPoint1: CGPointMake(53, 31.1) controlPoint2: CGPointMake(52.11, 32)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(49, 54)]; + [bezierPath addLineToPoint: CGPointMake(49, 35)]; + [bezierPath addLineToPoint: CGPointMake(53, 35)]; + [bezierPath addLineToPoint: CGPointMake(53, 54)]; + [bezierPath addLineToPoint: CGPointMake(49, 54)]; + [bezierPath addLineToPoint: CGPointMake(49, 54)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(70, 41)]; + [bezierPath addCurveToPoint: CGPointMake(65.5, 37) controlPoint1: CGPointMake(70, 38.71) controlPoint2: CGPointMake(68.28, 37)]; + [bezierPath addCurveToPoint: CGPointMake(62, 38) controlPoint1: CGPointMake(64.01, 37) controlPoint2: CGPointMake(62.82, 37.67)]; + [bezierPath addLineToPoint: CGPointMake(62, 54)]; + [bezierPath addLineToPoint: CGPointMake(58, 54)]; + [bezierPath addLineToPoint: CGPointMake(58, 35.38)]; + [bezierPath addCurveToPoint: CGPointMake(65.5, 34) controlPoint1: CGPointMake(60, 34.58) controlPoint2: CGPointMake(62.38, 34)]; + [bezierPath addCurveToPoint: CGPointMake(74, 40.55) controlPoint1: CGPointMake(71.11, 34) controlPoint2: CGPointMake(74, 36.4)]; + [bezierPath addLineToPoint: CGPointMake(74, 54)]; + [bezierPath addLineToPoint: CGPointMake(70, 54)]; + [bezierPath addLineToPoint: CGPointMake(70, 41)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(78, 52.66)]; + [bezierPath addLineToPoint: CGPointMake(78, 26)]; + [bezierPath addLineToPoint: CGPointMake(81.9, 26)]; + [bezierPath addLineToPoint: CGPointMake(81.9, 35.15)]; + [bezierPath addCurveToPoint: CGPointMake(85.5, 34) controlPoint1: CGPointMake(82.83, 34.72) controlPoint2: CGPointMake(84.18, 34)]; + [bezierPath addCurveToPoint: CGPointMake(94, 43.69) controlPoint1: CGPointMake(90.48, 34) controlPoint2: CGPointMake(94, 37.89)]; + [bezierPath addCurveToPoint: CGPointMake(84.48, 54) controlPoint1: CGPointMake(94, 50.83) controlPoint2: CGPointMake(90.24, 54)]; + [bezierPath addCurveToPoint: CGPointMake(78, 52.66) controlPoint1: CGPointMake(81.97, 54) controlPoint2: CGPointMake(79.5, 53.4)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(85, 37)]; + [bezierPath addCurveToPoint: CGPointMake(82, 37.65) controlPoint1: CGPointMake(83.96, 37) controlPoint2: CGPointMake(82.73, 37.25)]; + [bezierPath addLineToPoint: CGPointMake(82, 50.49)]; + [bezierPath addCurveToPoint: CGPointMake(84.72, 51) controlPoint1: CGPointMake(82.56, 50.75) controlPoint2: CGPointMake(83.64, 51)]; + [bezierPath addCurveToPoint: CGPointMake(90, 43.82) controlPoint1: CGPointMake(87.76, 51) controlPoint2: CGPointMake(90, 48.82)]; + [bezierPath addCurveToPoint: CGPointMake(85, 37) controlPoint1: CGPointMake(90, 39.54) controlPoint2: CGPointMake(88.04, 37)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(97, 48)]; + [bezierPath addCurveToPoint: CGPointMake(108, 41.5) controlPoint1: CGPointMake(97, 42.72) controlPoint2: CGPointMake(102.19, 41.82)]; + [bezierPath addLineToPoint: CGPointMake(108, 40)]; + [bezierPath addCurveToPoint: CGPointMake(104.5, 37) controlPoint1: CGPointMake(108, 37.61) controlPoint2: CGPointMake(106.96, 37)]; + [bezierPath addCurveToPoint: CGPointMake(98.9, 38.24) controlPoint1: CGPointMake(102.68, 37) controlPoint2: CGPointMake(100.18, 37.64)]; + [bezierPath addLineToPoint: CGPointMake(97.9, 35.6)]; + [bezierPath addCurveToPoint: CGPointMake(104.5, 34) controlPoint1: CGPointMake(99.43, 34.93) controlPoint2: CGPointMake(101.93, 34)]; + [bezierPath addCurveToPoint: CGPointMake(111.99, 40.7) controlPoint1: CGPointMake(109.1, 34) controlPoint2: CGPointMake(111.99, 36.03)]; + [bezierPath addLineToPoint: CGPointMake(111.99, 52.66)]; + [bezierPath addCurveToPoint: CGPointMake(105.07, 54) controlPoint1: CGPointMake(110.6, 53.4) controlPoint2: CGPointMake(107.78, 54)]; + [bezierPath addCurveToPoint: CGPointMake(97, 48) controlPoint1: CGPointMake(99.54, 54) controlPoint2: CGPointMake(97, 51.73)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(100.5, 48)]; + [bezierPath addCurveToPoint: CGPointMake(105, 51) controlPoint1: CGPointMake(100.5, 50.01) controlPoint2: CGPointMake(102.04, 51)]; + [bezierPath addLineToPoint: CGPointMake(108, 51)]; + [bezierPath addLineToPoint: CGPointMake(108, 44)]; + [bezierPath addCurveToPoint: CGPointMake(100.5, 48) controlPoint1: CGPointMake(104.08, 44.21) controlPoint2: CGPointMake(100.5, 44.62)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(121.79, 54)]; + [bezierPath addCurveToPoint: CGPointMake(116, 52.65) controlPoint1: CGPointMake(119.62, 54) controlPoint2: CGPointMake(117.35, 53.39)]; + [bezierPath addLineToPoint: CGPointMake(117.28, 49.65)]; + [bezierPath addCurveToPoint: CGPointMake(121.69, 50.9) controlPoint1: CGPointMake(118.24, 50.26) controlPoint2: CGPointMake(120.28, 50.9)]; + [bezierPath addCurveToPoint: CGPointMake(125.07, 48.26) controlPoint1: CGPointMake(123.72, 50.9) controlPoint2: CGPointMake(125.07, 49.86)]; + [bezierPath addCurveToPoint: CGPointMake(121.76, 45.12) controlPoint1: CGPointMake(125.07, 46.51) controlPoint2: CGPointMake(123.66, 45.84)]; + [bezierPath addCurveToPoint: CGPointMake(116.48, 39.38) controlPoint1: CGPointMake(119.28, 44.16) controlPoint2: CGPointMake(116.48, 42.98)]; + [bezierPath addCurveToPoint: CGPointMake(123, 34) controlPoint1: CGPointMake(116.48, 36.21) controlPoint2: CGPointMake(118.86, 34)]; + [bezierPath addCurveToPoint: CGPointMake(128.41, 35.35) controlPoint1: CGPointMake(125.24, 34) controlPoint2: CGPointMake(127.1, 34.57)]; + [bezierPath addLineToPoint: CGPointMake(127.24, 38.06)]; + [bezierPath addCurveToPoint: CGPointMake(123.41, 36.92) controlPoint1: CGPointMake(126.41, 37.53) controlPoint2: CGPointMake(124.76, 36.92)]; + [bezierPath addCurveToPoint: CGPointMake(120.34, 39.38) controlPoint1: CGPointMake(121.45, 36.92) controlPoint2: CGPointMake(120.34, 37.99)]; + [bezierPath addCurveToPoint: CGPointMake(123.55, 42.45) controlPoint1: CGPointMake(120.34, 41.13) controlPoint2: CGPointMake(121.72, 41.74)]; + [bezierPath addCurveToPoint: CGPointMake(129, 48.3) controlPoint1: CGPointMake(126.14, 43.45) controlPoint2: CGPointMake(129, 44.55)]; + [bezierPath addCurveToPoint: CGPointMake(121.79, 54) controlPoint1: CGPointMake(129, 51.75) controlPoint2: CGPointMake(126.45, 54)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(136, 46)]; + [bezierPath addCurveToPoint: CGPointMake(142.08, 50.94) controlPoint1: CGPointMake(136.39, 49.41) controlPoint2: CGPointMake(138.84, 50.94)]; + [bezierPath addCurveToPoint: CGPointMake(147.39, 49.78) controlPoint1: CGPointMake(144.01, 50.94) controlPoint2: CGPointMake(146.08, 50.48)]; + [bezierPath addLineToPoint: CGPointMake(148.54, 52.66)]; + [bezierPath addCurveToPoint: CGPointMake(141.83, 54) controlPoint1: CGPointMake(147.04, 53.44) controlPoint2: CGPointMake(144.47, 54)]; + [bezierPath addCurveToPoint: CGPointMake(132, 44.04) controlPoint1: CGPointMake(135.77, 54) controlPoint2: CGPointMake(132, 50.1)]; + [bezierPath addCurveToPoint: CGPointMake(141, 34) controlPoint1: CGPointMake(132, 38.24) controlPoint2: CGPointMake(135.62, 34)]; + [bezierPath addCurveToPoint: CGPointMake(149, 42.6) controlPoint1: CGPointMake(145.99, 34) controlPoint2: CGPointMake(149, 37.5)]; + [bezierPath addCurveToPoint: CGPointMake(148.96, 44.04) controlPoint1: CGPointMake(149, 43.06) controlPoint2: CGPointMake(149, 43.55)]; + [bezierPath addLineToPoint: CGPointMake(136, 46)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(140.98, 37.08)]; + [bezierPath addCurveToPoint: CGPointMake(135.95, 43.27) controlPoint1: CGPointMake(137.98, 37.08) controlPoint2: CGPointMake(136.02, 39.33)]; + [bezierPath addLineToPoint: CGPointMake(145.26, 42)]; + [bezierPath addCurveToPoint: CGPointMake(140.98, 37.08) controlPoint1: CGPointMake(145.22, 38.7) controlPoint2: CGPointMake(143.54, 37.08)]; + [bezierPath addLineToPoint: CGPointMake(140.98, 37.08)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + bezierPath.usesEvenOddFillRule = YES; + + [self.color setFill]; + [bezierPath fill]; + } + } + } +} + +- (void)updateConstraints { + NSLayoutConstraint *aspectRatioConstraint = [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeWidth + relatedBy:NSLayoutRelationEqual + toItem:self + attribute:NSLayoutAttributeHeight + multiplier:(self.artDimensions.width / self.artDimensions.height) + constant:0.0f]; + aspectRatioConstraint.priority = UILayoutPriorityRequired; + + [self addConstraints:@[aspectRatioConstraint]]; + + [super updateConstraints]; +} + +- (UILayoutPriority)contentCompressionResistancePriorityForAxis:(__unused UILayoutConstraintAxis)axis { + return UILayoutPriorityRequired; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIDinersClubVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIDinersClubVectorArtView.h new file mode 100644 index 0000000..aa2251d --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIDinersClubVectorArtView.h @@ -0,0 +1,5 @@ +#import "BTUICardVectorArtView.h" + +@interface BTUIDinersClubVectorArtView : BTUICardVectorArtView + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIDinersClubVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIDinersClubVectorArtView.m new file mode 100644 index 0000000..8dbc16d --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIDinersClubVectorArtView.m @@ -0,0 +1,66 @@ +#import "BTUIDinersClubVectorArtView.h" + +@implementation BTUIDinersClubVectorArtView + +- (void)drawArt { + //// Color Declarations + UIColor* color1 = [UIColor colorWithRed: 0.019 green: 0.213 blue: 0.52 alpha: 1]; + UIColor* color2 = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + + //// Page-1 + { + //// Diners-Club + { + //// Shape + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(46, 44)]; + [bezierPath addCurveToPoint: CGPointMake(64, 28) controlPoint1: CGPointMake(55.5, 44.04) controlPoint2: CGPointMake(64, 36.64)]; + [bezierPath addCurveToPoint: CGPointMake(46, 11) controlPoint1: CGPointMake(64, 17.8) controlPoint2: CGPointMake(55.5, 11)]; + [bezierPath addLineToPoint: CGPointMake(38, 11)]; + [bezierPath addCurveToPoint: CGPointMake(21, 28) controlPoint1: CGPointMake(28.76, 11) controlPoint2: CGPointMake(21, 17.8)]; + [bezierPath addCurveToPoint: CGPointMake(38, 44) controlPoint1: CGPointMake(21, 36.65) controlPoint2: CGPointMake(28.76, 44.04)]; + [bezierPath addLineToPoint: CGPointMake(46, 44)]; + [bezierPath addLineToPoint: CGPointMake(46, 44)]; + [bezierPath addLineToPoint: CGPointMake(46, 44)]; + [bezierPath addLineToPoint: CGPointMake(46, 44)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + bezierPath.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezierPath fill]; + + + //// Bezier 2 Drawing + UIBezierPath* bezier2Path = [UIBezierPath bezierPath]; + [bezier2Path moveToPoint: CGPointMake(40.6, 36.8)]; + [bezier2Path addLineToPoint: CGPointMake(40.6, 18.2)]; + [bezier2Path addCurveToPoint: CGPointMake(46.8, 27.5) controlPoint1: CGPointMake(44.22, 19.63) controlPoint2: CGPointMake(46.79, 23.25)]; + [bezier2Path addCurveToPoint: CGPointMake(40.6, 36.8) controlPoint1: CGPointMake(46.79, 31.75) controlPoint2: CGPointMake(44.22, 35.36)]; + [bezier2Path closePath]; + [bezier2Path moveToPoint: CGPointMake(27.17, 27.5)]; + [bezier2Path addCurveToPoint: CGPointMake(33.37, 18.2) controlPoint1: CGPointMake(27.18, 23.26) controlPoint2: CGPointMake(29.74, 19.64)]; + [bezier2Path addLineToPoint: CGPointMake(33.37, 36.8)]; + [bezier2Path addCurveToPoint: CGPointMake(27.17, 27.5) controlPoint1: CGPointMake(29.74, 35.36) controlPoint2: CGPointMake(27.18, 31.75)]; + [bezier2Path closePath]; + [bezier2Path moveToPoint: CGPointMake(37.5, 12)]; + [bezier2Path addCurveToPoint: CGPointMake(22, 27.5) controlPoint1: CGPointMake(28.94, 12) controlPoint2: CGPointMake(22, 18.94)]; + [bezier2Path addCurveToPoint: CGPointMake(37.5, 43) controlPoint1: CGPointMake(22, 36.06) controlPoint2: CGPointMake(28.94, 43)]; + [bezier2Path addCurveToPoint: CGPointMake(53, 27.5) controlPoint1: CGPointMake(46.06, 43) controlPoint2: CGPointMake(53, 36.06)]; + [bezier2Path addCurveToPoint: CGPointMake(37.5, 12) controlPoint1: CGPointMake(53, 18.94) controlPoint2: CGPointMake(46.06, 12)]; + [bezier2Path closePath]; + bezier2Path.miterLimit = 4; + + bezier2Path.usesEvenOddFillRule = YES; + + [color2 setFill]; + [bezier2Path fill]; + } + } + } +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIDiscoverVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIDiscoverVectorArtView.h new file mode 100644 index 0000000..ba9aa79 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIDiscoverVectorArtView.h @@ -0,0 +1,5 @@ +#import "BTUICardVectorArtView.h" + +@interface BTUIDiscoverVectorArtView : BTUICardVectorArtView + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIDiscoverVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIDiscoverVectorArtView.m new file mode 100644 index 0000000..c4d3f3d --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIDiscoverVectorArtView.m @@ -0,0 +1,213 @@ +#import "BTUIDiscoverVectorArtView.h" + +@implementation BTUIDiscoverVectorArtView + +- (void)drawArt { + //// Color Declarations + UIColor* color2 = [UIColor colorWithRed: 0.879 green: 0.425 blue: 0.167 alpha: 1]; + UIColor* color1 = [UIColor colorWithRed: 0.042 green: 0.053 blue: 0.066 alpha: 1]; + + //// Page-1 + { + //// Discover + { + //// Group 4 + { + //// Group 5 + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(13.13, 22)]; + [bezierPath addLineToPoint: CGPointMake(10, 22)]; + [bezierPath addLineToPoint: CGPointMake(10, 33)]; + [bezierPath addLineToPoint: CGPointMake(13.12, 33)]; + [bezierPath addCurveToPoint: CGPointMake(17.02, 31.73) controlPoint1: CGPointMake(14.77, 33) controlPoint2: CGPointMake(15.97, 32.61)]; + [bezierPath addCurveToPoint: CGPointMake(19, 27.51) controlPoint1: CGPointMake(18.26, 30.69) controlPoint2: CGPointMake(19, 29.12)]; + [bezierPath addCurveToPoint: CGPointMake(13.13, 22) controlPoint1: CGPointMake(19, 24.26) controlPoint2: CGPointMake(16.59, 22)]; + [bezierPath addLineToPoint: CGPointMake(13.13, 22)]; + [bezierPath addLineToPoint: CGPointMake(13.13, 22)]; + [bezierPath addLineToPoint: CGPointMake(13.13, 22)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(15.74, 30.16)]; + [bezierPath addCurveToPoint: CGPointMake(12.61, 31) controlPoint1: CGPointMake(15.02, 30.75) controlPoint2: CGPointMake(14.09, 31)]; + [bezierPath addLineToPoint: CGPointMake(12, 31)]; + [bezierPath addLineToPoint: CGPointMake(12, 24)]; + [bezierPath addLineToPoint: CGPointMake(12.61, 24)]; + [bezierPath addCurveToPoint: CGPointMake(15.74, 24.86) controlPoint1: CGPointMake(14.09, 24) controlPoint2: CGPointMake(14.98, 24.24)]; + [bezierPath addCurveToPoint: CGPointMake(17, 27.49) controlPoint1: CGPointMake(16.53, 25.49) controlPoint2: CGPointMake(17, 26.47)]; + [bezierPath addCurveToPoint: CGPointMake(15.74, 30.16) controlPoint1: CGPointMake(17, 28.51) controlPoint2: CGPointMake(16.53, 29.52)]; + [bezierPath addLineToPoint: CGPointMake(15.74, 30.16)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + bezierPath.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezierPath fill]; + + + //// Bezier 2 Drawing + UIBezierPath* bezier2Path = [UIBezierPath bezierPath]; + [bezier2Path moveToPoint: CGPointMake(20, 22)]; + [bezier2Path addLineToPoint: CGPointMake(22, 22)]; + [bezier2Path addLineToPoint: CGPointMake(22, 33)]; + [bezier2Path addLineToPoint: CGPointMake(20, 33)]; + [bezier2Path addLineToPoint: CGPointMake(20, 33)]; + [bezier2Path addLineToPoint: CGPointMake(20, 22)]; + [bezier2Path addLineToPoint: CGPointMake(20, 22)]; + [bezier2Path closePath]; + bezier2Path.miterLimit = 4; + + bezier2Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier2Path fill]; + + + //// Bezier 3 Drawing + UIBezierPath* bezier3Path = [UIBezierPath bezierPath]; + [bezier3Path moveToPoint: CGPointMake(27.09, 26.23)]; + [bezier3Path addCurveToPoint: CGPointMake(25.55, 24.9) controlPoint1: CGPointMake(25.9, 25.77) controlPoint2: CGPointMake(25.55, 25.47)]; + [bezier3Path addCurveToPoint: CGPointMake(27.02, 23.73) controlPoint1: CGPointMake(25.55, 24.23) controlPoint2: CGPointMake(26.17, 23.73)]; + [bezier3Path addCurveToPoint: CGPointMake(28.62, 24.58) controlPoint1: CGPointMake(27.62, 23.73) controlPoint2: CGPointMake(28.1, 23.98)]; + [bezier3Path addLineToPoint: CGPointMake(29.65, 23.17)]; + [bezier3Path addCurveToPoint: CGPointMake(26.67, 22) controlPoint1: CGPointMake(28.8, 22.4) controlPoint2: CGPointMake(27.78, 22)]; + [bezier3Path addCurveToPoint: CGPointMake(23.52, 25.03) controlPoint1: CGPointMake(24.88, 22) controlPoint2: CGPointMake(23.52, 23.3)]; + [bezier3Path addCurveToPoint: CGPointMake(26.01, 27.93) controlPoint1: CGPointMake(23.52, 26.48) controlPoint2: CGPointMake(24.15, 27.23)]; + [bezier3Path addCurveToPoint: CGPointMake(27.37, 28.53) controlPoint1: CGPointMake(26.78, 28.21) controlPoint2: CGPointMake(27.17, 28.4)]; + [bezier3Path addCurveToPoint: CGPointMake(27.97, 29.62) controlPoint1: CGPointMake(27.77, 28.8) controlPoint2: CGPointMake(27.97, 29.18)]; + [bezier3Path addCurveToPoint: CGPointMake(26.43, 31.11) controlPoint1: CGPointMake(27.97, 30.48) controlPoint2: CGPointMake(27.31, 31.11)]; + [bezier3Path addCurveToPoint: CGPointMake(24.27, 29.7) controlPoint1: CGPointMake(25.49, 31.11) controlPoint2: CGPointMake(24.73, 30.62)]; + [bezier3Path addLineToPoint: CGPointMake(23, 30.99)]; + [bezier3Path addCurveToPoint: CGPointMake(26.51, 33) controlPoint1: CGPointMake(23.91, 32.38) controlPoint2: CGPointMake(25, 33)]; + [bezier3Path addCurveToPoint: CGPointMake(30, 29.53) controlPoint1: CGPointMake(28.56, 33) controlPoint2: CGPointMake(30, 31.57)]; + [bezier3Path addCurveToPoint: CGPointMake(27.09, 26.23) controlPoint1: CGPointMake(30, 27.85) controlPoint2: CGPointMake(29.33, 27.09)]; + [bezier3Path closePath]; + bezier3Path.miterLimit = 4; + + bezier3Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier3Path fill]; + + + //// Bezier 4 Drawing + UIBezierPath* bezier4Path = [UIBezierPath bezierPath]; + [bezier4Path moveToPoint: CGPointMake(31, 27.51)]; + [bezier4Path addCurveToPoint: CGPointMake(36.47, 33) controlPoint1: CGPointMake(31, 30.6) controlPoint2: CGPointMake(33.39, 33)]; + [bezier4Path addCurveToPoint: CGPointMake(39, 32.39) controlPoint1: CGPointMake(37.34, 33) controlPoint2: CGPointMake(38.08, 32.83)]; + [bezier4Path addLineToPoint: CGPointMake(39, 29.97)]; + [bezier4Path addCurveToPoint: CGPointMake(36.56, 31.12) controlPoint1: CGPointMake(38.19, 30.79) controlPoint2: CGPointMake(37.48, 31.12)]; + [bezier4Path addCurveToPoint: CGPointMake(33.08, 27.49) controlPoint1: CGPointMake(34.53, 31.12) controlPoint2: CGPointMake(33.08, 29.62)]; + [bezier4Path addCurveToPoint: CGPointMake(36.47, 23.88) controlPoint1: CGPointMake(33.08, 25.47) controlPoint2: CGPointMake(34.57, 23.88)]; + [bezier4Path addCurveToPoint: CGPointMake(39, 25.06) controlPoint1: CGPointMake(37.43, 23.88) controlPoint2: CGPointMake(38.16, 24.22)]; + [bezier4Path addLineToPoint: CGPointMake(39, 22.64)]; + [bezier4Path addCurveToPoint: CGPointMake(36.51, 22) controlPoint1: CGPointMake(38.11, 22.19) controlPoint2: CGPointMake(37.38, 22)]; + [bezier4Path addCurveToPoint: CGPointMake(31, 27.51) controlPoint1: CGPointMake(33.45, 22) controlPoint2: CGPointMake(31, 24.45)]; + [bezier4Path closePath]; + bezier4Path.miterLimit = 4; + + bezier4Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier4Path fill]; + + + //// Bezier 5 Drawing + UIBezierPath* bezier5Path = [UIBezierPath bezierPath]; + [bezier5Path moveToPoint: CGPointMake(55.99, 29.2)]; + [bezier5Path addLineToPoint: CGPointMake(53.22, 22)]; + [bezier5Path addLineToPoint: CGPointMake(51, 22)]; + [bezier5Path addLineToPoint: CGPointMake(55.42, 33)]; + [bezier5Path addLineToPoint: CGPointMake(56.51, 33)]; + [bezier5Path addLineToPoint: CGPointMake(61, 22)]; + [bezier5Path addLineToPoint: CGPointMake(58.8, 22)]; + [bezier5Path addLineToPoint: CGPointMake(55.99, 29.2)]; + [bezier5Path closePath]; + bezier5Path.miterLimit = 4; + + bezier5Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier5Path fill]; + + + //// Bezier 6 Drawing + UIBezierPath* bezier6Path = [UIBezierPath bezierPath]; + [bezier6Path moveToPoint: CGPointMake(62, 33)]; + [bezier6Path addLineToPoint: CGPointMake(68, 33)]; + [bezier6Path addLineToPoint: CGPointMake(68, 31.14)]; + [bezier6Path addLineToPoint: CGPointMake(64.11, 31.14)]; + [bezier6Path addLineToPoint: CGPointMake(64.11, 28.17)]; + [bezier6Path addLineToPoint: CGPointMake(67.85, 28.17)]; + [bezier6Path addLineToPoint: CGPointMake(67.85, 26.3)]; + [bezier6Path addLineToPoint: CGPointMake(64.11, 26.3)]; + [bezier6Path addLineToPoint: CGPointMake(64.11, 23.86)]; + [bezier6Path addLineToPoint: CGPointMake(68, 23.86)]; + [bezier6Path addLineToPoint: CGPointMake(68, 22)]; + [bezier6Path addLineToPoint: CGPointMake(62, 22)]; + [bezier6Path addLineToPoint: CGPointMake(62, 33)]; + [bezier6Path closePath]; + bezier6Path.miterLimit = 4; + + bezier6Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier6Path fill]; + + + //// Bezier 7 Drawing + UIBezierPath* bezier7Path = [UIBezierPath bezierPath]; + [bezier7Path moveToPoint: CGPointMake(77.05, 25.25)]; + [bezier7Path addCurveToPoint: CGPointMake(73.17, 22) controlPoint1: CGPointMake(77.05, 23.19) controlPoint2: CGPointMake(75.64, 22)]; + [bezier7Path addLineToPoint: CGPointMake(70, 22)]; + [bezier7Path addLineToPoint: CGPointMake(70, 33)]; + [bezier7Path addLineToPoint: CGPointMake(72.14, 33)]; + [bezier7Path addLineToPoint: CGPointMake(72.14, 28.58)]; + [bezier7Path addLineToPoint: CGPointMake(72.42, 28.58)]; + [bezier7Path addLineToPoint: CGPointMake(75.37, 33)]; + [bezier7Path addLineToPoint: CGPointMake(78, 33)]; + [bezier7Path addLineToPoint: CGPointMake(74.55, 28.37)]; + [bezier7Path addCurveToPoint: CGPointMake(77.05, 25.25) controlPoint1: CGPointMake(76.16, 28.04) controlPoint2: CGPointMake(77.05, 26.93)]; + [bezier7Path addCurveToPoint: CGPointMake(77.05, 25.25) controlPoint1: CGPointMake(77.05, 25.25) controlPoint2: CGPointMake(77.05, 26.93)]; + [bezier7Path addLineToPoint: CGPointMake(77.05, 25.25)]; + [bezier7Path addLineToPoint: CGPointMake(77.05, 25.25)]; + [bezier7Path closePath]; + [bezier7Path moveToPoint: CGPointMake(72.69, 27)]; + [bezier7Path addLineToPoint: CGPointMake(72, 27)]; + [bezier7Path addLineToPoint: CGPointMake(72, 24)]; + [bezier7Path addLineToPoint: CGPointMake(72.73, 24)]; + [bezier7Path addCurveToPoint: CGPointMake(75, 25.47) controlPoint1: CGPointMake(74.2, 24) controlPoint2: CGPointMake(75, 24.51)]; + [bezier7Path addCurveToPoint: CGPointMake(72.69, 27) controlPoint1: CGPointMake(75, 26.46) controlPoint2: CGPointMake(74.2, 27)]; + [bezier7Path addLineToPoint: CGPointMake(72.69, 27)]; + [bezier7Path closePath]; + bezier7Path.miterLimit = 4; + + bezier7Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier7Path fill]; + + + //// Bezier 8 Drawing + UIBezierPath* bezier8Path = [UIBezierPath bezierPath]; + [bezier8Path moveToPoint: CGPointMake(45.5, 33)]; + [bezier8Path addCurveToPoint: CGPointMake(51, 27.5) controlPoint1: CGPointMake(48.54, 33) controlPoint2: CGPointMake(51, 30.54)]; + [bezier8Path addCurveToPoint: CGPointMake(45.5, 22) controlPoint1: CGPointMake(51, 24.46) controlPoint2: CGPointMake(48.54, 22)]; + [bezier8Path addCurveToPoint: CGPointMake(40, 27.5) controlPoint1: CGPointMake(42.46, 22) controlPoint2: CGPointMake(40, 24.46)]; + [bezier8Path addCurveToPoint: CGPointMake(45.5, 33) controlPoint1: CGPointMake(40, 30.54) controlPoint2: CGPointMake(42.46, 33)]; + [bezier8Path closePath]; + bezier8Path.miterLimit = 4; + + bezier8Path.usesEvenOddFillRule = YES; + + [color2 setFill]; + [bezier8Path fill]; + } + } + } + } + + +} +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIJCBVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIJCBVectorArtView.h new file mode 100644 index 0000000..bcfb5b3 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIJCBVectorArtView.h @@ -0,0 +1,5 @@ +#import "BTUICardVectorArtView.h" + +@interface BTUIJCBVectorArtView : BTUICardVectorArtView + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIJCBVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIJCBVectorArtView.m new file mode 100644 index 0000000..d806e83 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIJCBVectorArtView.m @@ -0,0 +1,179 @@ +#import "BTUIJCBVectorArtView.h" + +@implementation BTUIJCBVectorArtView + +- (void)drawArt { + //// General Declarations + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = UIGraphicsGetCurrentContext(); + + //// Color Declarations + UIColor* color1 = [UIColor colorWithRed: 0.262 green: 0.646 blue: 0.146 alpha: 1]; + UIColor* color2 = [UIColor colorWithRed: 0.279 green: 0.659 blue: 0.143 alpha: 1]; + UIColor* color3 = [UIColor colorWithRed: 0.041 green: 0.33 blue: 0.659 alpha: 1]; + UIColor* color4 = [UIColor colorWithRed: 0.041 green: 0.341 blue: 0.673 alpha: 1]; + UIColor* color5 = [UIColor colorWithRed: 0.833 green: 0 blue: 0.166 alpha: 1]; + UIColor* color6 = [UIColor colorWithRed: 0.852 green: 0 blue: 0.169 alpha: 1]; + + //// Gradient Declarations + NSArray* linearGradient3Colors = [NSArray arrayWithObjects: + (id)color5.CGColor, + (id)color6.CGColor, nil]; + CGFloat linearGradient3Locations[] = {0, 1}; + CGGradientRef linearGradient3 = CGGradientCreateWithColors(colorSpace, (CFArrayRef)linearGradient3Colors, linearGradient3Locations); + NSArray* linearGradient1Colors = [NSArray arrayWithObjects: + (id)color1.CGColor, + (id)color2.CGColor, nil]; + CGFloat linearGradient1Locations[] = {0, 1}; + CGGradientRef linearGradient1 = CGGradientCreateWithColors(colorSpace, (CFArrayRef)linearGradient1Colors, linearGradient1Locations); + NSArray* linearGradient2Colors = [NSArray arrayWithObjects: + (id)color3.CGColor, + (id)color4.CGColor, nil]; + CGFloat linearGradient2Locations[] = {0, 1}; + CGGradientRef linearGradient2 = CGGradientCreateWithColors(colorSpace, (CFArrayRef)linearGradient2Colors, linearGradient2Locations); + + + + //// Page-1 + { + //// JCB + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(55.66, 28.16)]; + [bezierPath addCurveToPoint: CGPointMake(58.73, 28.16) controlPoint1: CGPointMake(56.68, 28.16) controlPoint2: CGPointMake(57.71, 28.16)]; + [bezierPath addCurveToPoint: CGPointMake(59.1, 28.16) controlPoint1: CGPointMake(58.82, 28.16) controlPoint2: CGPointMake(59.01, 28.16)]; + [bezierPath addLineToPoint: CGPointMake(59.1, 28.16)]; + [bezierPath addCurveToPoint: CGPointMake(59.1, 31.02) controlPoint1: CGPointMake(60.5, 28.45) controlPoint2: CGPointMake(60.5, 30.63)]; + [bezierPath addLineToPoint: CGPointMake(59.1, 31.02)]; + [bezierPath addCurveToPoint: CGPointMake(58.73, 31.02) controlPoint1: CGPointMake(59.01, 31.02) controlPoint2: CGPointMake(58.92, 31.02)]; + [bezierPath addCurveToPoint: CGPointMake(55.66, 31.02) controlPoint1: CGPointMake(57.71, 31.02) controlPoint2: CGPointMake(56.68, 31.02)]; + [bezierPath addLineToPoint: CGPointMake(55.66, 28.16)]; + [bezierPath addLineToPoint: CGPointMake(55.66, 28.16)]; + [bezierPath addLineToPoint: CGPointMake(55.66, 28.16)]; + [bezierPath addLineToPoint: CGPointMake(55.66, 28.16)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(59.75, 24.79)]; + [bezierPath addCurveToPoint: CGPointMake(58.73, 26.47) controlPoint1: CGPointMake(59.94, 25.58) controlPoint2: CGPointMake(59.47, 26.28)]; + [bezierPath addCurveToPoint: CGPointMake(58.45, 26.47) controlPoint1: CGPointMake(58.64, 26.47) controlPoint2: CGPointMake(58.54, 26.47)]; + [bezierPath addCurveToPoint: CGPointMake(55.66, 26.47) controlPoint1: CGPointMake(57.52, 26.47) controlPoint2: CGPointMake(56.59, 26.47)]; + [bezierPath addLineToPoint: CGPointMake(55.66, 23.8)]; + [bezierPath addCurveToPoint: CGPointMake(58.45, 23.8) controlPoint1: CGPointMake(56.59, 23.8) controlPoint2: CGPointMake(57.52, 23.8)]; + [bezierPath addLineToPoint: CGPointMake(58.45, 23.8)]; + [bezierPath addCurveToPoint: CGPointMake(58.73, 23.8) controlPoint1: CGPointMake(58.54, 23.8) controlPoint2: CGPointMake(58.64, 23.8)]; + [bezierPath addLineToPoint: CGPointMake(58.73, 23.8)]; + [bezierPath addCurveToPoint: CGPointMake(59.75, 24.79) controlPoint1: CGPointMake(59.19, 23.9) controlPoint2: CGPointMake(59.66, 24.3)]; + [bezierPath addLineToPoint: CGPointMake(59.75, 24.79)]; + [bezierPath addLineToPoint: CGPointMake(59.75, 24.79)]; + [bezierPath addLineToPoint: CGPointMake(59.75, 24.79)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(66.54, 38.54)]; + [bezierPath addCurveToPoint: CGPointMake(61.98, 43.89) controlPoint1: CGPointMake(66.54, 41.12) controlPoint2: CGPointMake(64.31, 43.29)]; + [bezierPath addCurveToPoint: CGPointMake(52.59, 43.99) controlPoint1: CGPointMake(60.87, 44.18) controlPoint2: CGPointMake(52.59, 43.99)]; + [bezierPath addLineToPoint: CGPointMake(52.59, 33.1)]; + [bezierPath addCurveToPoint: CGPointMake(58.82, 33.1) controlPoint1: CGPointMake(52.59, 33.1) controlPoint2: CGPointMake(56.87, 33.1)]; + [bezierPath addCurveToPoint: CGPointMake(64.49, 30.93) controlPoint1: CGPointMake(60.68, 33.1) controlPoint2: CGPointMake(63.66, 33.2)]; + [bezierPath addCurveToPoint: CGPointMake(61.61, 27.36) controlPoint1: CGPointMake(65.24, 28.75) controlPoint2: CGPointMake(63.29, 27.46)]; + [bezierPath addLineToPoint: CGPointMake(61.61, 27.26)]; + [bezierPath addCurveToPoint: CGPointMake(63.84, 23.9) controlPoint1: CGPointMake(63.1, 27.07) controlPoint2: CGPointMake(64.49, 25.68)]; + [bezierPath addCurveToPoint: CGPointMake(61.15, 22.22) controlPoint1: CGPointMake(63.47, 22.71) controlPoint2: CGPointMake(62.26, 22.32)]; + [bezierPath addCurveToPoint: CGPointMake(52.5, 22.22) controlPoint1: CGPointMake(59.47, 22.02) controlPoint2: CGPointMake(52.5, 22.22)]; + [bezierPath addLineToPoint: CGPointMake(52.5, 16.48)]; + [bezierPath addCurveToPoint: CGPointMake(52.59, 15.39) controlPoint1: CGPointMake(52.5, 16.08) controlPoint2: CGPointMake(52.5, 15.69)]; + [bezierPath addCurveToPoint: CGPointMake(57.99, 10.54) controlPoint1: CGPointMake(53.06, 12.92) controlPoint2: CGPointMake(55.66, 10.64)]; + [bezierPath addCurveToPoint: CGPointMake(66.35, 10.54) controlPoint1: CGPointMake(59.66, 10.45) controlPoint2: CGPointMake(66.35, 10.54)]; + [bezierPath addLineToPoint: CGPointMake(66.54, 38.54)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + bezierPath.usesEvenOddFillRule = YES; + + CGContextSaveGState(context); + [bezierPath addClip]; + CGContextDrawLinearGradient(context, linearGradient1, + CGPointMake(52.5, 27.28), + CGPointMake(66.54, 27.28), + kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation); + CGContextRestoreGState(context); + + + //// Bezier 2 Drawing + UIBezierPath* bezier2Path = [UIBezierPath bezierPath]; + [bezier2Path moveToPoint: CGPointMake(20.6, 30.23)]; + [bezier2Path addCurveToPoint: CGPointMake(20.5, 30.13) controlPoint1: CGPointMake(20.6, 30.23) controlPoint2: CGPointMake(20.5, 30.23)]; + [bezier2Path addLineToPoint: CGPointMake(20.5, 16.55)]; + [bezier2Path addCurveToPoint: CGPointMake(25.41, 10.54) controlPoint1: CGPointMake(20.5, 13.59) controlPoint2: CGPointMake(22.51, 10.74)]; + [bezier2Path addCurveToPoint: CGPointMake(34.54, 10.54) controlPoint1: CGPointMake(27.22, 10.45) controlPoint2: CGPointMake(34.54, 10.54)]; + [bezier2Path addLineToPoint: CGPointMake(34.54, 38.59)]; + [bezier2Path addCurveToPoint: CGPointMake(28.62, 44.01) controlPoint1: CGPointMake(34.54, 41.55) controlPoint2: CGPointMake(31.53, 43.91)]; + [bezier2Path addCurveToPoint: CGPointMake(20.5, 44.01) controlPoint1: CGPointMake(26.82, 44.1) controlPoint2: CGPointMake(20.5, 44.01)]; + [bezier2Path addLineToPoint: CGPointMake(20.5, 32.49)]; + [bezier2Path addCurveToPoint: CGPointMake(30.13, 32.59) controlPoint1: CGPointMake(23.61, 33.28) controlPoint2: CGPointMake(27.12, 33.67)]; + [bezier2Path addCurveToPoint: CGPointMake(32.53, 28.75) controlPoint1: CGPointMake(31.83, 31.9) controlPoint2: CGPointMake(32.53, 30.62)]; + [bezier2Path addLineToPoint: CGPointMake(32.53, 22.35)]; + [bezier2Path addCurveToPoint: CGPointMake(27.52, 22.35) controlPoint1: CGPointMake(30.93, 22.35) controlPoint2: CGPointMake(29.12, 22.35)]; + [bezier2Path addLineToPoint: CGPointMake(27.52, 28.75)]; + [bezier2Path addCurveToPoint: CGPointMake(22.41, 31.01) controlPoint1: CGPointMake(27.52, 32.1) controlPoint2: CGPointMake(24.51, 31.7)]; + [bezier2Path addCurveToPoint: CGPointMake(20.6, 30.23) controlPoint1: CGPointMake(21.8, 30.72) controlPoint2: CGPointMake(21.2, 30.42)]; + [bezier2Path addLineToPoint: CGPointMake(20.6, 30.23)]; + [bezier2Path addLineToPoint: CGPointMake(20.6, 30.23)]; + [bezier2Path addLineToPoint: CGPointMake(20.6, 30.23)]; + [bezier2Path addLineToPoint: CGPointMake(20.6, 30.23)]; + [bezier2Path closePath]; + bezier2Path.miterLimit = 4; + + bezier2Path.usesEvenOddFillRule = YES; + + CGContextSaveGState(context); + [bezier2Path addClip]; + CGContextDrawLinearGradient(context, linearGradient2, + CGPointMake(20.5, 27.28), + CGPointMake(34.54, 27.28), + kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation); + CGContextRestoreGState(context); + + //// Bezier 3 Drawing + UIBezierPath* bezier3Path = [UIBezierPath bezierPath]; + [bezier3Path moveToPoint: CGPointMake(36.5, 23.72)]; + [bezier3Path addLineToPoint: CGPointMake(36.5, 16.53)]; + [bezier3Path addCurveToPoint: CGPointMake(41.37, 10.62) controlPoint1: CGPointMake(36.5, 13.87) controlPoint2: CGPointMake(38.84, 11.12)]; + [bezier3Path addCurveToPoint: CGPointMake(50.54, 10.52) controlPoint1: CGPointMake(42.49, 10.43) controlPoint2: CGPointMake(50.54, 10.52)]; + [bezier3Path addLineToPoint: CGPointMake(50.54, 38.59)]; + [bezier3Path addCurveToPoint: CGPointMake(45.02, 44.01) controlPoint1: CGPointMake(50.54, 41.54) controlPoint2: CGPointMake(47.83, 43.81)]; + [bezier3Path addCurveToPoint: CGPointMake(36.5, 44.01) controlPoint1: CGPointMake(43.33, 44.1) controlPoint2: CGPointMake(36.5, 44.01)]; + [bezier3Path addLineToPoint: CGPointMake(36.5, 31.3)]; + [bezier3Path addCurveToPoint: CGPointMake(46.05, 32.88) controlPoint1: CGPointMake(38.84, 33.37) controlPoint2: CGPointMake(43.15, 33.27)]; + [bezier3Path addCurveToPoint: CGPointMake(48.57, 32.39) controlPoint1: CGPointMake(46.89, 32.78) controlPoint2: CGPointMake(47.73, 32.58)]; + [bezier3Path addLineToPoint: CGPointMake(48.57, 30.02)]; + [bezier3Path addCurveToPoint: CGPointMake(41.84, 30.81) controlPoint1: CGPointMake(46.61, 31.01) controlPoint2: CGPointMake(43.89, 31.89)]; + [bezier3Path addCurveToPoint: CGPointMake(39.96, 27.95) controlPoint1: CGPointMake(40.71, 30.22) controlPoint2: CGPointMake(40.06, 29.14)]; + [bezier3Path addCurveToPoint: CGPointMake(39.96, 26.97) controlPoint1: CGPointMake(39.96, 27.66) controlPoint2: CGPointMake(39.96, 27.36)]; + [bezier3Path addCurveToPoint: CGPointMake(46.7, 24.02) controlPoint1: CGPointMake(40.24, 23.33) controlPoint2: CGPointMake(44.18, 23.23)]; + [bezier3Path addCurveToPoint: CGPointMake(48.57, 24.8) controlPoint1: CGPointMake(47.36, 24.21) controlPoint2: CGPointMake(48.01, 24.51)]; + [bezier3Path addLineToPoint: CGPointMake(48.57, 22.44)]; + [bezier3Path addCurveToPoint: CGPointMake(39.5, 22.24) controlPoint1: CGPointMake(45.67, 21.75) controlPoint2: CGPointMake(42.49, 21.36)]; + [bezier3Path addCurveToPoint: CGPointMake(36.5, 23.72) controlPoint1: CGPointMake(38.65, 22.64) controlPoint2: CGPointMake(37.25, 23.03)]; + [bezier3Path closePath]; + bezier3Path.miterLimit = 4; + + bezier3Path.usesEvenOddFillRule = YES; + + CGContextSaveGState(context); + [bezier3Path addClip]; + CGContextDrawLinearGradient(context, linearGradient3, + CGPointMake(36.5, 27.28), + CGPointMake(50.54, 27.28), + kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation); + CGContextRestoreGState(context); + } + } + + //// Cleanup + CGGradientRelease(linearGradient3); + CGGradientRelease(linearGradient1); + CGGradientRelease(linearGradient2); + CGColorSpaceRelease(colorSpace); +} + + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIMaestroVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIMaestroVectorArtView.h new file mode 100644 index 0000000..7b63195 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIMaestroVectorArtView.h @@ -0,0 +1,5 @@ +#import "BTUICardVectorArtView.h" + +@interface BTUIMaestroVectorArtView : BTUICardVectorArtView + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIMaestroVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIMaestroVectorArtView.m new file mode 100644 index 0000000..81dd870 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIMaestroVectorArtView.m @@ -0,0 +1,309 @@ +#import "BTUIMaestroVectorArtView.h" + +@implementation BTUIMaestroVectorArtView + +- (void)drawArt { + //// Color Declarations + UIColor* color3 = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + UIColor* color1 = [UIColor colorWithRed: 0.067 green: 0.541 blue: 0.834 alpha: 1]; + UIColor* color2 = [UIColor colorWithRed: 0.899 green: 0 blue: 0.139 alpha: 1]; + + //// Page-1 + { + //// Maestro + { + //// Shape + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(43.91, 40.1)]; + [bezierPath addCurveToPoint: CGPointMake(49.5, 27.5) controlPoint1: CGPointMake(47.34, 36.99) controlPoint2: CGPointMake(49.5, 32.5)]; + [bezierPath addCurveToPoint: CGPointMake(43.91, 14.9) controlPoint1: CGPointMake(49.5, 22.5) controlPoint2: CGPointMake(47.34, 18.01)]; + [bezierPath addCurveToPoint: CGPointMake(32.5, 10.5) controlPoint1: CGPointMake(40.89, 12.17) controlPoint2: CGPointMake(36.89, 10.5)]; + [bezierPath addCurveToPoint: CGPointMake(15.5, 27.5) controlPoint1: CGPointMake(23.11, 10.5) controlPoint2: CGPointMake(15.5, 18.11)]; + [bezierPath addCurveToPoint: CGPointMake(32.5, 44.5) controlPoint1: CGPointMake(15.5, 36.89) controlPoint2: CGPointMake(23.11, 44.5)]; + [bezierPath addCurveToPoint: CGPointMake(43.91, 40.1) controlPoint1: CGPointMake(36.89, 44.5) controlPoint2: CGPointMake(40.89, 42.83)]; + [bezierPath addLineToPoint: CGPointMake(43.91, 40.1)]; + [bezierPath addLineToPoint: CGPointMake(43.91, 40.1)]; + [bezierPath addLineToPoint: CGPointMake(43.91, 40.1)]; + [bezierPath addLineToPoint: CGPointMake(43.91, 40.1)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + bezierPath.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezierPath fill]; + + + //// Bezier 2 Drawing + UIBezierPath* bezier2Path = [UIBezierPath bezierPath]; + [bezier2Path moveToPoint: CGPointMake(54.81, 11)]; + [bezier2Path addCurveToPoint: CGPointMake(43.27, 15.4) controlPoint1: CGPointMake(50.36, 11) controlPoint2: CGPointMake(46.32, 12.67)]; + [bezier2Path addCurveToPoint: CGPointMake(41.53, 17.2) controlPoint1: CGPointMake(42.64, 15.96) controlPoint2: CGPointMake(42.06, 16.56)]; + [bezier2Path addLineToPoint: CGPointMake(45, 17.2)]; + [bezier2Path addCurveToPoint: CGPointMake(46.31, 19) controlPoint1: CGPointMake(45.48, 17.77) controlPoint2: CGPointMake(45.91, 18.37)]; + [bezier2Path addLineToPoint: CGPointMake(40.22, 19)]; + [bezier2Path addCurveToPoint: CGPointMake(39.23, 20.8) controlPoint1: CGPointMake(39.85, 19.58) controlPoint2: CGPointMake(39.52, 20.18)]; + [bezier2Path addLineToPoint: CGPointMake(47.3, 20.8)]; + [bezier2Path addCurveToPoint: CGPointMake(48.03, 22.6) controlPoint1: CGPointMake(47.58, 21.38) controlPoint2: CGPointMake(47.82, 21.98)]; + [bezier2Path addLineToPoint: CGPointMake(38.5, 22.6)]; + [bezier2Path addCurveToPoint: CGPointMake(38, 24.4) controlPoint1: CGPointMake(38.3, 23.19) controlPoint2: CGPointMake(38.13, 23.79)]; + [bezier2Path addLineToPoint: CGPointMake(48.53, 24.4)]; + [bezier2Path addCurveToPoint: CGPointMake(48.92, 28) controlPoint1: CGPointMake(48.78, 25.56) controlPoint2: CGPointMake(48.92, 26.76)]; + [bezier2Path addCurveToPoint: CGPointMake(48.03, 33.4) controlPoint1: CGPointMake(48.92, 29.89) controlPoint2: CGPointMake(48.61, 31.7)]; + [bezier2Path addLineToPoint: CGPointMake(38.5, 33.4)]; + [bezier2Path addCurveToPoint: CGPointMake(39.23, 35.2) controlPoint1: CGPointMake(38.71, 34.02) controlPoint2: CGPointMake(38.95, 34.62)]; + [bezier2Path addLineToPoint: CGPointMake(47.3, 35.2)]; + [bezier2Path addCurveToPoint: CGPointMake(46.31, 37) controlPoint1: CGPointMake(47.01, 35.82) controlPoint2: CGPointMake(46.68, 36.42)]; + [bezier2Path addLineToPoint: CGPointMake(40.22, 37)]; + [bezier2Path addCurveToPoint: CGPointMake(41.53, 38.8) controlPoint1: CGPointMake(40.62, 37.63) controlPoint2: CGPointMake(41.05, 38.23)]; + [bezier2Path addLineToPoint: CGPointMake(45, 38.8)]; + [bezier2Path addCurveToPoint: CGPointMake(43.27, 40.6) controlPoint1: CGPointMake(44.47, 39.44) controlPoint2: CGPointMake(43.89, 40.04)]; + [bezier2Path addCurveToPoint: CGPointMake(54.81, 45) controlPoint1: CGPointMake(46.32, 43.33) controlPoint2: CGPointMake(50.36, 45)]; + [bezier2Path addCurveToPoint: CGPointMake(72, 28) controlPoint1: CGPointMake(64.3, 45) controlPoint2: CGPointMake(72, 37.39)]; + [bezier2Path addCurveToPoint: CGPointMake(54.81, 11) controlPoint1: CGPointMake(72, 18.61) controlPoint2: CGPointMake(64.3, 11)]; + [bezier2Path addLineToPoint: CGPointMake(54.81, 11)]; + [bezier2Path addLineToPoint: CGPointMake(54.81, 11)]; + [bezier2Path addLineToPoint: CGPointMake(54.81, 11)]; + [bezier2Path addLineToPoint: CGPointMake(54.81, 11)]; + [bezier2Path closePath]; + bezier2Path.miterLimit = 4; + + bezier2Path.usesEvenOddFillRule = YES; + + [color2 setFill]; + [bezier2Path fill]; + + + //// Bezier 3 Drawing + UIBezierPath* bezier3Path = [UIBezierPath bezierPath]; + [bezier3Path moveToPoint: CGPointMake(30.6, 32.21)]; + [bezier3Path addLineToPoint: CGPointMake(28.45, 32.21)]; + [bezier3Path addLineToPoint: CGPointMake(29.73, 25.44)]; + [bezier3Path addLineToPoint: CGPointMake(26.79, 32.21)]; + [bezier3Path addLineToPoint: CGPointMake(24.83, 32.21)]; + [bezier3Path addLineToPoint: CGPointMake(24.47, 25.48)]; + [bezier3Path addLineToPoint: CGPointMake(23.19, 32.21)]; + [bezier3Path addLineToPoint: CGPointMake(21.24, 32.21)]; + [bezier3Path addLineToPoint: CGPointMake(22.91, 23.4)]; + [bezier3Path addLineToPoint: CGPointMake(26.26, 23.4)]; + [bezier3Path addLineToPoint: CGPointMake(26.44, 28.85)]; + [bezier3Path addLineToPoint: CGPointMake(28.8, 23.4)]; + [bezier3Path addLineToPoint: CGPointMake(32.29, 23.4)]; + [bezier3Path addLineToPoint: CGPointMake(30.6, 32.21)]; + [bezier3Path addLineToPoint: CGPointMake(30.6, 32.21)]; + [bezier3Path closePath]; + bezier3Path.miterLimit = 4; + + bezier3Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier3Path fill]; + + + //// Bezier 4 Drawing + UIBezierPath* bezier4Path = [UIBezierPath bezierPath]; + [bezier4Path moveToPoint: CGPointMake(54.6, 32.12)]; + [bezier4Path addCurveToPoint: CGPointMake(53.06, 32.36) controlPoint1: CGPointMake(54.01, 32.29) controlPoint2: CGPointMake(53.55, 32.36)]; + [bezier4Path addCurveToPoint: CGPointMake(51.36, 30.78) controlPoint1: CGPointMake(51.96, 32.36) controlPoint2: CGPointMake(51.36, 31.8)]; + [bezier4Path addCurveToPoint: CGPointMake(51.42, 30.14) controlPoint1: CGPointMake(51.36, 30.58) controlPoint2: CGPointMake(51.38, 30.37)]; + [bezier4Path addLineToPoint: CGPointMake(51.55, 29.44)]; + [bezier4Path addLineToPoint: CGPointMake(51.65, 28.87)]; + [bezier4Path addLineToPoint: CGPointMake(52.65, 23.4)]; + [bezier4Path addLineToPoint: CGPointMake(54.78, 23.4)]; + [bezier4Path addLineToPoint: CGPointMake(54.47, 25.04)]; + [bezier4Path addLineToPoint: CGPointMake(55.57, 25.04)]; + [bezier4Path addLineToPoint: CGPointMake(55.27, 26.79)]; + [bezier4Path addLineToPoint: CGPointMake(54.17, 26.79)]; + [bezier4Path addLineToPoint: CGPointMake(53.61, 29.78)]; + [bezier4Path addCurveToPoint: CGPointMake(53.57, 30.07) controlPoint1: CGPointMake(53.58, 29.91) controlPoint2: CGPointMake(53.57, 30.01)]; + [bezier4Path addCurveToPoint: CGPointMake(54.3, 30.61) controlPoint1: CGPointMake(53.57, 30.44) controlPoint2: CGPointMake(53.79, 30.61)]; + [bezier4Path addCurveToPoint: CGPointMake(54.88, 30.54) controlPoint1: CGPointMake(54.55, 30.61) controlPoint2: CGPointMake(54.74, 30.58)]; + [bezier4Path addLineToPoint: CGPointMake(54.6, 32.12)]; + [bezier4Path addLineToPoint: CGPointMake(54.6, 32.12)]; + [bezier4Path addLineToPoint: CGPointMake(54.6, 32.12)]; + [bezier4Path addLineToPoint: CGPointMake(54.6, 32.12)]; + [bezier4Path closePath]; + bezier4Path.miterLimit = 4; + + bezier4Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier4Path fill]; + + + //// Bezier 5 Drawing + UIBezierPath* bezier5Path = [UIBezierPath bezierPath]; + [bezier5Path moveToPoint: CGPointMake(60.87, 25.1)]; + [bezier5Path addCurveToPoint: CGPointMake(60.63, 25.03) controlPoint1: CGPointMake(60.69, 25.03) controlPoint2: CGPointMake(60.65, 25.03)]; + [bezier5Path addCurveToPoint: CGPointMake(60.44, 24.98) controlPoint1: CGPointMake(60.51, 25) controlPoint2: CGPointMake(60.45, 24.99)]; + [bezier5Path addCurveToPoint: CGPointMake(60.23, 24.97) controlPoint1: CGPointMake(60.38, 24.97) controlPoint2: CGPointMake(60.31, 24.97)]; + [bezier5Path addCurveToPoint: CGPointMake(58.36, 26.13) controlPoint1: CGPointMake(59.52, 24.97) controlPoint2: CGPointMake(59.01, 25.28)]; + [bezier5Path addLineToPoint: CGPointMake(58.55, 25.04)]; + [bezier5Path addLineToPoint: CGPointMake(56.6, 25.04)]; + [bezier5Path addLineToPoint: CGPointMake(55.29, 32.21)]; + [bezier5Path addLineToPoint: CGPointMake(57.44, 32.21)]; + [bezier5Path addCurveToPoint: CGPointMake(59.57, 27.06) controlPoint1: CGPointMake(58.21, 27.83) controlPoint2: CGPointMake(58.54, 27.06)]; + [bezier5Path addCurveToPoint: CGPointMake(59.84, 27.08) controlPoint1: CGPointMake(59.65, 27.06) controlPoint2: CGPointMake(59.74, 27.07)]; + [bezier5Path addLineToPoint: CGPointMake(60.09, 27.13)]; + [bezier5Path addLineToPoint: CGPointMake(60.87, 25.1)]; + [bezier5Path addLineToPoint: CGPointMake(60.87, 25.1)]; + [bezier5Path addLineToPoint: CGPointMake(60.87, 25.1)]; + [bezier5Path addLineToPoint: CGPointMake(60.87, 25.1)]; + [bezier5Path closePath]; + bezier5Path.miterLimit = 4; + + bezier5Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier5Path fill]; + + + //// Bezier 6 Drawing + UIBezierPath* bezier6Path = [UIBezierPath bezierPath]; + [bezier6Path moveToPoint: CGPointMake(46.09, 27.31)]; + [bezier6Path addCurveToPoint: CGPointMake(47.74, 29.31) controlPoint1: CGPointMake(46.09, 28.21) controlPoint2: CGPointMake(46.59, 28.84)]; + [bezier6Path addCurveToPoint: CGPointMake(48.76, 30.1) controlPoint1: CGPointMake(48.62, 29.67) controlPoint2: CGPointMake(48.76, 29.77)]; + [bezier6Path addCurveToPoint: CGPointMake(47.51, 30.75) controlPoint1: CGPointMake(48.76, 30.54) controlPoint2: CGPointMake(48.37, 30.75)]; + [bezier6Path addCurveToPoint: CGPointMake(45.56, 30.46) controlPoint1: CGPointMake(46.86, 30.75) controlPoint2: CGPointMake(46.26, 30.66)]; + [bezier6Path addLineToPoint: CGPointMake(45.26, 32.11)]; + [bezier6Path addLineToPoint: CGPointMake(45.36, 32.13)]; + [bezier6Path addLineToPoint: CGPointMake(45.76, 32.2)]; + [bezier6Path addCurveToPoint: CGPointMake(46.33, 32.27) controlPoint1: CGPointMake(45.89, 32.23) controlPoint2: CGPointMake(46.08, 32.25)]; + [bezier6Path addCurveToPoint: CGPointMake(47.52, 32.33) controlPoint1: CGPointMake(46.84, 32.31) controlPoint2: CGPointMake(47.24, 32.33)]; + [bezier6Path addCurveToPoint: CGPointMake(50.88, 29.93) controlPoint1: CGPointMake(49.82, 32.33) controlPoint2: CGPointMake(50.88, 31.57)]; + [bezier6Path addCurveToPoint: CGPointMake(49.34, 27.94) controlPoint1: CGPointMake(50.88, 28.95) controlPoint2: CGPointMake(50.43, 28.37)]; + [bezier6Path addCurveToPoint: CGPointMake(48.33, 27.16) controlPoint1: CGPointMake(48.43, 27.58) controlPoint2: CGPointMake(48.33, 27.5)]; + [bezier6Path addCurveToPoint: CGPointMake(49.39, 26.58) controlPoint1: CGPointMake(48.33, 26.78) controlPoint2: CGPointMake(48.69, 26.58)]; + [bezier6Path addCurveToPoint: CGPointMake(50.95, 26.68) controlPoint1: CGPointMake(49.82, 26.58) controlPoint2: CGPointMake(50.4, 26.62)]; + [bezier6Path addLineToPoint: CGPointMake(51.26, 25.03)]; + [bezier6Path addCurveToPoint: CGPointMake(49.35, 24.89) controlPoint1: CGPointMake(50.7, 24.95) controlPoint2: CGPointMake(49.85, 24.89)]; + [bezier6Path addCurveToPoint: CGPointMake(46.09, 27.31) controlPoint1: CGPointMake(46.92, 24.89) controlPoint2: CGPointMake(46.08, 25.99)]; + [bezier6Path addLineToPoint: CGPointMake(46.09, 27.31)]; + [bezier6Path addLineToPoint: CGPointMake(46.09, 27.31)]; + [bezier6Path addLineToPoint: CGPointMake(46.09, 27.31)]; + [bezier6Path addLineToPoint: CGPointMake(46.09, 27.31)]; + [bezier6Path closePath]; + bezier6Path.miterLimit = 4; + + bezier6Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier6Path fill]; + + + //// Bezier 7 Drawing + UIBezierPath* bezier7Path = [UIBezierPath bezierPath]; + [bezier7Path moveToPoint: CGPointMake(37.58, 32.21)]; + [bezier7Path addLineToPoint: CGPointMake(35.8, 32.21)]; + [bezier7Path addLineToPoint: CGPointMake(35.84, 31.47)]; + [bezier7Path addCurveToPoint: CGPointMake(33.58, 32.34) controlPoint1: CGPointMake(35.29, 32.06) controlPoint2: CGPointMake(34.57, 32.34)]; + [bezier7Path addCurveToPoint: CGPointMake(31.62, 30.38) controlPoint1: CGPointMake(32.42, 32.34) controlPoint2: CGPointMake(31.62, 31.54)]; + [bezier7Path addCurveToPoint: CGPointMake(35.39, 27.61) controlPoint1: CGPointMake(31.62, 28.63) controlPoint2: CGPointMake(33.01, 27.61)]; + [bezier7Path addCurveToPoint: CGPointMake(36.27, 27.67) controlPoint1: CGPointMake(35.64, 27.61) controlPoint2: CGPointMake(35.95, 27.63)]; + [bezier7Path addCurveToPoint: CGPointMake(36.35, 27.2) controlPoint1: CGPointMake(36.34, 27.43) controlPoint2: CGPointMake(36.35, 27.33)]; + [bezier7Path addCurveToPoint: CGPointMake(34.98, 26.55) controlPoint1: CGPointMake(36.35, 26.73) controlPoint2: CGPointMake(35.98, 26.55)]; + [bezier7Path addCurveToPoint: CGPointMake(33.19, 26.75) controlPoint1: CGPointMake(34.36, 26.55) controlPoint2: CGPointMake(33.67, 26.63)]; + [bezier7Path addLineToPoint: CGPointMake(32.89, 26.83)]; + [bezier7Path addLineToPoint: CGPointMake(32.7, 26.87)]; + [bezier7Path addLineToPoint: CGPointMake(33, 25.26)]; + [bezier7Path addCurveToPoint: CGPointMake(35.57, 24.88) controlPoint1: CGPointMake(34.07, 24.99) controlPoint2: CGPointMake(34.78, 24.88)]; + [bezier7Path addCurveToPoint: CGPointMake(38.39, 26.98) controlPoint1: CGPointMake(37.42, 24.88) controlPoint2: CGPointMake(38.39, 25.61)]; + [bezier7Path addCurveToPoint: CGPointMake(38.22, 28.4) controlPoint1: CGPointMake(38.39, 27.34) controlPoint2: CGPointMake(38.36, 27.61)]; + [bezier7Path addLineToPoint: CGPointMake(37.77, 30.95)]; + [bezier7Path addLineToPoint: CGPointMake(37.69, 31.4)]; + [bezier7Path addLineToPoint: CGPointMake(37.64, 31.77)]; + [bezier7Path addLineToPoint: CGPointMake(37.6, 32.02)]; + [bezier7Path addLineToPoint: CGPointMake(37.58, 32.21)]; + [bezier7Path addLineToPoint: CGPointMake(37.58, 32.21)]; + [bezier7Path addLineToPoint: CGPointMake(37.58, 32.21)]; + [bezier7Path addLineToPoint: CGPointMake(37.58, 32.21)]; + [bezier7Path closePath]; + [bezier7Path moveToPoint: CGPointMake(36.01, 29.02)]; + [bezier7Path addCurveToPoint: CGPointMake(35.53, 28.99) controlPoint1: CGPointMake(35.79, 28.99) controlPoint2: CGPointMake(35.69, 28.99)]; + [bezier7Path addCurveToPoint: CGPointMake(33.7, 30.08) controlPoint1: CGPointMake(34.32, 28.99) controlPoint2: CGPointMake(33.7, 29.36)]; + [bezier7Path addCurveToPoint: CGPointMake(34.47, 30.81) controlPoint1: CGPointMake(33.7, 30.53) controlPoint2: CGPointMake(34, 30.81)]; + [bezier7Path addCurveToPoint: CGPointMake(36.01, 29.02) controlPoint1: CGPointMake(35.35, 30.81) controlPoint2: CGPointMake(35.98, 30.08)]; + [bezier7Path addLineToPoint: CGPointMake(36.01, 29.02)]; + [bezier7Path addLineToPoint: CGPointMake(36.01, 29.02)]; + [bezier7Path addLineToPoint: CGPointMake(36.01, 29.02)]; + [bezier7Path addLineToPoint: CGPointMake(36.01, 29.02)]; + [bezier7Path closePath]; + bezier7Path.miterLimit = 4; + + bezier7Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier7Path fill]; + + + //// Bezier 8 Drawing + UIBezierPath* bezier8Path = [UIBezierPath bezierPath]; + [bezier8Path moveToPoint: CGPointMake(44.63, 32.06)]; + [bezier8Path addCurveToPoint: CGPointMake(42.43, 32.35) controlPoint1: CGPointMake(43.89, 32.25) controlPoint2: CGPointMake(43.18, 32.35)]; + [bezier8Path addCurveToPoint: CGPointMake(38.77, 29.14) controlPoint1: CGPointMake(40.02, 32.35) controlPoint2: CGPointMake(38.77, 31.24)]; + [bezier8Path addCurveToPoint: CGPointMake(42.53, 24.86) controlPoint1: CGPointMake(38.77, 26.68) controlPoint2: CGPointMake(40.36, 24.86)]; + [bezier8Path addCurveToPoint: CGPointMake(45.42, 27.47) controlPoint1: CGPointMake(44.29, 24.86) controlPoint2: CGPointMake(45.42, 25.88)]; + [bezier8Path addCurveToPoint: CGPointMake(45.16, 29.24) controlPoint1: CGPointMake(45.42, 28) controlPoint2: CGPointMake(45.35, 28.51)]; + [bezier8Path addLineToPoint: CGPointMake(40.89, 29.24)]; + [bezier8Path addCurveToPoint: CGPointMake(40.87, 29.47) controlPoint1: CGPointMake(40.87, 29.35) controlPoint2: CGPointMake(40.87, 29.4)]; + [bezier8Path addCurveToPoint: CGPointMake(42.75, 30.72) controlPoint1: CGPointMake(40.87, 30.3) controlPoint2: CGPointMake(41.5, 30.72)]; + [bezier8Path addCurveToPoint: CGPointMake(44.98, 30.27) controlPoint1: CGPointMake(43.52, 30.72) controlPoint2: CGPointMake(44.21, 30.58)]; + [bezier8Path addLineToPoint: CGPointMake(44.63, 32.06)]; + [bezier8Path addLineToPoint: CGPointMake(44.63, 32.06)]; + [bezier8Path addLineToPoint: CGPointMake(44.63, 32.06)]; + [bezier8Path addLineToPoint: CGPointMake(44.63, 32.06)]; + [bezier8Path closePath]; + [bezier8Path moveToPoint: CGPointMake(43.48, 27.79)]; + [bezier8Path addCurveToPoint: CGPointMake(43.5, 27.43) controlPoint1: CGPointMake(43.49, 27.64) controlPoint2: CGPointMake(43.5, 27.52)]; + [bezier8Path addCurveToPoint: CGPointMake(42.48, 26.5) controlPoint1: CGPointMake(43.5, 26.84) controlPoint2: CGPointMake(43.12, 26.5)]; + [bezier8Path addCurveToPoint: CGPointMake(41.11, 27.79) controlPoint1: CGPointMake(41.8, 26.5) controlPoint2: CGPointMake(41.31, 26.96)]; + [bezier8Path addLineToPoint: CGPointMake(43.48, 27.79)]; + [bezier8Path addLineToPoint: CGPointMake(43.48, 27.79)]; + [bezier8Path addLineToPoint: CGPointMake(43.48, 27.79)]; + [bezier8Path addLineToPoint: CGPointMake(43.48, 27.79)]; + [bezier8Path closePath]; + bezier8Path.miterLimit = 4; + + bezier8Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier8Path fill]; + + + //// Bezier 9 Drawing + UIBezierPath* bezier9Path = [UIBezierPath bezierPath]; + [bezier9Path moveToPoint: CGPointMake(67.55, 28.96)]; + [bezier9Path addCurveToPoint: CGPointMake(63.38, 32.4) controlPoint1: CGPointMake(67.23, 31.35) controlPoint2: CGPointMake(65.57, 32.4)]; + [bezier9Path addCurveToPoint: CGPointMake(59.96, 29.1) controlPoint1: CGPointMake(60.95, 32.4) controlPoint2: CGPointMake(59.96, 30.92)]; + [bezier9Path addCurveToPoint: CGPointMake(64.19, 24.84) controlPoint1: CGPointMake(59.96, 26.56) controlPoint2: CGPointMake(61.63, 24.84)]; + [bezier9Path addCurveToPoint: CGPointMake(67.6, 28.07) controlPoint1: CGPointMake(66.42, 24.84) controlPoint2: CGPointMake(67.6, 26.25)]; + [bezier9Path addCurveToPoint: CGPointMake(67.55, 28.96) controlPoint1: CGPointMake(67.6, 28.52) controlPoint2: CGPointMake(67.6, 28.55)]; + [bezier9Path addLineToPoint: CGPointMake(67.55, 28.96)]; + [bezier9Path addLineToPoint: CGPointMake(67.55, 28.96)]; + [bezier9Path addLineToPoint: CGPointMake(67.55, 28.96)]; + [bezier9Path addLineToPoint: CGPointMake(67.55, 28.96)]; + [bezier9Path closePath]; + [bezier9Path moveToPoint: CGPointMake(65.33, 28.05)]; + [bezier9Path addCurveToPoint: CGPointMake(64.15, 26.59) controlPoint1: CGPointMake(65.33, 27.3) controlPoint2: CGPointMake(65.03, 26.59)]; + [bezier9Path addCurveToPoint: CGPointMake(62.38, 29.04) controlPoint1: CGPointMake(63.06, 26.59) controlPoint2: CGPointMake(62.38, 27.89)]; + [bezier9Path addCurveToPoint: CGPointMake(63.61, 30.66) controlPoint1: CGPointMake(62.38, 30.02) controlPoint2: CGPointMake(62.84, 30.67)]; + [bezier9Path addCurveToPoint: CGPointMake(65.26, 28.9) controlPoint1: CGPointMake(64.08, 30.66) controlPoint2: CGPointMake(65.07, 30.02)]; + [bezier9Path addCurveToPoint: CGPointMake(65.33, 28.05) controlPoint1: CGPointMake(65.31, 28.64) controlPoint2: CGPointMake(65.33, 28.35)]; + [bezier9Path addLineToPoint: CGPointMake(65.33, 28.05)]; + [bezier9Path addLineToPoint: CGPointMake(65.33, 28.05)]; + [bezier9Path addLineToPoint: CGPointMake(65.33, 28.05)]; + [bezier9Path addLineToPoint: CGPointMake(65.33, 28.05)]; + [bezier9Path closePath]; + bezier9Path.miterLimit = 4; + + bezier9Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier9Path fill]; + } + } + } +} +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIMasterCardVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIMasterCardVectorArtView.h new file mode 100644 index 0000000..6ad97ef --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIMasterCardVectorArtView.h @@ -0,0 +1,5 @@ +#import "BTUICardVectorArtView.h" + +@interface BTUIMasterCardVectorArtView : BTUICardVectorArtView + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIMasterCardVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIMasterCardVectorArtView.m new file mode 100644 index 0000000..7a4a371 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIMasterCardVectorArtView.m @@ -0,0 +1,3247 @@ +#import "BTUIMasterCardVectorArtView.h" + +@implementation BTUIMasterCardVectorArtView + +- (void)drawArt { + //// Color Declarations + UIColor* color1 = [UIColor colorWithRed: 0.93 green: 0.619 blue: 0.186 alpha: 1]; + UIColor* color2 = [UIColor colorWithRed: 0.8 green: 0.039 blue: 0.147 alpha: 1]; + UIColor* color3 = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + + //// Page-1 + { + //// MasterCard + { + //// Group 4 + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(54.97, 45)]; + [bezierPath addLineToPoint: CGPointMake(55.85, 44.98)]; + [bezierPath addLineToPoint: CGPointMake(56.71, 44.91)]; + [bezierPath addLineToPoint: CGPointMake(57.56, 44.81)]; + [bezierPath addLineToPoint: CGPointMake(58.4, 44.66)]; + [bezierPath addLineToPoint: CGPointMake(59.22, 44.47)]; + [bezierPath addLineToPoint: CGPointMake(60.03, 44.24)]; + [bezierPath addLineToPoint: CGPointMake(60.82, 43.97)]; + [bezierPath addLineToPoint: CGPointMake(61.6, 43.66)]; + [bezierPath addLineToPoint: CGPointMake(62.35, 43.32)]; + [bezierPath addLineToPoint: CGPointMake(63.09, 42.95)]; + [bezierPath addLineToPoint: CGPointMake(63.8, 42.53)]; + [bezierPath addLineToPoint: CGPointMake(64.49, 42.09)]; + [bezierPath addLineToPoint: CGPointMake(65.16, 41.62)]; + [bezierPath addLineToPoint: CGPointMake(65.8, 41.11)]; + [bezierPath addLineToPoint: CGPointMake(66.42, 40.58)]; + [bezierPath addLineToPoint: CGPointMake(67.01, 40.01)]; + [bezierPath addLineToPoint: CGPointMake(67.58, 39.42)]; + [bezierPath addLineToPoint: CGPointMake(68.11, 38.8)]; + [bezierPath addLineToPoint: CGPointMake(68.62, 38.16)]; + [bezierPath addLineToPoint: CGPointMake(69.09, 37.49)]; + [bezierPath addLineToPoint: CGPointMake(69.53, 36.8)]; + [bezierPath addLineToPoint: CGPointMake(69.95, 36.09)]; + [bezierPath addLineToPoint: CGPointMake(70.32, 35.35)]; + [bezierPath addLineToPoint: CGPointMake(70.66, 34.6)]; + [bezierPath addLineToPoint: CGPointMake(70.97, 33.82)]; + [bezierPath addLineToPoint: CGPointMake(71.24, 33.03)]; + [bezierPath addLineToPoint: CGPointMake(71.47, 32.22)]; + [bezierPath addLineToPoint: CGPointMake(71.66, 31.4)]; + [bezierPath addLineToPoint: CGPointMake(71.81, 30.56)]; + [bezierPath addLineToPoint: CGPointMake(71.91, 29.71)]; + [bezierPath addLineToPoint: CGPointMake(71.98, 28.85)]; + [bezierPath addLineToPoint: CGPointMake(72, 27.97)]; + [bezierPath addLineToPoint: CGPointMake(71.98, 27.1)]; + [bezierPath addLineToPoint: CGPointMake(71.91, 26.24)]; + [bezierPath addLineToPoint: CGPointMake(71.81, 25.39)]; + [bezierPath addLineToPoint: CGPointMake(71.66, 24.56)]; + [bezierPath addLineToPoint: CGPointMake(71.47, 23.74)]; + [bezierPath addLineToPoint: CGPointMake(71.24, 22.93)]; + [bezierPath addLineToPoint: CGPointMake(70.97, 22.14)]; + [bezierPath addLineToPoint: CGPointMake(70.66, 21.37)]; + [bezierPath addLineToPoint: CGPointMake(70.32, 20.62)]; + [bezierPath addLineToPoint: CGPointMake(69.95, 19.89)]; + [bezierPath addLineToPoint: CGPointMake(69.53, 19.18)]; + [bezierPath addLineToPoint: CGPointMake(69.09, 18.49)]; + [bezierPath addLineToPoint: CGPointMake(68.62, 17.82)]; + [bezierPath addLineToPoint: CGPointMake(68.11, 17.19)]; + [bezierPath addLineToPoint: CGPointMake(67.58, 16.57)]; + [bezierPath addLineToPoint: CGPointMake(67.01, 15.98)]; + [bezierPath addLineToPoint: CGPointMake(66.42, 15.42)]; + [bezierPath addLineToPoint: CGPointMake(65.8, 14.88)]; + [bezierPath addLineToPoint: CGPointMake(65.16, 14.38)]; + [bezierPath addLineToPoint: CGPointMake(64.49, 13.9)]; + [bezierPath addLineToPoint: CGPointMake(63.8, 13.46)]; + [bezierPath addLineToPoint: CGPointMake(63.09, 13.05)]; + [bezierPath addLineToPoint: CGPointMake(62.35, 12.68)]; + [bezierPath addLineToPoint: CGPointMake(61.6, 12.34)]; + [bezierPath addLineToPoint: CGPointMake(60.82, 12.03)]; + [bezierPath addLineToPoint: CGPointMake(60.03, 11.76)]; + [bezierPath addLineToPoint: CGPointMake(59.22, 11.53)]; + [bezierPath addLineToPoint: CGPointMake(58.4, 11.34)]; + [bezierPath addLineToPoint: CGPointMake(57.56, 11.19)]; + [bezierPath addLineToPoint: CGPointMake(56.71, 11.09)]; + [bezierPath addLineToPoint: CGPointMake(55.85, 11.02)]; + [bezierPath addLineToPoint: CGPointMake(54.97, 11)]; + [bezierPath addLineToPoint: CGPointMake(54.1, 11.02)]; + [bezierPath addLineToPoint: CGPointMake(53.23, 11.09)]; + [bezierPath addLineToPoint: CGPointMake(52.38, 11.19)]; + [bezierPath addLineToPoint: CGPointMake(51.54, 11.34)]; + [bezierPath addLineToPoint: CGPointMake(50.72, 11.53)]; + [bezierPath addLineToPoint: CGPointMake(49.92, 11.76)]; + [bezierPath addLineToPoint: CGPointMake(49.13, 12.03)]; + [bezierPath addLineToPoint: CGPointMake(48.36, 12.34)]; + [bezierPath addLineToPoint: CGPointMake(47.61, 12.68)]; + [bezierPath addLineToPoint: CGPointMake(46.88, 13.05)]; + [bezierPath addLineToPoint: CGPointMake(46.17, 13.46)]; + [bezierPath addLineToPoint: CGPointMake(45.48, 13.9)]; + [bezierPath addLineToPoint: CGPointMake(44.81, 14.38)]; + [bezierPath addLineToPoint: CGPointMake(44.17, 14.88)]; + [bezierPath addLineToPoint: CGPointMake(43.56, 15.42)]; + [bezierPath addLineToPoint: CGPointMake(42.97, 15.98)]; + [bezierPath addLineToPoint: CGPointMake(42.4, 16.57)]; + [bezierPath addLineToPoint: CGPointMake(41.87, 17.19)]; + [bezierPath addLineToPoint: CGPointMake(41.37, 17.82)]; + [bezierPath addLineToPoint: CGPointMake(40.9, 18.49)]; + [bezierPath addLineToPoint: CGPointMake(40.45, 19.18)]; + [bezierPath addLineToPoint: CGPointMake(40.05, 19.89)]; + [bezierPath addLineToPoint: CGPointMake(39.67, 20.62)]; + [bezierPath addLineToPoint: CGPointMake(39.33, 21.37)]; + [bezierPath addLineToPoint: CGPointMake(39.03, 22.14)]; + [bezierPath addLineToPoint: CGPointMake(38.76, 22.93)]; + [bezierPath addLineToPoint: CGPointMake(38.53, 23.74)]; + [bezierPath addLineToPoint: CGPointMake(38.34, 24.56)]; + [bezierPath addLineToPoint: CGPointMake(38.19, 25.39)]; + [bezierPath addLineToPoint: CGPointMake(38.09, 26.24)]; + [bezierPath addLineToPoint: CGPointMake(38.02, 27.1)]; + [bezierPath addLineToPoint: CGPointMake(38, 27.97)]; + [bezierPath addLineToPoint: CGPointMake(38.02, 28.85)]; + [bezierPath addLineToPoint: CGPointMake(38.09, 29.71)]; + [bezierPath addLineToPoint: CGPointMake(38.19, 30.56)]; + [bezierPath addLineToPoint: CGPointMake(38.34, 31.4)]; + [bezierPath addLineToPoint: CGPointMake(38.53, 32.22)]; + [bezierPath addLineToPoint: CGPointMake(38.76, 33.03)]; + [bezierPath addLineToPoint: CGPointMake(39.03, 33.82)]; + [bezierPath addLineToPoint: CGPointMake(39.33, 34.6)]; + [bezierPath addLineToPoint: CGPointMake(39.67, 35.35)]; + [bezierPath addLineToPoint: CGPointMake(40.05, 36.09)]; + [bezierPath addLineToPoint: CGPointMake(40.45, 36.8)]; + [bezierPath addLineToPoint: CGPointMake(40.9, 37.49)]; + [bezierPath addLineToPoint: CGPointMake(41.37, 38.16)]; + [bezierPath addLineToPoint: CGPointMake(41.87, 38.8)]; + [bezierPath addLineToPoint: CGPointMake(42.4, 39.42)]; + [bezierPath addLineToPoint: CGPointMake(42.97, 40.01)]; + [bezierPath addLineToPoint: CGPointMake(43.56, 40.58)]; + [bezierPath addLineToPoint: CGPointMake(44.17, 41.11)]; + [bezierPath addLineToPoint: CGPointMake(44.81, 41.62)]; + [bezierPath addLineToPoint: CGPointMake(45.48, 42.09)]; + [bezierPath addLineToPoint: CGPointMake(46.17, 42.53)]; + [bezierPath addLineToPoint: CGPointMake(46.88, 42.95)]; + [bezierPath addLineToPoint: CGPointMake(47.61, 43.32)]; + [bezierPath addLineToPoint: CGPointMake(48.36, 43.66)]; + [bezierPath addLineToPoint: CGPointMake(49.13, 43.97)]; + [bezierPath addLineToPoint: CGPointMake(49.92, 44.24)]; + [bezierPath addLineToPoint: CGPointMake(50.72, 44.47)]; + [bezierPath addLineToPoint: CGPointMake(51.54, 44.66)]; + [bezierPath addLineToPoint: CGPointMake(52.38, 44.81)]; + [bezierPath addLineToPoint: CGPointMake(53.23, 44.91)]; + [bezierPath addLineToPoint: CGPointMake(54.1, 44.98)]; + [bezierPath addLineToPoint: CGPointMake(54.97, 45)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + bezierPath.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezierPath fill]; + + + //// Bezier 2 Drawing + UIBezierPath* bezier2Path = [UIBezierPath bezierPath]; + [bezier2Path moveToPoint: CGPointMake(33.03, 45)]; + [bezier2Path addLineToPoint: CGPointMake(33.9, 44.98)]; + [bezier2Path addLineToPoint: CGPointMake(34.77, 44.91)]; + [bezier2Path addLineToPoint: CGPointMake(35.62, 44.81)]; + [bezier2Path addLineToPoint: CGPointMake(36.46, 44.66)]; + [bezier2Path addLineToPoint: CGPointMake(37.28, 44.47)]; + [bezier2Path addLineToPoint: CGPointMake(38.08, 44.24)]; + [bezier2Path addLineToPoint: CGPointMake(38.87, 43.97)]; + [bezier2Path addLineToPoint: CGPointMake(39.64, 43.66)]; + [bezier2Path addLineToPoint: CGPointMake(40.39, 43.32)]; + [bezier2Path addLineToPoint: CGPointMake(41.12, 42.95)]; + [bezier2Path addLineToPoint: CGPointMake(41.83, 42.53)]; + [bezier2Path addLineToPoint: CGPointMake(42.52, 42.09)]; + [bezier2Path addLineToPoint: CGPointMake(43.19, 41.62)]; + [bezier2Path addLineToPoint: CGPointMake(43.83, 41.11)]; + [bezier2Path addLineToPoint: CGPointMake(44.44, 40.58)]; + [bezier2Path addLineToPoint: CGPointMake(45.03, 40.01)]; + [bezier2Path addLineToPoint: CGPointMake(45.6, 39.42)]; + [bezier2Path addLineToPoint: CGPointMake(46.13, 38.8)]; + [bezier2Path addLineToPoint: CGPointMake(46.63, 38.16)]; + [bezier2Path addLineToPoint: CGPointMake(47.1, 37.49)]; + [bezier2Path addLineToPoint: CGPointMake(47.55, 36.8)]; + [bezier2Path addLineToPoint: CGPointMake(47.95, 36.09)]; + [bezier2Path addLineToPoint: CGPointMake(48.33, 35.35)]; + [bezier2Path addLineToPoint: CGPointMake(48.67, 34.6)]; + [bezier2Path addLineToPoint: CGPointMake(48.97, 33.82)]; + [bezier2Path addLineToPoint: CGPointMake(49.24, 33.03)]; + [bezier2Path addLineToPoint: CGPointMake(49.47, 32.22)]; + [bezier2Path addLineToPoint: CGPointMake(49.66, 31.4)]; + [bezier2Path addLineToPoint: CGPointMake(49.81, 30.56)]; + [bezier2Path addLineToPoint: CGPointMake(49.91, 29.71)]; + [bezier2Path addLineToPoint: CGPointMake(49.98, 28.85)]; + [bezier2Path addLineToPoint: CGPointMake(50, 27.97)]; + [bezier2Path addLineToPoint: CGPointMake(49.98, 27.1)]; + [bezier2Path addLineToPoint: CGPointMake(49.91, 26.24)]; + [bezier2Path addLineToPoint: CGPointMake(49.81, 25.39)]; + [bezier2Path addLineToPoint: CGPointMake(49.66, 24.56)]; + [bezier2Path addLineToPoint: CGPointMake(49.47, 23.74)]; + [bezier2Path addLineToPoint: CGPointMake(49.24, 22.93)]; + [bezier2Path addLineToPoint: CGPointMake(48.97, 22.14)]; + [bezier2Path addLineToPoint: CGPointMake(48.67, 21.37)]; + [bezier2Path addLineToPoint: CGPointMake(48.33, 20.62)]; + [bezier2Path addLineToPoint: CGPointMake(47.95, 19.89)]; + [bezier2Path addLineToPoint: CGPointMake(47.55, 19.18)]; + [bezier2Path addLineToPoint: CGPointMake(47.1, 18.49)]; + [bezier2Path addLineToPoint: CGPointMake(46.63, 17.82)]; + [bezier2Path addLineToPoint: CGPointMake(46.13, 17.19)]; + [bezier2Path addLineToPoint: CGPointMake(45.6, 16.57)]; + [bezier2Path addLineToPoint: CGPointMake(45.03, 15.98)]; + [bezier2Path addLineToPoint: CGPointMake(44.44, 15.42)]; + [bezier2Path addLineToPoint: CGPointMake(43.83, 14.88)]; + [bezier2Path addLineToPoint: CGPointMake(43.19, 14.38)]; + [bezier2Path addLineToPoint: CGPointMake(42.52, 13.9)]; + [bezier2Path addLineToPoint: CGPointMake(41.83, 13.46)]; + [bezier2Path addLineToPoint: CGPointMake(41.12, 13.05)]; + [bezier2Path addLineToPoint: CGPointMake(40.39, 12.68)]; + [bezier2Path addLineToPoint: CGPointMake(39.64, 12.34)]; + [bezier2Path addLineToPoint: CGPointMake(38.87, 12.03)]; + [bezier2Path addLineToPoint: CGPointMake(38.08, 11.76)]; + [bezier2Path addLineToPoint: CGPointMake(37.28, 11.53)]; + [bezier2Path addLineToPoint: CGPointMake(36.46, 11.34)]; + [bezier2Path addLineToPoint: CGPointMake(35.62, 11.19)]; + [bezier2Path addLineToPoint: CGPointMake(34.77, 11.09)]; + [bezier2Path addLineToPoint: CGPointMake(33.9, 11.02)]; + [bezier2Path addLineToPoint: CGPointMake(33.03, 11)]; + [bezier2Path addLineToPoint: CGPointMake(32.15, 11.02)]; + [bezier2Path addLineToPoint: CGPointMake(31.29, 11.09)]; + [bezier2Path addLineToPoint: CGPointMake(30.44, 11.19)]; + [bezier2Path addLineToPoint: CGPointMake(29.6, 11.34)]; + [bezier2Path addLineToPoint: CGPointMake(28.78, 11.53)]; + [bezier2Path addLineToPoint: CGPointMake(27.97, 11.76)]; + [bezier2Path addLineToPoint: CGPointMake(27.18, 12.03)]; + [bezier2Path addLineToPoint: CGPointMake(26.4, 12.34)]; + [bezier2Path addLineToPoint: CGPointMake(25.65, 12.68)]; + [bezier2Path addLineToPoint: CGPointMake(24.91, 13.05)]; + [bezier2Path addLineToPoint: CGPointMake(24.2, 13.46)]; + [bezier2Path addLineToPoint: CGPointMake(23.51, 13.9)]; + [bezier2Path addLineToPoint: CGPointMake(22.84, 14.38)]; + [bezier2Path addLineToPoint: CGPointMake(22.2, 14.88)]; + [bezier2Path addLineToPoint: CGPointMake(21.58, 15.42)]; + [bezier2Path addLineToPoint: CGPointMake(20.99, 15.98)]; + [bezier2Path addLineToPoint: CGPointMake(20.42, 16.57)]; + [bezier2Path addLineToPoint: CGPointMake(19.89, 17.19)]; + [bezier2Path addLineToPoint: CGPointMake(19.38, 17.82)]; + [bezier2Path addLineToPoint: CGPointMake(18.91, 18.49)]; + [bezier2Path addLineToPoint: CGPointMake(18.47, 19.18)]; + [bezier2Path addLineToPoint: CGPointMake(18.05, 19.89)]; + [bezier2Path addLineToPoint: CGPointMake(17.68, 20.62)]; + [bezier2Path addLineToPoint: CGPointMake(17.34, 21.37)]; + [bezier2Path addLineToPoint: CGPointMake(17.03, 22.14)]; + [bezier2Path addLineToPoint: CGPointMake(16.76, 22.93)]; + [bezier2Path addLineToPoint: CGPointMake(16.53, 23.74)]; + [bezier2Path addLineToPoint: CGPointMake(16.34, 24.56)]; + [bezier2Path addLineToPoint: CGPointMake(16.2, 25.39)]; + [bezier2Path addLineToPoint: CGPointMake(16.09, 26.24)]; + [bezier2Path addLineToPoint: CGPointMake(16.02, 27.1)]; + [bezier2Path addLineToPoint: CGPointMake(16, 27.97)]; + [bezier2Path addLineToPoint: CGPointMake(16.02, 28.85)]; + [bezier2Path addLineToPoint: CGPointMake(16.09, 29.71)]; + [bezier2Path addLineToPoint: CGPointMake(16.2, 30.56)]; + [bezier2Path addLineToPoint: CGPointMake(16.34, 31.4)]; + [bezier2Path addLineToPoint: CGPointMake(16.53, 32.22)]; + [bezier2Path addLineToPoint: CGPointMake(16.76, 33.03)]; + [bezier2Path addLineToPoint: CGPointMake(17.03, 33.82)]; + [bezier2Path addLineToPoint: CGPointMake(17.34, 34.6)]; + [bezier2Path addLineToPoint: CGPointMake(17.68, 35.35)]; + [bezier2Path addLineToPoint: CGPointMake(18.05, 36.09)]; + [bezier2Path addLineToPoint: CGPointMake(18.47, 36.8)]; + [bezier2Path addLineToPoint: CGPointMake(18.91, 37.49)]; + [bezier2Path addLineToPoint: CGPointMake(19.38, 38.16)]; + [bezier2Path addLineToPoint: CGPointMake(19.89, 38.8)]; + [bezier2Path addLineToPoint: CGPointMake(20.42, 39.42)]; + [bezier2Path addLineToPoint: CGPointMake(20.99, 40.01)]; + [bezier2Path addLineToPoint: CGPointMake(21.58, 40.58)]; + [bezier2Path addLineToPoint: CGPointMake(22.2, 41.11)]; + [bezier2Path addLineToPoint: CGPointMake(22.84, 41.62)]; + [bezier2Path addLineToPoint: CGPointMake(23.51, 42.09)]; + [bezier2Path addLineToPoint: CGPointMake(24.2, 42.53)]; + [bezier2Path addLineToPoint: CGPointMake(24.91, 42.95)]; + [bezier2Path addLineToPoint: CGPointMake(25.65, 43.32)]; + [bezier2Path addLineToPoint: CGPointMake(26.4, 43.66)]; + [bezier2Path addLineToPoint: CGPointMake(27.18, 43.97)]; + [bezier2Path addLineToPoint: CGPointMake(27.97, 44.24)]; + [bezier2Path addLineToPoint: CGPointMake(28.78, 44.47)]; + [bezier2Path addLineToPoint: CGPointMake(29.6, 44.66)]; + [bezier2Path addLineToPoint: CGPointMake(30.44, 44.81)]; + [bezier2Path addLineToPoint: CGPointMake(31.29, 44.91)]; + [bezier2Path addLineToPoint: CGPointMake(32.15, 44.98)]; + [bezier2Path addLineToPoint: CGPointMake(33.03, 45)]; + [bezier2Path closePath]; + bezier2Path.miterLimit = 4; + + bezier2Path.usesEvenOddFillRule = YES; + + [color2 setFill]; + [bezier2Path fill]; + + + //// Bezier 3 Drawing + UIBezierPath* bezier3Path = [UIBezierPath bezierPath]; + [bezier3Path moveToPoint: CGPointMake(41.68, 17.72)]; + [bezier3Path addLineToPoint: CGPointMake(50.65, 17.72)]; + [bezier3Path addLineToPoint: CGPointMake(50.65, 16.81)]; + [bezier3Path addLineToPoint: CGPointMake(42.46, 16.81)]; + [bezier3Path addLineToPoint: CGPointMake(41.68, 17.72)]; + [bezier3Path closePath]; + bezier3Path.miterLimit = 4; + + bezier3Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier3Path fill]; + + + //// Bezier 4 Drawing + UIBezierPath* bezier4Path = [UIBezierPath bezierPath]; + [bezier4Path moveToPoint: CGPointMake(40.34, 19.76)]; + [bezier4Path addLineToPoint: CGPointMake(50.65, 19.76)]; + [bezier4Path addLineToPoint: CGPointMake(50.65, 18.85)]; + [bezier4Path addLineToPoint: CGPointMake(40.88, 18.85)]; + [bezier4Path addLineToPoint: CGPointMake(40.34, 19.76)]; + [bezier4Path closePath]; + bezier4Path.miterLimit = 4; + + bezier4Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier4Path fill]; + + + //// Bezier 5 Drawing + UIBezierPath* bezier5Path = [UIBezierPath bezierPath]; + [bezier5Path moveToPoint: CGPointMake(39.34, 21.8)]; + [bezier5Path addLineToPoint: CGPointMake(50.65, 21.8)]; + [bezier5Path addLineToPoint: CGPointMake(50.65, 20.88)]; + [bezier5Path addLineToPoint: CGPointMake(39.73, 20.88)]; + [bezier5Path addLineToPoint: CGPointMake(39.34, 21.8)]; + [bezier5Path closePath]; + bezier5Path.miterLimit = 4; + + bezier5Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier5Path fill]; + + + //// Bezier 6 Drawing + UIBezierPath* bezier6Path = [UIBezierPath bezierPath]; + [bezier6Path moveToPoint: CGPointMake(38.65, 23.83)]; + [bezier6Path addLineToPoint: CGPointMake(50.65, 23.83)]; + [bezier6Path addLineToPoint: CGPointMake(50.65, 22.92)]; + [bezier6Path addLineToPoint: CGPointMake(38.93, 22.92)]; + [bezier6Path addLineToPoint: CGPointMake(38.65, 23.83)]; + [bezier6Path closePath]; + bezier6Path.miterLimit = 4; + + bezier6Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier6Path fill]; + + + //// Bezier 7 Drawing + UIBezierPath* bezier7Path = [UIBezierPath bezierPath]; + [bezier7Path moveToPoint: CGPointMake(39.05, 33.68)]; + [bezier7Path addLineToPoint: CGPointMake(50.68, 33.68)]; + [bezier7Path addLineToPoint: CGPointMake(50.68, 32.77)]; + [bezier7Path addLineToPoint: CGPointMake(38.76, 32.77)]; + [bezier7Path addLineToPoint: CGPointMake(39.05, 33.68)]; + [bezier7Path closePath]; + bezier7Path.miterLimit = 4; + + bezier7Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier7Path fill]; + + + //// Bezier 8 Drawing + UIBezierPath* bezier8Path = [UIBezierPath bezierPath]; + [bezier8Path moveToPoint: CGPointMake(39.9, 35.72)]; + [bezier8Path addLineToPoint: CGPointMake(50.68, 35.72)]; + [bezier8Path addLineToPoint: CGPointMake(50.68, 34.8)]; + [bezier8Path addLineToPoint: CGPointMake(39.48, 34.8)]; + [bezier8Path addLineToPoint: CGPointMake(39.9, 35.72)]; + [bezier8Path closePath]; + bezier8Path.miterLimit = 4; + + bezier8Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier8Path fill]; + + + //// Bezier 9 Drawing + UIBezierPath* bezier9Path = [UIBezierPath bezierPath]; + [bezier9Path moveToPoint: CGPointMake(41.11, 37.75)]; + [bezier9Path addLineToPoint: CGPointMake(50.68, 37.75)]; + [bezier9Path addLineToPoint: CGPointMake(50.68, 36.84)]; + [bezier9Path addLineToPoint: CGPointMake(40.54, 36.84)]; + [bezier9Path addLineToPoint: CGPointMake(41.11, 37.75)]; + [bezier9Path closePath]; + bezier9Path.miterLimit = 4; + + bezier9Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier9Path fill]; + + + //// Bezier 10 Drawing + UIBezierPath* bezier10Path = [UIBezierPath bezierPath]; + [bezier10Path moveToPoint: CGPointMake(42.77, 39.79)]; + [bezier10Path addLineToPoint: CGPointMake(50.68, 39.79)]; + [bezier10Path addLineToPoint: CGPointMake(50.68, 38.87)]; + [bezier10Path addLineToPoint: CGPointMake(41.97, 38.87)]; + [bezier10Path addLineToPoint: CGPointMake(42.77, 39.79)]; + [bezier10Path closePath]; + bezier10Path.miterLimit = 4; + + bezier10Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier10Path fill]; + + + //// Bezier 11 Drawing + UIBezierPath* bezier11Path = [UIBezierPath bezierPath]; + [bezier11Path moveToPoint: CGPointMake(38.24, 25.87)]; + [bezier11Path addLineToPoint: CGPointMake(50.65, 25.87)]; + [bezier11Path addLineToPoint: CGPointMake(50.65, 24.95)]; + [bezier11Path addLineToPoint: CGPointMake(38.42, 24.95)]; + [bezier11Path addLineToPoint: CGPointMake(38.24, 25.87)]; + [bezier11Path closePath]; + bezier11Path.miterLimit = 4; + + bezier11Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier11Path fill]; + + + //// Bezier 12 Drawing + UIBezierPath* bezier12Path = [UIBezierPath bezierPath]; + [bezier12Path moveToPoint: CGPointMake(45.8, 31.65)]; + [bezier12Path addLineToPoint: CGPointMake(50.53, 31.65)]; + [bezier12Path addLineToPoint: CGPointMake(50.53, 30.73)]; + [bezier12Path addLineToPoint: CGPointMake(45.97, 30.73)]; + [bezier12Path addLineToPoint: CGPointMake(45.8, 31.65)]; + [bezier12Path closePath]; + bezier12Path.miterLimit = 4; + + bezier12Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier12Path fill]; + + + //// Bezier 13 Drawing + UIBezierPath* bezier13Path = [UIBezierPath bezierPath]; + [bezier13Path moveToPoint: CGPointMake(46.18, 29.62)]; + [bezier13Path addLineToPoint: CGPointMake(50.53, 29.62)]; + [bezier13Path addLineToPoint: CGPointMake(50.53, 28.7)]; + [bezier13Path addLineToPoint: CGPointMake(46.35, 28.7)]; + [bezier13Path addLineToPoint: CGPointMake(46.18, 29.62)]; + [bezier13Path closePath]; + bezier13Path.miterLimit = 4; + + bezier13Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier13Path fill]; + + + //// Bezier 14 Drawing + UIBezierPath* bezier14Path = [UIBezierPath bezierPath]; + [bezier14Path moveToPoint: CGPointMake(37.93, 28.7)]; + [bezier14Path addLineToPoint: CGPointMake(39.16, 28.7)]; + [bezier14Path addLineToPoint: CGPointMake(39.16, 29.62)]; + [bezier14Path addLineToPoint: CGPointMake(37.99, 29.62)]; + [bezier14Path addLineToPoint: CGPointMake(37.93, 28.7)]; + [bezier14Path closePath]; + bezier14Path.miterLimit = 4; + + bezier14Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier14Path fill]; + + + //// Bezier 15 Drawing + UIBezierPath* bezier15Path = [UIBezierPath bezierPath]; + [bezier15Path moveToPoint: CGPointMake(35.63, 27.59)]; + [bezier15Path addLineToPoint: CGPointMake(35.55, 27.58)]; + [bezier15Path addLineToPoint: CGPointMake(35.48, 27.57)]; + [bezier15Path addLineToPoint: CGPointMake(35.4, 27.56)]; + [bezier15Path addLineToPoint: CGPointMake(35.33, 27.55)]; + [bezier15Path addLineToPoint: CGPointMake(35.26, 27.53)]; + [bezier15Path addLineToPoint: CGPointMake(35.18, 27.52)]; + [bezier15Path addLineToPoint: CGPointMake(35.11, 27.51)]; + [bezier15Path addLineToPoint: CGPointMake(35.03, 27.5)]; + [bezier15Path addLineToPoint: CGPointMake(34.95, 27.49)]; + [bezier15Path addLineToPoint: CGPointMake(34.86, 27.48)]; + [bezier15Path addLineToPoint: CGPointMake(34.76, 27.48)]; + [bezier15Path addLineToPoint: CGPointMake(34.65, 27.47)]; + [bezier15Path addLineToPoint: CGPointMake(34.53, 27.47)]; + [bezier15Path addLineToPoint: CGPointMake(34.4, 27.48)]; + [bezier15Path addLineToPoint: CGPointMake(34.25, 27.49)]; + [bezier15Path addLineToPoint: CGPointMake(34.09, 27.5)]; + [bezier15Path addLineToPoint: CGPointMake(33.97, 27.52)]; + [bezier15Path addLineToPoint: CGPointMake(33.86, 27.53)]; + [bezier15Path addLineToPoint: CGPointMake(33.77, 27.57)]; + [bezier15Path addLineToPoint: CGPointMake(33.68, 27.6)]; + [bezier15Path addLineToPoint: CGPointMake(33.6, 27.64)]; + [bezier15Path addLineToPoint: CGPointMake(33.53, 27.69)]; + [bezier15Path addLineToPoint: CGPointMake(33.47, 27.74)]; + [bezier15Path addLineToPoint: CGPointMake(33.42, 27.8)]; + [bezier15Path addLineToPoint: CGPointMake(33.39, 27.86)]; + [bezier15Path addLineToPoint: CGPointMake(33.36, 27.92)]; + [bezier15Path addLineToPoint: CGPointMake(33.35, 27.99)]; + [bezier15Path addLineToPoint: CGPointMake(33.35, 28.06)]; + [bezier15Path addLineToPoint: CGPointMake(33.36, 28.13)]; + [bezier15Path addLineToPoint: CGPointMake(33.39, 28.21)]; + [bezier15Path addLineToPoint: CGPointMake(33.43, 28.28)]; + [bezier15Path addLineToPoint: CGPointMake(33.49, 28.35)]; + [bezier15Path addLineToPoint: CGPointMake(33.6, 28.46)]; + [bezier15Path addLineToPoint: CGPointMake(33.74, 28.55)]; + [bezier15Path addLineToPoint: CGPointMake(33.9, 28.62)]; + [bezier15Path addLineToPoint: CGPointMake(34.07, 28.68)]; + [bezier15Path addLineToPoint: CGPointMake(34.25, 28.74)]; + [bezier15Path addLineToPoint: CGPointMake(34.44, 28.8)]; + [bezier15Path addLineToPoint: CGPointMake(34.63, 28.87)]; + [bezier15Path addLineToPoint: CGPointMake(34.81, 28.95)]; + [bezier15Path addLineToPoint: CGPointMake(34.98, 29.04)]; + [bezier15Path addLineToPoint: CGPointMake(35.14, 29.16)]; + [bezier15Path addLineToPoint: CGPointMake(35.28, 29.3)]; + [bezier15Path addLineToPoint: CGPointMake(35.4, 29.48)]; + [bezier15Path addLineToPoint: CGPointMake(35.49, 29.7)]; + [bezier15Path addLineToPoint: CGPointMake(35.55, 29.95)]; + [bezier15Path addLineToPoint: CGPointMake(35.57, 30.26)]; + [bezier15Path addLineToPoint: CGPointMake(35.55, 30.62)]; + [bezier15Path addLineToPoint: CGPointMake(35.51, 30.89)]; + [bezier15Path addLineToPoint: CGPointMake(35.44, 31.12)]; + [bezier15Path addLineToPoint: CGPointMake(35.35, 31.34)]; + [bezier15Path addLineToPoint: CGPointMake(35.24, 31.53)]; + [bezier15Path addLineToPoint: CGPointMake(35.11, 31.69)]; + [bezier15Path addLineToPoint: CGPointMake(34.96, 31.83)]; + [bezier15Path addLineToPoint: CGPointMake(34.8, 31.96)]; + [bezier15Path addLineToPoint: CGPointMake(34.62, 32.07)]; + [bezier15Path addLineToPoint: CGPointMake(34.44, 32.15)]; + [bezier15Path addLineToPoint: CGPointMake(34.25, 32.23)]; + [bezier15Path addLineToPoint: CGPointMake(34.06, 32.28)]; + [bezier15Path addLineToPoint: CGPointMake(33.86, 32.33)]; + [bezier15Path addLineToPoint: CGPointMake(33.66, 32.36)]; + [bezier15Path addLineToPoint: CGPointMake(33.48, 32.38)]; + [bezier15Path addLineToPoint: CGPointMake(33.29, 32.39)]; + [bezier15Path addLineToPoint: CGPointMake(33.11, 32.4)]; + [bezier15Path addLineToPoint: CGPointMake(32.87, 32.4)]; + [bezier15Path addLineToPoint: CGPointMake(32.64, 32.39)]; + [bezier15Path addLineToPoint: CGPointMake(32.44, 32.39)]; + [bezier15Path addLineToPoint: CGPointMake(32.25, 32.39)]; + [bezier15Path addLineToPoint: CGPointMake(32.08, 32.38)]; + [bezier15Path addLineToPoint: CGPointMake(31.93, 32.37)]; + [bezier15Path addLineToPoint: CGPointMake(31.79, 32.36)]; + [bezier15Path addLineToPoint: CGPointMake(31.66, 32.34)]; + [bezier15Path addLineToPoint: CGPointMake(31.54, 32.33)]; + [bezier15Path addLineToPoint: CGPointMake(31.43, 32.31)]; + [bezier15Path addLineToPoint: CGPointMake(31.32, 32.29)]; + [bezier15Path addLineToPoint: CGPointMake(31.23, 32.26)]; + [bezier15Path addLineToPoint: CGPointMake(31.13, 32.24)]; + [bezier15Path addLineToPoint: CGPointMake(30.95, 32.17)]; + [bezier15Path addLineToPoint: CGPointMake(30.85, 32.13)]; + [bezier15Path addLineToPoint: CGPointMake(31.11, 30.88)]; + [bezier15Path addLineToPoint: CGPointMake(31.16, 30.89)]; + [bezier15Path addLineToPoint: CGPointMake(31.22, 30.9)]; + [bezier15Path addLineToPoint: CGPointMake(31.3, 30.93)]; + [bezier15Path addLineToPoint: CGPointMake(31.4, 30.95)]; + [bezier15Path addLineToPoint: CGPointMake(31.5, 30.97)]; + [bezier15Path addLineToPoint: CGPointMake(31.62, 31)]; + [bezier15Path addLineToPoint: CGPointMake(31.74, 31.02)]; + [bezier15Path addLineToPoint: CGPointMake(31.88, 31.05)]; + [bezier15Path addLineToPoint: CGPointMake(32.02, 31.07)]; + [bezier15Path addLineToPoint: CGPointMake(32.17, 31.09)]; + [bezier15Path addLineToPoint: CGPointMake(32.32, 31.11)]; + [bezier15Path addLineToPoint: CGPointMake(32.48, 31.13)]; + [bezier15Path addLineToPoint: CGPointMake(32.65, 31.13)]; + [bezier15Path addLineToPoint: CGPointMake(32.81, 31.14)]; + [bezier15Path addLineToPoint: CGPointMake(32.98, 31.14)]; + [bezier15Path addLineToPoint: CGPointMake(33.14, 31.13)]; + [bezier15Path addLineToPoint: CGPointMake(33.31, 31.1)]; + [bezier15Path addLineToPoint: CGPointMake(33.44, 31.05)]; + [bezier15Path addLineToPoint: CGPointMake(33.54, 30.99)]; + [bezier15Path addLineToPoint: CGPointMake(33.62, 30.91)]; + [bezier15Path addLineToPoint: CGPointMake(33.68, 30.83)]; + [bezier15Path addLineToPoint: CGPointMake(33.72, 30.74)]; + [bezier15Path addLineToPoint: CGPointMake(33.75, 30.65)]; + [bezier15Path addLineToPoint: CGPointMake(33.77, 30.56)]; + [bezier15Path addLineToPoint: CGPointMake(33.78, 30.4)]; + [bezier15Path addLineToPoint: CGPointMake(33.73, 30.26)]; + [bezier15Path addLineToPoint: CGPointMake(33.64, 30.14)]; + [bezier15Path addLineToPoint: CGPointMake(33.49, 30.05)]; + [bezier15Path addLineToPoint: CGPointMake(33.32, 29.96)]; + [bezier15Path addLineToPoint: CGPointMake(33.12, 29.87)]; + [bezier15Path addLineToPoint: CGPointMake(32.9, 29.79)]; + [bezier15Path addLineToPoint: CGPointMake(32.68, 29.7)]; + [bezier15Path addLineToPoint: CGPointMake(32.45, 29.6)]; + [bezier15Path addLineToPoint: CGPointMake(32.24, 29.48)]; + [bezier15Path addLineToPoint: CGPointMake(32.04, 29.33)]; + [bezier15Path addLineToPoint: CGPointMake(31.85, 29.16)]; + [bezier15Path addLineToPoint: CGPointMake(31.71, 28.94)]; + [bezier15Path addLineToPoint: CGPointMake(31.61, 28.68)]; + [bezier15Path addLineToPoint: CGPointMake(31.56, 28.38)]; + [bezier15Path addLineToPoint: CGPointMake(31.56, 28.01)]; + [bezier15Path addLineToPoint: CGPointMake(31.59, 27.79)]; + [bezier15Path addLineToPoint: CGPointMake(31.63, 27.58)]; + [bezier15Path addLineToPoint: CGPointMake(31.69, 27.39)]; + [bezier15Path addLineToPoint: CGPointMake(31.76, 27.2)]; + [bezier15Path addLineToPoint: CGPointMake(31.85, 27.03)]; + [bezier15Path addLineToPoint: CGPointMake(31.95, 26.89)]; + [bezier15Path addLineToPoint: CGPointMake(32.07, 26.74)]; + [bezier15Path addLineToPoint: CGPointMake(32.21, 26.62)]; + [bezier15Path addLineToPoint: CGPointMake(32.38, 26.51)]; + [bezier15Path addLineToPoint: CGPointMake(32.56, 26.42)]; + [bezier15Path addLineToPoint: CGPointMake(32.76, 26.33)]; + [bezier15Path addLineToPoint: CGPointMake(32.99, 26.27)]; + [bezier15Path addLineToPoint: CGPointMake(33.25, 26.22)]; + [bezier15Path addLineToPoint: CGPointMake(33.53, 26.18)]; + [bezier15Path addLineToPoint: CGPointMake(33.84, 26.16)]; + [bezier15Path addLineToPoint: CGPointMake(34.17, 26.15)]; + [bezier15Path addLineToPoint: CGPointMake(34.38, 26.15)]; + [bezier15Path addLineToPoint: CGPointMake(34.58, 26.16)]; + [bezier15Path addLineToPoint: CGPointMake(34.75, 26.16)]; + [bezier15Path addLineToPoint: CGPointMake(34.91, 26.17)]; + [bezier15Path addLineToPoint: CGPointMake(35.05, 26.18)]; + [bezier15Path addLineToPoint: CGPointMake(35.18, 26.19)]; + [bezier15Path addLineToPoint: CGPointMake(35.3, 26.2)]; + [bezier15Path addLineToPoint: CGPointMake(35.4, 26.21)]; + [bezier15Path addLineToPoint: CGPointMake(35.5, 26.22)]; + [bezier15Path addLineToPoint: CGPointMake(35.58, 26.24)]; + [bezier15Path addLineToPoint: CGPointMake(35.65, 26.25)]; + [bezier15Path addLineToPoint: CGPointMake(35.72, 26.26)]; + [bezier15Path addLineToPoint: CGPointMake(35.78, 26.28)]; + [bezier15Path addLineToPoint: CGPointMake(35.83, 26.28)]; + [bezier15Path addLineToPoint: CGPointMake(35.88, 26.29)]; + [bezier15Path addLineToPoint: CGPointMake(35.92, 26.3)]; + [bezier15Path addLineToPoint: CGPointMake(35.63, 27.59)]; + [bezier15Path closePath]; + bezier15Path.miterLimit = 4; + + bezier15Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier15Path fill]; + + + //// Bezier 16 Drawing + UIBezierPath* bezier16Path = [UIBezierPath bezierPath]; + [bezier16Path moveToPoint: CGPointMake(35.63, 27.59)]; + [bezier16Path addLineToPoint: CGPointMake(35.63, 27.59)]; + [bezier16Path addLineToPoint: CGPointMake(35.55, 27.58)]; + [bezier16Path addLineToPoint: CGPointMake(35.48, 27.57)]; + [bezier16Path addLineToPoint: CGPointMake(35.4, 27.56)]; + [bezier16Path addLineToPoint: CGPointMake(35.33, 27.55)]; + [bezier16Path addLineToPoint: CGPointMake(35.26, 27.53)]; + [bezier16Path addLineToPoint: CGPointMake(35.18, 27.52)]; + [bezier16Path addLineToPoint: CGPointMake(35.11, 27.51)]; + [bezier16Path addLineToPoint: CGPointMake(35.03, 27.5)]; + [bezier16Path addLineToPoint: CGPointMake(34.95, 27.49)]; + [bezier16Path addLineToPoint: CGPointMake(34.86, 27.48)]; + [bezier16Path addLineToPoint: CGPointMake(34.76, 27.48)]; + [bezier16Path addLineToPoint: CGPointMake(34.65, 27.47)]; + [bezier16Path addLineToPoint: CGPointMake(34.53, 27.47)]; + [bezier16Path addLineToPoint: CGPointMake(34.4, 27.48)]; + [bezier16Path addLineToPoint: CGPointMake(34.25, 27.49)]; + [bezier16Path addLineToPoint: CGPointMake(34.09, 27.5)]; + [bezier16Path addLineToPoint: CGPointMake(33.97, 27.52)]; + [bezier16Path addLineToPoint: CGPointMake(33.86, 27.53)]; + [bezier16Path addLineToPoint: CGPointMake(33.77, 27.57)]; + [bezier16Path addLineToPoint: CGPointMake(33.68, 27.6)]; + [bezier16Path addLineToPoint: CGPointMake(33.6, 27.64)]; + [bezier16Path addLineToPoint: CGPointMake(33.53, 27.69)]; + [bezier16Path addLineToPoint: CGPointMake(33.47, 27.74)]; + [bezier16Path addLineToPoint: CGPointMake(33.42, 27.8)]; + [bezier16Path addLineToPoint: CGPointMake(33.39, 27.86)]; + [bezier16Path addLineToPoint: CGPointMake(33.36, 27.92)]; + [bezier16Path addLineToPoint: CGPointMake(33.35, 27.99)]; + [bezier16Path addLineToPoint: CGPointMake(33.35, 28.06)]; + [bezier16Path addLineToPoint: CGPointMake(33.36, 28.13)]; + [bezier16Path addLineToPoint: CGPointMake(33.39, 28.21)]; + [bezier16Path addLineToPoint: CGPointMake(33.43, 28.28)]; + [bezier16Path addLineToPoint: CGPointMake(33.49, 28.35)]; + [bezier16Path addLineToPoint: CGPointMake(33.6, 28.46)]; + [bezier16Path addLineToPoint: CGPointMake(33.74, 28.55)]; + [bezier16Path addLineToPoint: CGPointMake(33.9, 28.62)]; + [bezier16Path addLineToPoint: CGPointMake(34.07, 28.68)]; + [bezier16Path addLineToPoint: CGPointMake(34.25, 28.74)]; + [bezier16Path addLineToPoint: CGPointMake(34.44, 28.8)]; + [bezier16Path addLineToPoint: CGPointMake(34.63, 28.87)]; + [bezier16Path addLineToPoint: CGPointMake(34.81, 28.95)]; + [bezier16Path addLineToPoint: CGPointMake(34.98, 29.04)]; + [bezier16Path addLineToPoint: CGPointMake(35.14, 29.16)]; + [bezier16Path addLineToPoint: CGPointMake(35.28, 29.3)]; + [bezier16Path addLineToPoint: CGPointMake(35.4, 29.48)]; + [bezier16Path addLineToPoint: CGPointMake(35.49, 29.7)]; + [bezier16Path addLineToPoint: CGPointMake(35.55, 29.95)]; + [bezier16Path addLineToPoint: CGPointMake(35.57, 30.26)]; + [bezier16Path addLineToPoint: CGPointMake(35.55, 30.62)]; + [bezier16Path addLineToPoint: CGPointMake(35.51, 30.89)]; + [bezier16Path addLineToPoint: CGPointMake(35.44, 31.12)]; + [bezier16Path addLineToPoint: CGPointMake(35.35, 31.34)]; + [bezier16Path addLineToPoint: CGPointMake(35.24, 31.53)]; + [bezier16Path addLineToPoint: CGPointMake(35.11, 31.69)]; + [bezier16Path addLineToPoint: CGPointMake(34.96, 31.83)]; + [bezier16Path addLineToPoint: CGPointMake(34.8, 31.96)]; + [bezier16Path addLineToPoint: CGPointMake(34.62, 32.07)]; + [bezier16Path addLineToPoint: CGPointMake(34.44, 32.15)]; + [bezier16Path addLineToPoint: CGPointMake(34.25, 32.23)]; + [bezier16Path addLineToPoint: CGPointMake(34.06, 32.28)]; + [bezier16Path addLineToPoint: CGPointMake(33.86, 32.33)]; + [bezier16Path addLineToPoint: CGPointMake(33.66, 32.36)]; + [bezier16Path addLineToPoint: CGPointMake(33.48, 32.38)]; + [bezier16Path addLineToPoint: CGPointMake(33.29, 32.39)]; + [bezier16Path addLineToPoint: CGPointMake(33.11, 32.4)]; + [bezier16Path addLineToPoint: CGPointMake(32.87, 32.4)]; + [bezier16Path addLineToPoint: CGPointMake(32.64, 32.39)]; + [bezier16Path addLineToPoint: CGPointMake(32.44, 32.39)]; + [bezier16Path addLineToPoint: CGPointMake(32.25, 32.39)]; + [bezier16Path addLineToPoint: CGPointMake(32.08, 32.38)]; + [bezier16Path addLineToPoint: CGPointMake(31.93, 32.37)]; + [bezier16Path addLineToPoint: CGPointMake(31.79, 32.36)]; + [bezier16Path addLineToPoint: CGPointMake(31.66, 32.34)]; + [bezier16Path addLineToPoint: CGPointMake(31.54, 32.33)]; + [bezier16Path addLineToPoint: CGPointMake(31.43, 32.31)]; + [bezier16Path addLineToPoint: CGPointMake(31.32, 32.29)]; + [bezier16Path addLineToPoint: CGPointMake(31.23, 32.26)]; + [bezier16Path addLineToPoint: CGPointMake(31.13, 32.24)]; + [bezier16Path addLineToPoint: CGPointMake(30.95, 32.17)]; + [bezier16Path addLineToPoint: CGPointMake(30.85, 32.13)]; + [bezier16Path addLineToPoint: CGPointMake(31.11, 30.88)]; + [bezier16Path addLineToPoint: CGPointMake(31.16, 30.89)]; + [bezier16Path addLineToPoint: CGPointMake(31.22, 30.9)]; + [bezier16Path addLineToPoint: CGPointMake(31.3, 30.93)]; + [bezier16Path addLineToPoint: CGPointMake(31.4, 30.95)]; + [bezier16Path addLineToPoint: CGPointMake(31.5, 30.97)]; + [bezier16Path addLineToPoint: CGPointMake(31.62, 31)]; + [bezier16Path addLineToPoint: CGPointMake(31.74, 31.02)]; + [bezier16Path addLineToPoint: CGPointMake(31.88, 31.05)]; + [bezier16Path addLineToPoint: CGPointMake(32.02, 31.07)]; + [bezier16Path addLineToPoint: CGPointMake(32.17, 31.09)]; + [bezier16Path addLineToPoint: CGPointMake(32.32, 31.11)]; + [bezier16Path addLineToPoint: CGPointMake(32.48, 31.13)]; + [bezier16Path addLineToPoint: CGPointMake(32.65, 31.13)]; + [bezier16Path addLineToPoint: CGPointMake(32.81, 31.14)]; + [bezier16Path addLineToPoint: CGPointMake(32.98, 31.14)]; + [bezier16Path addLineToPoint: CGPointMake(33.14, 31.13)]; + [bezier16Path addLineToPoint: CGPointMake(33.31, 31.1)]; + [bezier16Path addLineToPoint: CGPointMake(33.44, 31.05)]; + [bezier16Path addLineToPoint: CGPointMake(33.54, 30.99)]; + [bezier16Path addLineToPoint: CGPointMake(33.62, 30.91)]; + [bezier16Path addLineToPoint: CGPointMake(33.68, 30.83)]; + [bezier16Path addLineToPoint: CGPointMake(33.72, 30.74)]; + [bezier16Path addLineToPoint: CGPointMake(33.75, 30.65)]; + [bezier16Path addLineToPoint: CGPointMake(33.77, 30.56)]; + [bezier16Path addLineToPoint: CGPointMake(33.78, 30.4)]; + [bezier16Path addLineToPoint: CGPointMake(33.73, 30.26)]; + [bezier16Path addLineToPoint: CGPointMake(33.64, 30.14)]; + [bezier16Path addLineToPoint: CGPointMake(33.49, 30.05)]; + [bezier16Path addLineToPoint: CGPointMake(33.32, 29.96)]; + [bezier16Path addLineToPoint: CGPointMake(33.12, 29.87)]; + [bezier16Path addLineToPoint: CGPointMake(32.9, 29.79)]; + [bezier16Path addLineToPoint: CGPointMake(32.68, 29.7)]; + [bezier16Path addLineToPoint: CGPointMake(32.45, 29.6)]; + [bezier16Path addLineToPoint: CGPointMake(32.24, 29.48)]; + [bezier16Path addLineToPoint: CGPointMake(32.04, 29.33)]; + [bezier16Path addLineToPoint: CGPointMake(31.85, 29.16)]; + [bezier16Path addLineToPoint: CGPointMake(31.71, 28.94)]; + [bezier16Path addLineToPoint: CGPointMake(31.61, 28.68)]; + [bezier16Path addLineToPoint: CGPointMake(31.56, 28.38)]; + [bezier16Path addLineToPoint: CGPointMake(31.56, 28.01)]; + [bezier16Path addLineToPoint: CGPointMake(31.59, 27.79)]; + [bezier16Path addLineToPoint: CGPointMake(31.63, 27.58)]; + [bezier16Path addLineToPoint: CGPointMake(31.69, 27.39)]; + [bezier16Path addLineToPoint: CGPointMake(31.76, 27.2)]; + [bezier16Path addLineToPoint: CGPointMake(31.85, 27.03)]; + [bezier16Path addLineToPoint: CGPointMake(31.95, 26.89)]; + [bezier16Path addLineToPoint: CGPointMake(32.07, 26.74)]; + [bezier16Path addLineToPoint: CGPointMake(32.21, 26.62)]; + [bezier16Path addLineToPoint: CGPointMake(32.38, 26.51)]; + [bezier16Path addLineToPoint: CGPointMake(32.56, 26.42)]; + [bezier16Path addLineToPoint: CGPointMake(32.76, 26.33)]; + [bezier16Path addLineToPoint: CGPointMake(32.99, 26.27)]; + [bezier16Path addLineToPoint: CGPointMake(33.25, 26.22)]; + [bezier16Path addLineToPoint: CGPointMake(33.53, 26.18)]; + [bezier16Path addLineToPoint: CGPointMake(33.84, 26.16)]; + [bezier16Path addLineToPoint: CGPointMake(34.17, 26.15)]; + [bezier16Path addLineToPoint: CGPointMake(34.38, 26.15)]; + [bezier16Path addLineToPoint: CGPointMake(34.58, 26.16)]; + [bezier16Path addLineToPoint: CGPointMake(34.75, 26.16)]; + [bezier16Path addLineToPoint: CGPointMake(34.91, 26.17)]; + [bezier16Path addLineToPoint: CGPointMake(35.05, 26.18)]; + [bezier16Path addLineToPoint: CGPointMake(35.18, 26.19)]; + [bezier16Path addLineToPoint: CGPointMake(35.3, 26.2)]; + [bezier16Path addLineToPoint: CGPointMake(35.4, 26.21)]; + [bezier16Path addLineToPoint: CGPointMake(35.5, 26.22)]; + [bezier16Path addLineToPoint: CGPointMake(35.58, 26.24)]; + [bezier16Path addLineToPoint: CGPointMake(35.65, 26.25)]; + [bezier16Path addLineToPoint: CGPointMake(35.72, 26.26)]; + [bezier16Path addLineToPoint: CGPointMake(35.78, 26.28)]; + [bezier16Path addLineToPoint: CGPointMake(35.83, 26.28)]; + [bezier16Path addLineToPoint: CGPointMake(35.88, 26.29)]; + [bezier16Path addLineToPoint: CGPointMake(35.92, 26.3)]; + [bezier16Path addLineToPoint: CGPointMake(35.63, 27.59)]; + [bezier16Path closePath]; + bezier16Path.miterLimit = 4; + + bezier16Path.usesEvenOddFillRule = YES; + + [color3 setStroke]; + bezier16Path.lineWidth = 0.5; + [bezier16Path stroke]; + + + //// Bezier 17 Drawing + UIBezierPath* bezier17Path = [UIBezierPath bezierPath]; + [bezier17Path moveToPoint: CGPointMake(36.98, 24.89)]; + [bezier17Path addLineToPoint: CGPointMake(38.56, 24.89)]; + [bezier17Path addLineToPoint: CGPointMake(38.33, 26.27)]; + [bezier17Path addLineToPoint: CGPointMake(39.28, 26.27)]; + [bezier17Path addLineToPoint: CGPointMake(39.07, 27.56)]; + [bezier17Path addLineToPoint: CGPointMake(38.07, 27.53)]; + [bezier17Path addLineToPoint: CGPointMake(37.53, 30.71)]; + [bezier17Path addLineToPoint: CGPointMake(37.52, 30.82)]; + [bezier17Path addLineToPoint: CGPointMake(37.55, 30.92)]; + [bezier17Path addLineToPoint: CGPointMake(37.6, 30.99)]; + [bezier17Path addLineToPoint: CGPointMake(37.68, 31.05)]; + [bezier17Path addLineToPoint: CGPointMake(37.78, 31.09)]; + [bezier17Path addLineToPoint: CGPointMake(37.89, 31.13)]; + [bezier17Path addLineToPoint: CGPointMake(38.02, 31.15)]; + [bezier17Path addLineToPoint: CGPointMake(38.16, 31.16)]; + [bezier17Path addLineToPoint: CGPointMake(38.28, 31.16)]; + [bezier17Path addLineToPoint: CGPointMake(38.4, 31.14)]; + [bezier17Path addLineToPoint: CGPointMake(38.5, 31.13)]; + [bezier17Path addLineToPoint: CGPointMake(38.59, 31.1)]; + [bezier17Path addLineToPoint: CGPointMake(38.66, 31.08)]; + [bezier17Path addLineToPoint: CGPointMake(38.71, 31.06)]; + [bezier17Path addLineToPoint: CGPointMake(38.75, 31.05)]; + [bezier17Path addLineToPoint: CGPointMake(38.76, 31.05)]; + [bezier17Path addLineToPoint: CGPointMake(38.56, 32.11)]; + [bezier17Path addLineToPoint: CGPointMake(38.52, 32.13)]; + [bezier17Path addLineToPoint: CGPointMake(38.48, 32.16)]; + [bezier17Path addLineToPoint: CGPointMake(38.44, 32.18)]; + [bezier17Path addLineToPoint: CGPointMake(38.4, 32.2)]; + [bezier17Path addLineToPoint: CGPointMake(38.36, 32.22)]; + [bezier17Path addLineToPoint: CGPointMake(38.32, 32.24)]; + [bezier17Path addLineToPoint: CGPointMake(38.27, 32.25)]; + [bezier17Path addLineToPoint: CGPointMake(38.21, 32.27)]; + [bezier17Path addLineToPoint: CGPointMake(38.16, 32.29)]; + [bezier17Path addLineToPoint: CGPointMake(38.1, 32.3)]; + [bezier17Path addLineToPoint: CGPointMake(38.03, 32.31)]; + [bezier17Path addLineToPoint: CGPointMake(37.96, 32.32)]; + [bezier17Path addLineToPoint: CGPointMake(37.89, 32.33)]; + [bezier17Path addLineToPoint: CGPointMake(37.8, 32.35)]; + [bezier17Path addLineToPoint: CGPointMake(37.71, 32.36)]; + [bezier17Path addLineToPoint: CGPointMake(37.62, 32.37)]; + [bezier17Path addLineToPoint: CGPointMake(37.18, 32.37)]; + [bezier17Path addLineToPoint: CGPointMake(36.96, 32.35)]; + [bezier17Path addLineToPoint: CGPointMake(36.76, 32.33)]; + [bezier17Path addLineToPoint: CGPointMake(36.57, 32.29)]; + [bezier17Path addLineToPoint: CGPointMake(36.42, 32.25)]; + [bezier17Path addLineToPoint: CGPointMake(36.29, 32.2)]; + [bezier17Path addLineToPoint: CGPointMake(36.18, 32.15)]; + [bezier17Path addLineToPoint: CGPointMake(36.08, 32.08)]; + [bezier17Path addLineToPoint: CGPointMake(36.01, 32)]; + [bezier17Path addLineToPoint: CGPointMake(35.95, 31.92)]; + [bezier17Path addLineToPoint: CGPointMake(35.91, 31.83)]; + [bezier17Path addLineToPoint: CGPointMake(35.89, 31.73)]; + [bezier17Path addLineToPoint: CGPointMake(35.87, 31.62)]; + [bezier17Path addLineToPoint: CGPointMake(35.86, 31.5)]; + [bezier17Path addLineToPoint: CGPointMake(35.86, 31.38)]; + [bezier17Path addLineToPoint: CGPointMake(35.88, 31.25)]; + [bezier17Path addLineToPoint: CGPointMake(35.9, 31.1)]; + [bezier17Path addLineToPoint: CGPointMake(36.98, 24.89)]; + [bezier17Path closePath]; + bezier17Path.miterLimit = 4; + + bezier17Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier17Path fill]; + + + //// Bezier 18 Drawing + UIBezierPath* bezier18Path = [UIBezierPath bezierPath]; + [bezier18Path moveToPoint: CGPointMake(36.98, 24.89)]; + [bezier18Path addLineToPoint: CGPointMake(38.56, 24.89)]; + [bezier18Path addLineToPoint: CGPointMake(38.33, 26.27)]; + [bezier18Path addLineToPoint: CGPointMake(39.28, 26.27)]; + [bezier18Path addLineToPoint: CGPointMake(39.07, 27.56)]; + [bezier18Path addLineToPoint: CGPointMake(38.07, 27.53)]; + [bezier18Path addLineToPoint: CGPointMake(37.53, 30.71)]; + [bezier18Path addLineToPoint: CGPointMake(37.52, 30.82)]; + [bezier18Path addLineToPoint: CGPointMake(37.55, 30.92)]; + [bezier18Path addLineToPoint: CGPointMake(37.6, 30.99)]; + [bezier18Path addLineToPoint: CGPointMake(37.68, 31.05)]; + [bezier18Path addLineToPoint: CGPointMake(37.78, 31.09)]; + [bezier18Path addLineToPoint: CGPointMake(37.89, 31.13)]; + [bezier18Path addLineToPoint: CGPointMake(38.02, 31.15)]; + [bezier18Path addLineToPoint: CGPointMake(38.16, 31.16)]; + [bezier18Path addLineToPoint: CGPointMake(38.28, 31.16)]; + [bezier18Path addLineToPoint: CGPointMake(38.4, 31.14)]; + [bezier18Path addLineToPoint: CGPointMake(38.5, 31.13)]; + [bezier18Path addLineToPoint: CGPointMake(38.59, 31.1)]; + [bezier18Path addLineToPoint: CGPointMake(38.66, 31.08)]; + [bezier18Path addLineToPoint: CGPointMake(38.71, 31.06)]; + [bezier18Path addLineToPoint: CGPointMake(38.75, 31.05)]; + [bezier18Path addLineToPoint: CGPointMake(38.76, 31.05)]; + [bezier18Path addLineToPoint: CGPointMake(38.56, 32.11)]; + [bezier18Path addLineToPoint: CGPointMake(38.52, 32.13)]; + [bezier18Path addLineToPoint: CGPointMake(38.48, 32.16)]; + [bezier18Path addLineToPoint: CGPointMake(38.44, 32.18)]; + [bezier18Path addLineToPoint: CGPointMake(38.4, 32.2)]; + [bezier18Path addLineToPoint: CGPointMake(38.36, 32.22)]; + [bezier18Path addLineToPoint: CGPointMake(38.32, 32.24)]; + [bezier18Path addLineToPoint: CGPointMake(38.27, 32.25)]; + [bezier18Path addLineToPoint: CGPointMake(38.21, 32.27)]; + [bezier18Path addLineToPoint: CGPointMake(38.16, 32.29)]; + [bezier18Path addLineToPoint: CGPointMake(38.1, 32.3)]; + [bezier18Path addLineToPoint: CGPointMake(38.03, 32.31)]; + [bezier18Path addLineToPoint: CGPointMake(37.96, 32.32)]; + [bezier18Path addLineToPoint: CGPointMake(37.89, 32.33)]; + [bezier18Path addLineToPoint: CGPointMake(37.8, 32.35)]; + [bezier18Path addLineToPoint: CGPointMake(37.71, 32.36)]; + [bezier18Path addLineToPoint: CGPointMake(37.62, 32.37)]; + [bezier18Path addLineToPoint: CGPointMake(37.18, 32.37)]; + [bezier18Path addLineToPoint: CGPointMake(36.96, 32.35)]; + [bezier18Path addLineToPoint: CGPointMake(36.76, 32.33)]; + [bezier18Path addLineToPoint: CGPointMake(36.57, 32.29)]; + [bezier18Path addLineToPoint: CGPointMake(36.42, 32.25)]; + [bezier18Path addLineToPoint: CGPointMake(36.29, 32.2)]; + [bezier18Path addLineToPoint: CGPointMake(36.18, 32.15)]; + [bezier18Path addLineToPoint: CGPointMake(36.08, 32.08)]; + [bezier18Path addLineToPoint: CGPointMake(36.01, 32)]; + [bezier18Path addLineToPoint: CGPointMake(35.95, 31.92)]; + [bezier18Path addLineToPoint: CGPointMake(35.91, 31.83)]; + [bezier18Path addLineToPoint: CGPointMake(35.89, 31.73)]; + [bezier18Path addLineToPoint: CGPointMake(35.87, 31.62)]; + [bezier18Path addLineToPoint: CGPointMake(35.86, 31.5)]; + [bezier18Path addLineToPoint: CGPointMake(35.86, 31.38)]; + [bezier18Path addLineToPoint: CGPointMake(35.88, 31.25)]; + [bezier18Path addLineToPoint: CGPointMake(35.9, 31.1)]; + [bezier18Path addLineToPoint: CGPointMake(36.98, 24.89)]; + [bezier18Path closePath]; + bezier18Path.miterLimit = 4; + + bezier18Path.usesEvenOddFillRule = YES; + + [color3 setStroke]; + bezier18Path.lineWidth = 0.5; + [bezier18Path stroke]; + + + //// Bezier 19 Drawing + UIBezierPath* bezier19Path = [UIBezierPath bezierPath]; + [bezier19Path moveToPoint: CGPointMake(40.52, 29.8)]; + [bezier19Path addLineToPoint: CGPointMake(40.51, 29.9)]; + [bezier19Path addLineToPoint: CGPointMake(40.53, 30.01)]; + [bezier19Path addLineToPoint: CGPointMake(40.55, 30.12)]; + [bezier19Path addLineToPoint: CGPointMake(40.59, 30.23)]; + [bezier19Path addLineToPoint: CGPointMake(40.63, 30.33)]; + [bezier19Path addLineToPoint: CGPointMake(40.7, 30.44)]; + [bezier19Path addLineToPoint: CGPointMake(40.76, 30.53)]; + [bezier19Path addLineToPoint: CGPointMake(40.84, 30.63)]; + [bezier19Path addLineToPoint: CGPointMake(40.93, 30.72)]; + [bezier19Path addLineToPoint: CGPointMake(41.02, 30.8)]; + [bezier19Path addLineToPoint: CGPointMake(41.12, 30.87)]; + [bezier19Path addLineToPoint: CGPointMake(41.23, 30.93)]; + [bezier19Path addLineToPoint: CGPointMake(41.34, 30.98)]; + [bezier19Path addLineToPoint: CGPointMake(41.45, 31.02)]; + [bezier19Path addLineToPoint: CGPointMake(41.57, 31.05)]; + [bezier19Path addLineToPoint: CGPointMake(41.72, 31.07)]; + [bezier19Path addLineToPoint: CGPointMake(41.86, 31.09)]; + [bezier19Path addLineToPoint: CGPointMake(42.01, 31.1)]; + [bezier19Path addLineToPoint: CGPointMake(42.15, 31.12)]; + [bezier19Path addLineToPoint: CGPointMake(42.3, 31.12)]; + [bezier19Path addLineToPoint: CGPointMake(42.46, 31.12)]; + [bezier19Path addLineToPoint: CGPointMake(42.6, 31.12)]; + [bezier19Path addLineToPoint: CGPointMake(42.76, 31.1)]; + [bezier19Path addLineToPoint: CGPointMake(42.91, 31.08)]; + [bezier19Path addLineToPoint: CGPointMake(43.06, 31.05)]; + [bezier19Path addLineToPoint: CGPointMake(43.22, 31.02)]; + [bezier19Path addLineToPoint: CGPointMake(43.38, 30.97)]; + [bezier19Path addLineToPoint: CGPointMake(43.54, 30.9)]; + [bezier19Path addLineToPoint: CGPointMake(43.7, 30.84)]; + [bezier19Path addLineToPoint: CGPointMake(43.86, 30.75)]; + [bezier19Path addLineToPoint: CGPointMake(44.03, 30.65)]; + [bezier19Path addLineToPoint: CGPointMake(43.8, 32.05)]; + [bezier19Path addLineToPoint: CGPointMake(43.71, 32.09)]; + [bezier19Path addLineToPoint: CGPointMake(43.62, 32.14)]; + [bezier19Path addLineToPoint: CGPointMake(43.53, 32.17)]; + [bezier19Path addLineToPoint: CGPointMake(43.44, 32.21)]; + [bezier19Path addLineToPoint: CGPointMake(43.36, 32.24)]; + [bezier19Path addLineToPoint: CGPointMake(43.26, 32.27)]; + [bezier19Path addLineToPoint: CGPointMake(43.17, 32.29)]; + [bezier19Path addLineToPoint: CGPointMake(43.08, 32.31)]; + [bezier19Path addLineToPoint: CGPointMake(42.97, 32.32)]; + [bezier19Path addLineToPoint: CGPointMake(42.86, 32.33)]; + [bezier19Path addLineToPoint: CGPointMake(42.74, 32.35)]; + [bezier19Path addLineToPoint: CGPointMake(42.61, 32.36)]; + [bezier19Path addLineToPoint: CGPointMake(42.46, 32.36)]; + [bezier19Path addLineToPoint: CGPointMake(42.31, 32.36)]; + [bezier19Path addLineToPoint: CGPointMake(42.13, 32.37)]; + [bezier19Path addLineToPoint: CGPointMake(41.94, 32.37)]; + [bezier19Path addLineToPoint: CGPointMake(41.66, 32.36)]; + [bezier19Path addLineToPoint: CGPointMake(41.38, 32.33)]; + [bezier19Path addLineToPoint: CGPointMake(41.09, 32.29)]; + [bezier19Path addLineToPoint: CGPointMake(40.81, 32.23)]; + [bezier19Path addLineToPoint: CGPointMake(40.53, 32.14)]; + [bezier19Path addLineToPoint: CGPointMake(40.26, 32.03)]; + [bezier19Path addLineToPoint: CGPointMake(40.01, 31.89)]; + [bezier19Path addLineToPoint: CGPointMake(39.77, 31.72)]; + [bezier19Path addLineToPoint: CGPointMake(39.55, 31.53)]; + [bezier19Path addLineToPoint: CGPointMake(39.35, 31.3)]; + [bezier19Path addLineToPoint: CGPointMake(39.19, 31.04)]; + [bezier19Path addLineToPoint: CGPointMake(39.05, 30.73)]; + [bezier19Path addLineToPoint: CGPointMake(38.95, 30.4)]; + [bezier19Path addLineToPoint: CGPointMake(38.89, 30.02)]; + [bezier19Path addLineToPoint: CGPointMake(38.87, 29.6)]; + [bezier19Path addLineToPoint: CGPointMake(38.9, 29.13)]; + [bezier19Path addLineToPoint: CGPointMake(38.93, 28.95)]; + [bezier19Path addLineToPoint: CGPointMake(38.96, 28.74)]; + [bezier19Path addLineToPoint: CGPointMake(39.01, 28.51)]; + [bezier19Path addLineToPoint: CGPointMake(39.07, 28.27)]; + [bezier19Path addLineToPoint: CGPointMake(39.15, 28.03)]; + [bezier19Path addLineToPoint: CGPointMake(39.26, 27.78)]; + [bezier19Path addLineToPoint: CGPointMake(39.39, 27.53)]; + [bezier19Path addLineToPoint: CGPointMake(39.55, 27.3)]; + [bezier19Path addLineToPoint: CGPointMake(39.73, 27.07)]; + [bezier19Path addLineToPoint: CGPointMake(39.95, 26.85)]; + [bezier19Path addLineToPoint: CGPointMake(40.2, 26.66)]; + [bezier19Path addLineToPoint: CGPointMake(40.49, 26.49)]; + [bezier19Path addLineToPoint: CGPointMake(40.82, 26.34)]; + [bezier19Path addLineToPoint: CGPointMake(41.19, 26.24)]; + [bezier19Path addLineToPoint: CGPointMake(41.6, 26.17)]; + [bezier19Path addLineToPoint: CGPointMake(42.06, 26.15)]; + [bezier19Path addLineToPoint: CGPointMake(42.28, 26.16)]; + [bezier19Path addLineToPoint: CGPointMake(42.51, 26.18)]; + [bezier19Path addLineToPoint: CGPointMake(42.75, 26.22)]; + [bezier19Path addLineToPoint: CGPointMake(42.98, 26.28)]; + [bezier19Path addLineToPoint: CGPointMake(43.21, 26.36)]; + [bezier19Path addLineToPoint: CGPointMake(43.43, 26.46)]; + [bezier19Path addLineToPoint: CGPointMake(43.63, 26.6)]; + [bezier19Path addLineToPoint: CGPointMake(43.82, 26.76)]; + [bezier19Path addLineToPoint: CGPointMake(43.99, 26.95)]; + [bezier19Path addLineToPoint: CGPointMake(44.13, 27.18)]; + [bezier19Path addLineToPoint: CGPointMake(44.25, 27.44)]; + [bezier19Path addLineToPoint: CGPointMake(44.33, 27.74)]; + [bezier19Path addLineToPoint: CGPointMake(44.37, 28.09)]; + [bezier19Path addLineToPoint: CGPointMake(44.38, 28.47)]; + [bezier19Path addLineToPoint: CGPointMake(44.34, 28.91)]; + [bezier19Path addLineToPoint: CGPointMake(44.25, 29.38)]; + [bezier19Path addLineToPoint: CGPointMake(44.23, 29.73)]; + [bezier19Path addLineToPoint: CGPointMake(40.08, 29.73)]; + [bezier19Path addLineToPoint: CGPointMake(40.34, 28.61)]; + [bezier19Path addLineToPoint: CGPointMake(42.83, 28.61)]; + [bezier19Path addLineToPoint: CGPointMake(42.84, 28.47)]; + [bezier19Path addLineToPoint: CGPointMake(42.84, 28.33)]; + [bezier19Path addLineToPoint: CGPointMake(42.83, 28.21)]; + [bezier19Path addLineToPoint: CGPointMake(42.8, 28.09)]; + [bezier19Path addLineToPoint: CGPointMake(42.76, 27.98)]; + [bezier19Path addLineToPoint: CGPointMake(42.72, 27.89)]; + [bezier19Path addLineToPoint: CGPointMake(42.67, 27.8)]; + [bezier19Path addLineToPoint: CGPointMake(42.61, 27.72)]; + [bezier19Path addLineToPoint: CGPointMake(42.54, 27.65)]; + [bezier19Path addLineToPoint: CGPointMake(42.47, 27.6)]; + [bezier19Path addLineToPoint: CGPointMake(42.38, 27.55)]; + [bezier19Path addLineToPoint: CGPointMake(42.3, 27.5)]; + [bezier19Path addLineToPoint: CGPointMake(42.2, 27.47)]; + [bezier19Path addLineToPoint: CGPointMake(42.11, 27.44)]; + [bezier19Path addLineToPoint: CGPointMake(42.02, 27.43)]; + [bezier19Path addLineToPoint: CGPointMake(41.91, 27.41)]; + [bezier19Path addLineToPoint: CGPointMake(41.81, 27.42)]; + [bezier19Path addLineToPoint: CGPointMake(41.7, 27.44)]; + [bezier19Path addLineToPoint: CGPointMake(41.61, 27.46)]; + [bezier19Path addLineToPoint: CGPointMake(41.51, 27.49)]; + [bezier19Path addLineToPoint: CGPointMake(41.41, 27.54)]; + [bezier19Path addLineToPoint: CGPointMake(41.33, 27.59)]; + [bezier19Path addLineToPoint: CGPointMake(41.24, 27.65)]; + [bezier19Path addLineToPoint: CGPointMake(41.17, 27.72)]; + [bezier19Path addLineToPoint: CGPointMake(41.09, 27.8)]; + [bezier19Path addLineToPoint: CGPointMake(41.03, 27.89)]; + [bezier19Path addLineToPoint: CGPointMake(40.96, 27.98)]; + [bezier19Path addLineToPoint: CGPointMake(40.91, 28.08)]; + [bezier19Path addLineToPoint: CGPointMake(40.86, 28.18)]; + [bezier19Path addLineToPoint: CGPointMake(40.82, 28.29)]; + [bezier19Path addLineToPoint: CGPointMake(40.79, 28.41)]; + [bezier19Path addLineToPoint: CGPointMake(40.76, 28.52)]; + [bezier19Path addLineToPoint: CGPointMake(40.54, 29.7)]; + [bezier19Path addLineToPoint: CGPointMake(40.52, 29.8)]; + [bezier19Path closePath]; + bezier19Path.miterLimit = 4; + + bezier19Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier19Path fill]; + + + //// Bezier 20 Drawing + UIBezierPath* bezier20Path = [UIBezierPath bezierPath]; + [bezier20Path moveToPoint: CGPointMake(40.63, 28.52)]; + [bezier20Path addLineToPoint: CGPointMake(40.54, 29.7)]; + [bezier20Path addLineToPoint: CGPointMake(40.52, 29.8)]; + [bezier20Path addLineToPoint: CGPointMake(40.51, 29.9)]; + [bezier20Path addLineToPoint: CGPointMake(40.53, 30.01)]; + [bezier20Path addLineToPoint: CGPointMake(40.55, 30.12)]; + [bezier20Path addLineToPoint: CGPointMake(40.59, 30.23)]; + [bezier20Path addLineToPoint: CGPointMake(40.63, 30.33)]; + [bezier20Path addLineToPoint: CGPointMake(40.7, 30.44)]; + [bezier20Path addLineToPoint: CGPointMake(40.76, 30.53)]; + [bezier20Path addLineToPoint: CGPointMake(40.84, 30.63)]; + [bezier20Path addLineToPoint: CGPointMake(40.93, 30.72)]; + [bezier20Path addLineToPoint: CGPointMake(41.02, 30.8)]; + [bezier20Path addLineToPoint: CGPointMake(41.12, 30.87)]; + [bezier20Path addLineToPoint: CGPointMake(41.23, 30.93)]; + [bezier20Path addLineToPoint: CGPointMake(41.34, 30.98)]; + [bezier20Path addLineToPoint: CGPointMake(41.45, 31.02)]; + [bezier20Path addLineToPoint: CGPointMake(41.57, 31.05)]; + [bezier20Path addLineToPoint: CGPointMake(41.72, 31.07)]; + [bezier20Path addLineToPoint: CGPointMake(41.86, 31.09)]; + [bezier20Path addLineToPoint: CGPointMake(42.01, 31.1)]; + [bezier20Path addLineToPoint: CGPointMake(42.15, 31.12)]; + [bezier20Path addLineToPoint: CGPointMake(42.3, 31.12)]; + [bezier20Path addLineToPoint: CGPointMake(42.46, 31.12)]; + [bezier20Path addLineToPoint: CGPointMake(42.6, 31.12)]; + [bezier20Path addLineToPoint: CGPointMake(42.76, 31.1)]; + [bezier20Path addLineToPoint: CGPointMake(42.91, 31.08)]; + [bezier20Path addLineToPoint: CGPointMake(43.06, 31.05)]; + [bezier20Path addLineToPoint: CGPointMake(43.22, 31.02)]; + [bezier20Path addLineToPoint: CGPointMake(43.38, 30.97)]; + [bezier20Path addLineToPoint: CGPointMake(43.54, 30.9)]; + [bezier20Path addLineToPoint: CGPointMake(43.7, 30.84)]; + [bezier20Path addLineToPoint: CGPointMake(43.86, 30.75)]; + [bezier20Path addLineToPoint: CGPointMake(44.03, 30.65)]; + [bezier20Path addLineToPoint: CGPointMake(43.8, 32.05)]; + [bezier20Path addLineToPoint: CGPointMake(43.71, 32.09)]; + [bezier20Path addLineToPoint: CGPointMake(43.62, 32.14)]; + [bezier20Path addLineToPoint: CGPointMake(43.53, 32.17)]; + [bezier20Path addLineToPoint: CGPointMake(43.44, 32.21)]; + [bezier20Path addLineToPoint: CGPointMake(43.36, 32.24)]; + [bezier20Path addLineToPoint: CGPointMake(43.26, 32.27)]; + [bezier20Path addLineToPoint: CGPointMake(43.17, 32.29)]; + [bezier20Path addLineToPoint: CGPointMake(43.08, 32.31)]; + [bezier20Path addLineToPoint: CGPointMake(42.97, 32.32)]; + [bezier20Path addLineToPoint: CGPointMake(42.86, 32.33)]; + [bezier20Path addLineToPoint: CGPointMake(42.74, 32.35)]; + [bezier20Path addLineToPoint: CGPointMake(42.61, 32.36)]; + [bezier20Path addLineToPoint: CGPointMake(42.46, 32.36)]; + [bezier20Path addLineToPoint: CGPointMake(42.31, 32.36)]; + [bezier20Path addLineToPoint: CGPointMake(42.13, 32.37)]; + [bezier20Path addLineToPoint: CGPointMake(41.94, 32.37)]; + [bezier20Path addLineToPoint: CGPointMake(41.66, 32.36)]; + [bezier20Path addLineToPoint: CGPointMake(41.38, 32.33)]; + [bezier20Path addLineToPoint: CGPointMake(41.09, 32.29)]; + [bezier20Path addLineToPoint: CGPointMake(40.81, 32.23)]; + [bezier20Path addLineToPoint: CGPointMake(40.53, 32.14)]; + [bezier20Path addLineToPoint: CGPointMake(40.26, 32.03)]; + [bezier20Path addLineToPoint: CGPointMake(40.01, 31.89)]; + [bezier20Path addLineToPoint: CGPointMake(39.77, 31.72)]; + [bezier20Path addLineToPoint: CGPointMake(39.55, 31.53)]; + [bezier20Path addLineToPoint: CGPointMake(39.35, 31.3)]; + [bezier20Path addLineToPoint: CGPointMake(39.19, 31.04)]; + [bezier20Path addLineToPoint: CGPointMake(39.05, 30.73)]; + [bezier20Path addLineToPoint: CGPointMake(38.95, 30.4)]; + [bezier20Path addLineToPoint: CGPointMake(38.89, 30.02)]; + [bezier20Path addLineToPoint: CGPointMake(38.87, 29.6)]; + [bezier20Path addLineToPoint: CGPointMake(38.9, 29.13)]; + [bezier20Path addLineToPoint: CGPointMake(38.93, 28.95)]; + [bezier20Path addLineToPoint: CGPointMake(38.96, 28.74)]; + [bezier20Path addLineToPoint: CGPointMake(39.01, 28.51)]; + [bezier20Path addLineToPoint: CGPointMake(39.07, 28.27)]; + [bezier20Path addLineToPoint: CGPointMake(39.15, 28.03)]; + [bezier20Path addLineToPoint: CGPointMake(39.26, 27.78)]; + [bezier20Path addLineToPoint: CGPointMake(39.39, 27.53)]; + [bezier20Path addLineToPoint: CGPointMake(39.55, 27.3)]; + [bezier20Path addLineToPoint: CGPointMake(39.73, 27.07)]; + [bezier20Path addLineToPoint: CGPointMake(39.95, 26.85)]; + [bezier20Path addLineToPoint: CGPointMake(40.2, 26.66)]; + [bezier20Path addLineToPoint: CGPointMake(40.49, 26.49)]; + [bezier20Path addLineToPoint: CGPointMake(40.82, 26.34)]; + [bezier20Path addLineToPoint: CGPointMake(41.19, 26.24)]; + [bezier20Path addLineToPoint: CGPointMake(41.6, 26.17)]; + [bezier20Path addLineToPoint: CGPointMake(42.06, 26.15)]; + [bezier20Path addLineToPoint: CGPointMake(42.28, 26.16)]; + [bezier20Path addLineToPoint: CGPointMake(42.51, 26.18)]; + [bezier20Path addLineToPoint: CGPointMake(42.75, 26.22)]; + [bezier20Path addLineToPoint: CGPointMake(42.98, 26.28)]; + [bezier20Path addLineToPoint: CGPointMake(43.21, 26.36)]; + [bezier20Path addLineToPoint: CGPointMake(43.43, 26.46)]; + [bezier20Path addLineToPoint: CGPointMake(43.63, 26.6)]; + [bezier20Path addLineToPoint: CGPointMake(43.82, 26.76)]; + [bezier20Path addLineToPoint: CGPointMake(43.99, 26.95)]; + [bezier20Path addLineToPoint: CGPointMake(44.13, 27.18)]; + [bezier20Path addLineToPoint: CGPointMake(44.25, 27.44)]; + [bezier20Path addLineToPoint: CGPointMake(44.33, 27.74)]; + [bezier20Path addLineToPoint: CGPointMake(44.37, 28.09)]; + [bezier20Path addLineToPoint: CGPointMake(44.38, 28.47)]; + [bezier20Path addLineToPoint: CGPointMake(44.34, 28.91)]; + [bezier20Path addLineToPoint: CGPointMake(44.25, 29.38)]; + [bezier20Path addLineToPoint: CGPointMake(44.23, 29.73)]; + [bezier20Path addLineToPoint: CGPointMake(40.14, 29.7)]; + [bezier20Path addLineToPoint: CGPointMake(40.34, 28.61)]; + [bezier20Path addLineToPoint: CGPointMake(42.83, 28.61)]; + [bezier20Path addLineToPoint: CGPointMake(42.84, 28.47)]; + [bezier20Path addLineToPoint: CGPointMake(42.84, 28.33)]; + [bezier20Path addLineToPoint: CGPointMake(42.83, 28.21)]; + [bezier20Path addLineToPoint: CGPointMake(42.8, 28.09)]; + [bezier20Path addLineToPoint: CGPointMake(42.76, 27.98)]; + [bezier20Path addLineToPoint: CGPointMake(42.72, 27.89)]; + [bezier20Path addLineToPoint: CGPointMake(42.67, 27.8)]; + [bezier20Path addLineToPoint: CGPointMake(42.61, 27.72)]; + [bezier20Path addLineToPoint: CGPointMake(42.54, 27.65)]; + [bezier20Path addLineToPoint: CGPointMake(42.47, 27.6)]; + [bezier20Path addLineToPoint: CGPointMake(42.38, 27.55)]; + [bezier20Path addLineToPoint: CGPointMake(42.3, 27.5)]; + [bezier20Path addLineToPoint: CGPointMake(42.2, 27.47)]; + [bezier20Path addLineToPoint: CGPointMake(42.11, 27.44)]; + [bezier20Path addLineToPoint: CGPointMake(42.02, 27.43)]; + [bezier20Path addLineToPoint: CGPointMake(41.91, 27.41)]; + [bezier20Path addLineToPoint: CGPointMake(41.81, 27.42)]; + [bezier20Path addLineToPoint: CGPointMake(41.7, 27.44)]; + [bezier20Path addLineToPoint: CGPointMake(41.61, 27.46)]; + [bezier20Path addLineToPoint: CGPointMake(41.51, 27.49)]; + [bezier20Path addLineToPoint: CGPointMake(41.41, 27.54)]; + [bezier20Path addLineToPoint: CGPointMake(41.33, 27.59)]; + [bezier20Path addLineToPoint: CGPointMake(41.24, 27.65)]; + [bezier20Path addLineToPoint: CGPointMake(41.17, 27.72)]; + [bezier20Path addLineToPoint: CGPointMake(41.09, 27.8)]; + [bezier20Path addLineToPoint: CGPointMake(41.03, 27.89)]; + [bezier20Path addLineToPoint: CGPointMake(40.96, 27.98)]; + [bezier20Path addLineToPoint: CGPointMake(40.91, 28.08)]; + [bezier20Path addLineToPoint: CGPointMake(40.86, 28.18)]; + [bezier20Path addLineToPoint: CGPointMake(40.82, 28.29)]; + [bezier20Path addLineToPoint: CGPointMake(40.79, 28.41)]; + [bezier20Path addLineToPoint: CGPointMake(40.76, 28.52)]; + [bezier20Path addLineToPoint: CGPointMake(40.54, 29.7)]; + bezier20Path.miterLimit = 4; + + bezier20Path.usesEvenOddFillRule = YES; + + [color3 setStroke]; + bezier20Path.lineWidth = 0.5; + [bezier20Path stroke]; + + + //// Bezier 21 Drawing + UIBezierPath* bezier21Path = [UIBezierPath bezierPath]; + [bezier21Path moveToPoint: CGPointMake(39.5, 28.5)]; + [bezier21Path addLineToPoint: CGPointMake(39.5, 30.5)]; + [bezier21Path addLineToPoint: CGPointMake(40.5, 30.5)]; + [bezier21Path addLineToPoint: CGPointMake(40.62, 28.5)]; + [bezier21Path addLineToPoint: CGPointMake(39.5, 28.5)]; + [bezier21Path closePath]; + bezier21Path.miterLimit = 4; + + bezier21Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier21Path fill]; + + + //// Bezier 22 Drawing + UIBezierPath* bezier22Path = [UIBezierPath bezierPath]; + [bezier22Path moveToPoint: CGPointMake(54.12, 26.61)]; + [bezier22Path addLineToPoint: CGPointMake(54.04, 26.57)]; + [bezier22Path addLineToPoint: CGPointMake(53.97, 26.54)]; + [bezier22Path addLineToPoint: CGPointMake(53.89, 26.5)]; + [bezier22Path addLineToPoint: CGPointMake(53.8, 26.46)]; + [bezier22Path addLineToPoint: CGPointMake(53.72, 26.42)]; + [bezier22Path addLineToPoint: CGPointMake(53.52, 26.36)]; + [bezier22Path addLineToPoint: CGPointMake(53.42, 26.32)]; + [bezier22Path addLineToPoint: CGPointMake(53.31, 26.29)]; + [bezier22Path addLineToPoint: CGPointMake(53.2, 26.27)]; + [bezier22Path addLineToPoint: CGPointMake(53.09, 26.25)]; + [bezier22Path addLineToPoint: CGPointMake(52.97, 26.23)]; + [bezier22Path addLineToPoint: CGPointMake(52.83, 26.22)]; + [bezier22Path addLineToPoint: CGPointMake(52.7, 26.21)]; + [bezier22Path addLineToPoint: CGPointMake(52.28, 26.21)]; + [bezier22Path addLineToPoint: CGPointMake(52.13, 26.22)]; + [bezier22Path addLineToPoint: CGPointMake(51.98, 26.24)]; + [bezier22Path addLineToPoint: CGPointMake(51.82, 26.26)]; + [bezier22Path addLineToPoint: CGPointMake(51.66, 26.31)]; + [bezier22Path addLineToPoint: CGPointMake(51.5, 26.37)]; + [bezier22Path addLineToPoint: CGPointMake(51.34, 26.45)]; + [bezier22Path addLineToPoint: CGPointMake(51.18, 26.55)]; + [bezier22Path addLineToPoint: CGPointMake(51.03, 26.68)]; + [bezier22Path addLineToPoint: CGPointMake(50.88, 26.83)]; + [bezier22Path addLineToPoint: CGPointMake(50.74, 27.01)]; + [bezier22Path addLineToPoint: CGPointMake(50.6, 27.22)]; + [bezier22Path addLineToPoint: CGPointMake(50.48, 27.47)]; + [bezier22Path addLineToPoint: CGPointMake(50.36, 27.76)]; + [bezier22Path addLineToPoint: CGPointMake(50.25, 28.08)]; + [bezier22Path addLineToPoint: CGPointMake(50.16, 28.44)]; + [bezier22Path addLineToPoint: CGPointMake(50.12, 28.64)]; + [bezier22Path addLineToPoint: CGPointMake(50.1, 28.84)]; + [bezier22Path addLineToPoint: CGPointMake(50.09, 29.04)]; + [bezier22Path addLineToPoint: CGPointMake(50.1, 29.24)]; + [bezier22Path addLineToPoint: CGPointMake(50.11, 29.43)]; + [bezier22Path addLineToPoint: CGPointMake(50.15, 29.61)]; + [bezier22Path addLineToPoint: CGPointMake(50.2, 29.78)]; + [bezier22Path addLineToPoint: CGPointMake(50.27, 29.95)]; + [bezier22Path addLineToPoint: CGPointMake(50.35, 30.11)]; + [bezier22Path addLineToPoint: CGPointMake(50.45, 30.26)]; + [bezier22Path addLineToPoint: CGPointMake(50.57, 30.39)]; + [bezier22Path addLineToPoint: CGPointMake(50.71, 30.51)]; + [bezier22Path addLineToPoint: CGPointMake(50.86, 30.61)]; + [bezier22Path addLineToPoint: CGPointMake(51.04, 30.69)]; + [bezier22Path addLineToPoint: CGPointMake(51.24, 30.77)]; + [bezier22Path addLineToPoint: CGPointMake(51.45, 30.82)]; + [bezier22Path addLineToPoint: CGPointMake(51.53, 30.84)]; + [bezier22Path addLineToPoint: CGPointMake(51.61, 30.85)]; + [bezier22Path addLineToPoint: CGPointMake(51.71, 30.87)]; + [bezier22Path addLineToPoint: CGPointMake(51.83, 30.88)]; + [bezier22Path addLineToPoint: CGPointMake(51.95, 30.89)]; + [bezier22Path addLineToPoint: CGPointMake(52.23, 30.89)]; + [bezier22Path addLineToPoint: CGPointMake(52.37, 30.88)]; + [bezier22Path addLineToPoint: CGPointMake(52.52, 30.86)]; + [bezier22Path addLineToPoint: CGPointMake(52.66, 30.83)]; + [bezier22Path addLineToPoint: CGPointMake(52.81, 30.79)]; + [bezier22Path addLineToPoint: CGPointMake(52.95, 30.75)]; + [bezier22Path addLineToPoint: CGPointMake(53.09, 30.68)]; + [bezier22Path addLineToPoint: CGPointMake(53.22, 30.61)]; + [bezier22Path addLineToPoint: CGPointMake(53.34, 30.52)]; + [bezier22Path addLineToPoint: CGPointMake(53.46, 30.42)]; + [bezier22Path addLineToPoint: CGPointMake(53.2, 31.94)]; + [bezier22Path addLineToPoint: CGPointMake(53.17, 31.96)]; + [bezier22Path addLineToPoint: CGPointMake(53.13, 32)]; + [bezier22Path addLineToPoint: CGPointMake(53.09, 32.04)]; + [bezier22Path addLineToPoint: CGPointMake(53.03, 32.07)]; + [bezier22Path addLineToPoint: CGPointMake(52.97, 32.12)]; + [bezier22Path addLineToPoint: CGPointMake(52.89, 32.16)]; + [bezier22Path addLineToPoint: CGPointMake(52.8, 32.2)]; + [bezier22Path addLineToPoint: CGPointMake(52.7, 32.23)]; + [bezier22Path addLineToPoint: CGPointMake(52.57, 32.27)]; + [bezier22Path addLineToPoint: CGPointMake(52.42, 32.3)]; + [bezier22Path addLineToPoint: CGPointMake(52.25, 32.32)]; + [bezier22Path addLineToPoint: CGPointMake(52.05, 32.35)]; + [bezier22Path addLineToPoint: CGPointMake(51.83, 32.36)]; + [bezier22Path addLineToPoint: CGPointMake(51.57, 32.36)]; + [bezier22Path addLineToPoint: CGPointMake(51.28, 32.36)]; + [bezier22Path addLineToPoint: CGPointMake(50.96, 32.34)]; + [bezier22Path addLineToPoint: CGPointMake(50.7, 32.31)]; + [bezier22Path addLineToPoint: CGPointMake(50.44, 32.25)]; + [bezier22Path addLineToPoint: CGPointMake(50.18, 32.17)]; + [bezier22Path addLineToPoint: CGPointMake(49.91, 32.05)]; + [bezier22Path addLineToPoint: CGPointMake(49.66, 31.92)]; + [bezier22Path addLineToPoint: CGPointMake(49.42, 31.75)]; + [bezier22Path addLineToPoint: CGPointMake(49.2, 31.55)]; + [bezier22Path addLineToPoint: CGPointMake(48.99, 31.32)]; + [bezier22Path addLineToPoint: CGPointMake(48.8, 31.06)]; + [bezier22Path addLineToPoint: CGPointMake(48.64, 30.78)]; + [bezier22Path addLineToPoint: CGPointMake(48.5, 30.46)]; + [bezier22Path addLineToPoint: CGPointMake(48.4, 30.11)]; + [bezier22Path addLineToPoint: CGPointMake(48.33, 29.73)]; + [bezier22Path addLineToPoint: CGPointMake(48.31, 29.33)]; + [bezier22Path addLineToPoint: CGPointMake(48.32, 28.88)]; + [bezier22Path addLineToPoint: CGPointMake(48.38, 28.41)]; + [bezier22Path addLineToPoint: CGPointMake(48.43, 28.18)]; + [bezier22Path addLineToPoint: CGPointMake(48.48, 27.95)]; + [bezier22Path addLineToPoint: CGPointMake(48.54, 27.73)]; + [bezier22Path addLineToPoint: CGPointMake(48.59, 27.52)]; + [bezier22Path addLineToPoint: CGPointMake(48.66, 27.32)]; + [bezier22Path addLineToPoint: CGPointMake(48.73, 27.12)]; + [bezier22Path addLineToPoint: CGPointMake(48.8, 26.93)]; + [bezier22Path addLineToPoint: CGPointMake(48.88, 26.75)]; + [bezier22Path addLineToPoint: CGPointMake(48.97, 26.58)]; + [bezier22Path addLineToPoint: CGPointMake(49.05, 26.41)]; + [bezier22Path addLineToPoint: CGPointMake(49.15, 26.25)]; + [bezier22Path addLineToPoint: CGPointMake(49.25, 26.11)]; + [bezier22Path addLineToPoint: CGPointMake(49.36, 25.96)]; + [bezier22Path addLineToPoint: CGPointMake(49.47, 25.83)]; + [bezier22Path addLineToPoint: CGPointMake(49.58, 25.7)]; + [bezier22Path addLineToPoint: CGPointMake(49.7, 25.58)]; + [bezier22Path addLineToPoint: CGPointMake(49.83, 25.47)]; + [bezier22Path addLineToPoint: CGPointMake(49.97, 25.36)]; + [bezier22Path addLineToPoint: CGPointMake(50.1, 25.26)]; + [bezier22Path addLineToPoint: CGPointMake(50.24, 25.17)]; + [bezier22Path addLineToPoint: CGPointMake(50.4, 25.09)]; + [bezier22Path addLineToPoint: CGPointMake(50.55, 25.01)]; + [bezier22Path addLineToPoint: CGPointMake(50.71, 24.94)]; + [bezier22Path addLineToPoint: CGPointMake(50.88, 24.88)]; + [bezier22Path addLineToPoint: CGPointMake(51.05, 24.82)]; + [bezier22Path addLineToPoint: CGPointMake(51.23, 24.78)]; + [bezier22Path addLineToPoint: CGPointMake(51.41, 24.74)]; + [bezier22Path addLineToPoint: CGPointMake(51.61, 24.7)]; + [bezier22Path addLineToPoint: CGPointMake(51.8, 24.68)]; + [bezier22Path addLineToPoint: CGPointMake(52, 24.65)]; + [bezier22Path addLineToPoint: CGPointMake(52.21, 24.64)]; + [bezier22Path addLineToPoint: CGPointMake(52.43, 24.64)]; + [bezier22Path addLineToPoint: CGPointMake(52.61, 24.64)]; + [bezier22Path addLineToPoint: CGPointMake(52.78, 24.65)]; + [bezier22Path addLineToPoint: CGPointMake(52.95, 24.67)]; + [bezier22Path addLineToPoint: CGPointMake(53.13, 24.69)]; + [bezier22Path addLineToPoint: CGPointMake(53.28, 24.72)]; + [bezier22Path addLineToPoint: CGPointMake(53.44, 24.75)]; + [bezier22Path addLineToPoint: CGPointMake(53.59, 24.78)]; + [bezier22Path addLineToPoint: CGPointMake(53.72, 24.81)]; + [bezier22Path addLineToPoint: CGPointMake(53.85, 24.85)]; + [bezier22Path addLineToPoint: CGPointMake(53.97, 24.88)]; + [bezier22Path addLineToPoint: CGPointMake(54.08, 24.92)]; + [bezier22Path addLineToPoint: CGPointMake(54.17, 24.95)]; + [bezier22Path addLineToPoint: CGPointMake(54.25, 24.98)]; + [bezier22Path addLineToPoint: CGPointMake(54.31, 25)]; + [bezier22Path addLineToPoint: CGPointMake(54.37, 25.02)]; + [bezier22Path addLineToPoint: CGPointMake(54.4, 25.03)]; + [bezier22Path addLineToPoint: CGPointMake(54.12, 26.61)]; + [bezier22Path closePath]; + bezier22Path.miterLimit = 4; + + bezier22Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier22Path fill]; + + + //// Bezier 23 Drawing + UIBezierPath* bezier23Path = [UIBezierPath bezierPath]; + [bezier23Path moveToPoint: CGPointMake(54.12, 26.61)]; + [bezier23Path addLineToPoint: CGPointMake(54.12, 26.61)]; + [bezier23Path addLineToPoint: CGPointMake(54.04, 26.57)]; + [bezier23Path addLineToPoint: CGPointMake(53.97, 26.54)]; + [bezier23Path addLineToPoint: CGPointMake(53.89, 26.5)]; + [bezier23Path addLineToPoint: CGPointMake(53.8, 26.46)]; + [bezier23Path addLineToPoint: CGPointMake(53.72, 26.42)]; + [bezier23Path addLineToPoint: CGPointMake(53.52, 26.36)]; + [bezier23Path addLineToPoint: CGPointMake(53.42, 26.32)]; + [bezier23Path addLineToPoint: CGPointMake(53.31, 26.29)]; + [bezier23Path addLineToPoint: CGPointMake(53.2, 26.27)]; + [bezier23Path addLineToPoint: CGPointMake(53.09, 26.25)]; + [bezier23Path addLineToPoint: CGPointMake(52.97, 26.23)]; + [bezier23Path addLineToPoint: CGPointMake(52.83, 26.22)]; + [bezier23Path addLineToPoint: CGPointMake(52.7, 26.21)]; + [bezier23Path addLineToPoint: CGPointMake(52.28, 26.21)]; + [bezier23Path addLineToPoint: CGPointMake(52.13, 26.22)]; + [bezier23Path addLineToPoint: CGPointMake(51.98, 26.24)]; + [bezier23Path addLineToPoint: CGPointMake(51.82, 26.26)]; + [bezier23Path addLineToPoint: CGPointMake(51.66, 26.31)]; + [bezier23Path addLineToPoint: CGPointMake(51.5, 26.37)]; + [bezier23Path addLineToPoint: CGPointMake(51.34, 26.45)]; + [bezier23Path addLineToPoint: CGPointMake(51.18, 26.55)]; + [bezier23Path addLineToPoint: CGPointMake(51.03, 26.68)]; + [bezier23Path addLineToPoint: CGPointMake(50.88, 26.83)]; + [bezier23Path addLineToPoint: CGPointMake(50.74, 27.01)]; + [bezier23Path addLineToPoint: CGPointMake(50.6, 27.22)]; + [bezier23Path addLineToPoint: CGPointMake(50.48, 27.47)]; + [bezier23Path addLineToPoint: CGPointMake(50.36, 27.76)]; + [bezier23Path addLineToPoint: CGPointMake(50.25, 28.08)]; + [bezier23Path addLineToPoint: CGPointMake(50.16, 28.44)]; + [bezier23Path addLineToPoint: CGPointMake(50.12, 28.64)]; + [bezier23Path addLineToPoint: CGPointMake(50.1, 28.84)]; + [bezier23Path addLineToPoint: CGPointMake(50.09, 29.04)]; + [bezier23Path addLineToPoint: CGPointMake(50.1, 29.24)]; + [bezier23Path addLineToPoint: CGPointMake(50.11, 29.43)]; + [bezier23Path addLineToPoint: CGPointMake(50.15, 29.61)]; + [bezier23Path addLineToPoint: CGPointMake(50.2, 29.78)]; + [bezier23Path addLineToPoint: CGPointMake(50.27, 29.95)]; + [bezier23Path addLineToPoint: CGPointMake(50.35, 30.11)]; + [bezier23Path addLineToPoint: CGPointMake(50.45, 30.26)]; + [bezier23Path addLineToPoint: CGPointMake(50.57, 30.39)]; + [bezier23Path addLineToPoint: CGPointMake(50.71, 30.51)]; + [bezier23Path addLineToPoint: CGPointMake(50.86, 30.61)]; + [bezier23Path addLineToPoint: CGPointMake(51.04, 30.69)]; + [bezier23Path addLineToPoint: CGPointMake(51.24, 30.77)]; + [bezier23Path addLineToPoint: CGPointMake(51.45, 30.82)]; + [bezier23Path addLineToPoint: CGPointMake(51.53, 30.84)]; + [bezier23Path addLineToPoint: CGPointMake(51.61, 30.85)]; + [bezier23Path addLineToPoint: CGPointMake(51.71, 30.87)]; + [bezier23Path addLineToPoint: CGPointMake(51.83, 30.88)]; + [bezier23Path addLineToPoint: CGPointMake(51.95, 30.89)]; + [bezier23Path addLineToPoint: CGPointMake(52.23, 30.89)]; + [bezier23Path addLineToPoint: CGPointMake(52.37, 30.88)]; + [bezier23Path addLineToPoint: CGPointMake(52.52, 30.86)]; + [bezier23Path addLineToPoint: CGPointMake(52.66, 30.83)]; + [bezier23Path addLineToPoint: CGPointMake(52.81, 30.79)]; + [bezier23Path addLineToPoint: CGPointMake(52.95, 30.75)]; + [bezier23Path addLineToPoint: CGPointMake(53.09, 30.68)]; + [bezier23Path addLineToPoint: CGPointMake(53.22, 30.61)]; + [bezier23Path addLineToPoint: CGPointMake(53.34, 30.52)]; + [bezier23Path addLineToPoint: CGPointMake(53.46, 30.42)]; + [bezier23Path addLineToPoint: CGPointMake(53.2, 31.94)]; + [bezier23Path addLineToPoint: CGPointMake(53.17, 31.96)]; + [bezier23Path addLineToPoint: CGPointMake(53.13, 32)]; + [bezier23Path addLineToPoint: CGPointMake(53.09, 32.04)]; + [bezier23Path addLineToPoint: CGPointMake(53.03, 32.07)]; + [bezier23Path addLineToPoint: CGPointMake(52.97, 32.12)]; + [bezier23Path addLineToPoint: CGPointMake(52.89, 32.16)]; + [bezier23Path addLineToPoint: CGPointMake(52.8, 32.2)]; + [bezier23Path addLineToPoint: CGPointMake(52.7, 32.23)]; + [bezier23Path addLineToPoint: CGPointMake(52.57, 32.27)]; + [bezier23Path addLineToPoint: CGPointMake(52.42, 32.3)]; + [bezier23Path addLineToPoint: CGPointMake(52.25, 32.32)]; + [bezier23Path addLineToPoint: CGPointMake(52.05, 32.35)]; + [bezier23Path addLineToPoint: CGPointMake(51.83, 32.36)]; + [bezier23Path addLineToPoint: CGPointMake(51.57, 32.36)]; + [bezier23Path addLineToPoint: CGPointMake(51.28, 32.36)]; + [bezier23Path addLineToPoint: CGPointMake(50.96, 32.34)]; + [bezier23Path addLineToPoint: CGPointMake(50.7, 32.31)]; + [bezier23Path addLineToPoint: CGPointMake(50.44, 32.25)]; + [bezier23Path addLineToPoint: CGPointMake(50.18, 32.17)]; + [bezier23Path addLineToPoint: CGPointMake(49.91, 32.05)]; + [bezier23Path addLineToPoint: CGPointMake(49.66, 31.92)]; + [bezier23Path addLineToPoint: CGPointMake(49.42, 31.75)]; + [bezier23Path addLineToPoint: CGPointMake(49.2, 31.55)]; + [bezier23Path addLineToPoint: CGPointMake(48.99, 31.32)]; + [bezier23Path addLineToPoint: CGPointMake(48.8, 31.06)]; + [bezier23Path addLineToPoint: CGPointMake(48.64, 30.78)]; + [bezier23Path addLineToPoint: CGPointMake(48.5, 30.46)]; + [bezier23Path addLineToPoint: CGPointMake(48.4, 30.11)]; + [bezier23Path addLineToPoint: CGPointMake(48.33, 29.73)]; + [bezier23Path addLineToPoint: CGPointMake(48.31, 29.33)]; + [bezier23Path addLineToPoint: CGPointMake(48.32, 28.88)]; + [bezier23Path addLineToPoint: CGPointMake(48.38, 28.41)]; + [bezier23Path addLineToPoint: CGPointMake(48.43, 28.18)]; + [bezier23Path addLineToPoint: CGPointMake(48.48, 27.95)]; + [bezier23Path addLineToPoint: CGPointMake(48.54, 27.73)]; + [bezier23Path addLineToPoint: CGPointMake(48.59, 27.52)]; + [bezier23Path addLineToPoint: CGPointMake(48.66, 27.32)]; + [bezier23Path addLineToPoint: CGPointMake(48.73, 27.12)]; + [bezier23Path addLineToPoint: CGPointMake(48.8, 26.93)]; + [bezier23Path addLineToPoint: CGPointMake(48.88, 26.75)]; + [bezier23Path addLineToPoint: CGPointMake(48.97, 26.58)]; + [bezier23Path addLineToPoint: CGPointMake(49.05, 26.41)]; + [bezier23Path addLineToPoint: CGPointMake(49.15, 26.25)]; + [bezier23Path addLineToPoint: CGPointMake(49.25, 26.11)]; + [bezier23Path addLineToPoint: CGPointMake(49.36, 25.96)]; + [bezier23Path addLineToPoint: CGPointMake(49.47, 25.83)]; + [bezier23Path addLineToPoint: CGPointMake(49.58, 25.7)]; + [bezier23Path addLineToPoint: CGPointMake(49.7, 25.58)]; + [bezier23Path addLineToPoint: CGPointMake(49.83, 25.47)]; + [bezier23Path addLineToPoint: CGPointMake(49.97, 25.36)]; + [bezier23Path addLineToPoint: CGPointMake(50.1, 25.26)]; + [bezier23Path addLineToPoint: CGPointMake(50.24, 25.17)]; + [bezier23Path addLineToPoint: CGPointMake(50.4, 25.09)]; + [bezier23Path addLineToPoint: CGPointMake(50.55, 25.01)]; + [bezier23Path addLineToPoint: CGPointMake(50.71, 24.94)]; + [bezier23Path addLineToPoint: CGPointMake(50.88, 24.88)]; + [bezier23Path addLineToPoint: CGPointMake(51.05, 24.82)]; + [bezier23Path addLineToPoint: CGPointMake(51.23, 24.78)]; + [bezier23Path addLineToPoint: CGPointMake(51.41, 24.74)]; + [bezier23Path addLineToPoint: CGPointMake(51.61, 24.7)]; + [bezier23Path addLineToPoint: CGPointMake(51.8, 24.68)]; + [bezier23Path addLineToPoint: CGPointMake(52, 24.65)]; + [bezier23Path addLineToPoint: CGPointMake(52.21, 24.64)]; + [bezier23Path addLineToPoint: CGPointMake(52.43, 24.64)]; + [bezier23Path addLineToPoint: CGPointMake(52.61, 24.64)]; + [bezier23Path addLineToPoint: CGPointMake(52.78, 24.65)]; + [bezier23Path addLineToPoint: CGPointMake(52.95, 24.67)]; + [bezier23Path addLineToPoint: CGPointMake(53.13, 24.69)]; + [bezier23Path addLineToPoint: CGPointMake(53.28, 24.72)]; + [bezier23Path addLineToPoint: CGPointMake(53.44, 24.75)]; + [bezier23Path addLineToPoint: CGPointMake(53.59, 24.78)]; + [bezier23Path addLineToPoint: CGPointMake(53.72, 24.81)]; + [bezier23Path addLineToPoint: CGPointMake(53.85, 24.85)]; + [bezier23Path addLineToPoint: CGPointMake(53.97, 24.88)]; + [bezier23Path addLineToPoint: CGPointMake(54.08, 24.92)]; + [bezier23Path addLineToPoint: CGPointMake(54.17, 24.95)]; + [bezier23Path addLineToPoint: CGPointMake(54.25, 24.98)]; + [bezier23Path addLineToPoint: CGPointMake(54.31, 25)]; + [bezier23Path addLineToPoint: CGPointMake(54.37, 25.02)]; + [bezier23Path addLineToPoint: CGPointMake(54.4, 25.03)]; + [bezier23Path addLineToPoint: CGPointMake(54.12, 26.61)]; + [bezier23Path closePath]; + bezier23Path.miterLimit = 4; + + bezier23Path.usesEvenOddFillRule = YES; + + [color3 setStroke]; + bezier23Path.lineWidth = 0.5; + [bezier23Path stroke]; + + + //// Bezier 24 Drawing + UIBezierPath* bezier24Path = [UIBezierPath bezierPath]; + [bezier24Path moveToPoint: CGPointMake(68.13, 32.37)]; + [bezier24Path addLineToPoint: CGPointMake(66.56, 32.37)]; + [bezier24Path addLineToPoint: CGPointMake(66.67, 31.74)]; + [bezier24Path addLineToPoint: CGPointMake(66.67, 31.68)]; + [bezier24Path addLineToPoint: CGPointMake(66.58, 31.79)]; + [bezier24Path addLineToPoint: CGPointMake(66.48, 31.9)]; + [bezier24Path addLineToPoint: CGPointMake(66.39, 31.99)]; + [bezier24Path addLineToPoint: CGPointMake(66.28, 32.07)]; + [bezier24Path addLineToPoint: CGPointMake(66.18, 32.14)]; + [bezier24Path addLineToPoint: CGPointMake(66.08, 32.2)]; + [bezier24Path addLineToPoint: CGPointMake(65.98, 32.25)]; + [bezier24Path addLineToPoint: CGPointMake(65.87, 32.31)]; + [bezier24Path addLineToPoint: CGPointMake(65.76, 32.35)]; + [bezier24Path addLineToPoint: CGPointMake(65.65, 32.37)]; + [bezier24Path addLineToPoint: CGPointMake(65.54, 32.4)]; + [bezier24Path addLineToPoint: CGPointMake(65.43, 32.42)]; + [bezier24Path addLineToPoint: CGPointMake(65.32, 32.44)]; + [bezier24Path addLineToPoint: CGPointMake(65.21, 32.45)]; + [bezier24Path addLineToPoint: CGPointMake(65.09, 32.45)]; + [bezier24Path addLineToPoint: CGPointMake(64.98, 32.45)]; + [bezier24Path addLineToPoint: CGPointMake(64.68, 32.43)]; + [bezier24Path addLineToPoint: CGPointMake(64.41, 32.37)]; + [bezier24Path addLineToPoint: CGPointMake(64.16, 32.27)]; + [bezier24Path addLineToPoint: CGPointMake(63.93, 32.14)]; + [bezier24Path addLineToPoint: CGPointMake(63.73, 31.98)]; + [bezier24Path addLineToPoint: CGPointMake(63.54, 31.78)]; + [bezier24Path addLineToPoint: CGPointMake(63.38, 31.57)]; + [bezier24Path addLineToPoint: CGPointMake(63.25, 31.33)]; + [bezier24Path addLineToPoint: CGPointMake(63.13, 31.08)]; + [bezier24Path addLineToPoint: CGPointMake(63.04, 30.81)]; + [bezier24Path addLineToPoint: CGPointMake(62.98, 30.53)]; + [bezier24Path addLineToPoint: CGPointMake(62.94, 30.24)]; + [bezier24Path addLineToPoint: CGPointMake(62.92, 29.95)]; + [bezier24Path addLineToPoint: CGPointMake(62.92, 29.65)]; + [bezier24Path addLineToPoint: CGPointMake(62.95, 29.36)]; + [bezier24Path addLineToPoint: CGPointMake(63, 29.07)]; + [bezier24Path addLineToPoint: CGPointMake(63.09, 28.74)]; + [bezier24Path addLineToPoint: CGPointMake(63.19, 28.42)]; + [bezier24Path addLineToPoint: CGPointMake(63.31, 28.13)]; + [bezier24Path addLineToPoint: CGPointMake(63.45, 27.85)]; + [bezier24Path addLineToPoint: CGPointMake(63.6, 27.6)]; + [bezier24Path addLineToPoint: CGPointMake(63.77, 27.37)]; + [bezier24Path addLineToPoint: CGPointMake(63.95, 27.16)]; + [bezier24Path addLineToPoint: CGPointMake(64.14, 26.98)]; + [bezier24Path addLineToPoint: CGPointMake(64.34, 26.81)]; + [bezier24Path addLineToPoint: CGPointMake(64.55, 26.67)]; + [bezier24Path addLineToPoint: CGPointMake(64.76, 26.54)]; + [bezier24Path addLineToPoint: CGPointMake(64.98, 26.45)]; + [bezier24Path addLineToPoint: CGPointMake(65.21, 26.37)]; + [bezier24Path addLineToPoint: CGPointMake(65.43, 26.32)]; + [bezier24Path addLineToPoint: CGPointMake(65.66, 26.28)]; + [bezier24Path addLineToPoint: CGPointMake(65.9, 26.27)]; + [bezier24Path addLineToPoint: CGPointMake(66.06, 26.28)]; + [bezier24Path addLineToPoint: CGPointMake(66.22, 26.29)]; + [bezier24Path addLineToPoint: CGPointMake(66.37, 26.32)]; + [bezier24Path addLineToPoint: CGPointMake(66.51, 26.36)]; + [bezier24Path addLineToPoint: CGPointMake(66.64, 26.41)]; + [bezier24Path addLineToPoint: CGPointMake(66.75, 26.46)]; + [bezier24Path addLineToPoint: CGPointMake(66.86, 26.52)]; + [bezier24Path addLineToPoint: CGPointMake(66.97, 26.58)]; + [bezier24Path addLineToPoint: CGPointMake(67.06, 26.65)]; + [bezier24Path addLineToPoint: CGPointMake(67.14, 26.73)]; + [bezier24Path addLineToPoint: CGPointMake(67.22, 26.8)]; + [bezier24Path addLineToPoint: CGPointMake(67.29, 26.87)]; + [bezier24Path addLineToPoint: CGPointMake(67.34, 26.95)]; + [bezier24Path addLineToPoint: CGPointMake(67.39, 27.02)]; + [bezier24Path addLineToPoint: CGPointMake(67.44, 27.09)]; + [bezier24Path addLineToPoint: CGPointMake(67.47, 27.16)]; + [bezier24Path addLineToPoint: CGPointMake(67.87, 24.92)]; + [bezier24Path addLineToPoint: CGPointMake(69.42, 24.92)]; + [bezier24Path addLineToPoint: CGPointMake(68.13, 32.37)]; + [bezier24Path closePath]; + bezier24Path.miterLimit = 4; + + bezier24Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier24Path fill]; + + + //// Bezier 25 Drawing + UIBezierPath* bezier25Path = [UIBezierPath bezierPath]; + [bezier25Path moveToPoint: CGPointMake(68.13, 32.37)]; + [bezier25Path addLineToPoint: CGPointMake(66.56, 32.37)]; + [bezier25Path addLineToPoint: CGPointMake(66.67, 31.74)]; + [bezier25Path addLineToPoint: CGPointMake(66.67, 31.68)]; + [bezier25Path addLineToPoint: CGPointMake(66.58, 31.79)]; + [bezier25Path addLineToPoint: CGPointMake(66.48, 31.9)]; + [bezier25Path addLineToPoint: CGPointMake(66.39, 31.99)]; + [bezier25Path addLineToPoint: CGPointMake(66.28, 32.07)]; + [bezier25Path addLineToPoint: CGPointMake(66.18, 32.14)]; + [bezier25Path addLineToPoint: CGPointMake(66.08, 32.2)]; + [bezier25Path addLineToPoint: CGPointMake(65.98, 32.25)]; + [bezier25Path addLineToPoint: CGPointMake(65.87, 32.31)]; + [bezier25Path addLineToPoint: CGPointMake(65.76, 32.35)]; + [bezier25Path addLineToPoint: CGPointMake(65.65, 32.37)]; + [bezier25Path addLineToPoint: CGPointMake(65.54, 32.4)]; + [bezier25Path addLineToPoint: CGPointMake(65.43, 32.42)]; + [bezier25Path addLineToPoint: CGPointMake(65.32, 32.44)]; + [bezier25Path addLineToPoint: CGPointMake(65.21, 32.45)]; + [bezier25Path addLineToPoint: CGPointMake(65.09, 32.45)]; + [bezier25Path addLineToPoint: CGPointMake(64.98, 32.45)]; + [bezier25Path addLineToPoint: CGPointMake(64.68, 32.43)]; + [bezier25Path addLineToPoint: CGPointMake(64.41, 32.37)]; + [bezier25Path addLineToPoint: CGPointMake(64.16, 32.27)]; + [bezier25Path addLineToPoint: CGPointMake(63.93, 32.14)]; + [bezier25Path addLineToPoint: CGPointMake(63.73, 31.98)]; + [bezier25Path addLineToPoint: CGPointMake(63.54, 31.78)]; + [bezier25Path addLineToPoint: CGPointMake(63.38, 31.57)]; + [bezier25Path addLineToPoint: CGPointMake(63.25, 31.33)]; + [bezier25Path addLineToPoint: CGPointMake(63.13, 31.08)]; + [bezier25Path addLineToPoint: CGPointMake(63.04, 30.81)]; + [bezier25Path addLineToPoint: CGPointMake(62.98, 30.53)]; + [bezier25Path addLineToPoint: CGPointMake(62.94, 30.24)]; + [bezier25Path addLineToPoint: CGPointMake(62.92, 29.95)]; + [bezier25Path addLineToPoint: CGPointMake(62.92, 29.65)]; + [bezier25Path addLineToPoint: CGPointMake(62.95, 29.36)]; + [bezier25Path addLineToPoint: CGPointMake(63, 29.07)]; + [bezier25Path addLineToPoint: CGPointMake(63.09, 28.74)]; + [bezier25Path addLineToPoint: CGPointMake(63.19, 28.42)]; + [bezier25Path addLineToPoint: CGPointMake(63.31, 28.13)]; + [bezier25Path addLineToPoint: CGPointMake(63.45, 27.85)]; + [bezier25Path addLineToPoint: CGPointMake(63.6, 27.6)]; + [bezier25Path addLineToPoint: CGPointMake(63.77, 27.37)]; + [bezier25Path addLineToPoint: CGPointMake(63.95, 27.16)]; + [bezier25Path addLineToPoint: CGPointMake(64.14, 26.98)]; + [bezier25Path addLineToPoint: CGPointMake(64.34, 26.81)]; + [bezier25Path addLineToPoint: CGPointMake(64.55, 26.67)]; + [bezier25Path addLineToPoint: CGPointMake(64.76, 26.54)]; + [bezier25Path addLineToPoint: CGPointMake(64.98, 26.45)]; + [bezier25Path addLineToPoint: CGPointMake(65.21, 26.37)]; + [bezier25Path addLineToPoint: CGPointMake(65.43, 26.32)]; + [bezier25Path addLineToPoint: CGPointMake(65.66, 26.28)]; + [bezier25Path addLineToPoint: CGPointMake(65.9, 26.27)]; + [bezier25Path addLineToPoint: CGPointMake(66.06, 26.28)]; + [bezier25Path addLineToPoint: CGPointMake(66.22, 26.29)]; + [bezier25Path addLineToPoint: CGPointMake(66.37, 26.32)]; + [bezier25Path addLineToPoint: CGPointMake(66.51, 26.36)]; + [bezier25Path addLineToPoint: CGPointMake(66.64, 26.41)]; + [bezier25Path addLineToPoint: CGPointMake(66.75, 26.46)]; + [bezier25Path addLineToPoint: CGPointMake(66.86, 26.52)]; + [bezier25Path addLineToPoint: CGPointMake(66.97, 26.58)]; + [bezier25Path addLineToPoint: CGPointMake(67.06, 26.65)]; + [bezier25Path addLineToPoint: CGPointMake(67.14, 26.73)]; + [bezier25Path addLineToPoint: CGPointMake(67.22, 26.8)]; + [bezier25Path addLineToPoint: CGPointMake(67.29, 26.87)]; + [bezier25Path addLineToPoint: CGPointMake(67.34, 26.95)]; + [bezier25Path addLineToPoint: CGPointMake(67.39, 27.02)]; + [bezier25Path addLineToPoint: CGPointMake(67.44, 27.09)]; + [bezier25Path addLineToPoint: CGPointMake(67.47, 27.16)]; + [bezier25Path addLineToPoint: CGPointMake(67.87, 24.92)]; + [bezier25Path addLineToPoint: CGPointMake(69.42, 24.92)]; + [bezier25Path addLineToPoint: CGPointMake(68.13, 32.37)]; + [bezier25Path closePath]; + bezier25Path.miterLimit = 4; + + bezier25Path.usesEvenOddFillRule = YES; + + [color3 setStroke]; + bezier25Path.lineWidth = 0.5; + [bezier25Path stroke]; + + + //// Bezier 26 Drawing + UIBezierPath* bezier26Path = [UIBezierPath bezierPath]; + [bezier26Path moveToPoint: CGPointMake(65.55, 30.99)]; + [bezier26Path addLineToPoint: CGPointMake(65.71, 30.98)]; + [bezier26Path addLineToPoint: CGPointMake(65.86, 30.94)]; + [bezier26Path addLineToPoint: CGPointMake(66, 30.9)]; + [bezier26Path addLineToPoint: CGPointMake(66.13, 30.84)]; + [bezier26Path addLineToPoint: CGPointMake(66.25, 30.77)]; + [bezier26Path addLineToPoint: CGPointMake(66.36, 30.69)]; + [bezier26Path addLineToPoint: CGPointMake(66.47, 30.59)]; + [bezier26Path addLineToPoint: CGPointMake(66.57, 30.49)]; + [bezier26Path addLineToPoint: CGPointMake(66.65, 30.38)]; + [bezier26Path addLineToPoint: CGPointMake(66.73, 30.25)]; + [bezier26Path addLineToPoint: CGPointMake(66.81, 30.12)]; + [bezier26Path addLineToPoint: CGPointMake(66.87, 29.98)]; + [bezier26Path addLineToPoint: CGPointMake(66.93, 29.84)]; + [bezier26Path addLineToPoint: CGPointMake(66.97, 29.69)]; + [bezier26Path addLineToPoint: CGPointMake(67.01, 29.54)]; + [bezier26Path addLineToPoint: CGPointMake(67.04, 29.38)]; + [bezier26Path addLineToPoint: CGPointMake(67.07, 29.23)]; + [bezier26Path addLineToPoint: CGPointMake(67.09, 29.06)]; + [bezier26Path addLineToPoint: CGPointMake(67.09, 28.91)]; + [bezier26Path addLineToPoint: CGPointMake(67.08, 28.75)]; + [bezier26Path addLineToPoint: CGPointMake(67.06, 28.6)]; + [bezier26Path addLineToPoint: CGPointMake(67.04, 28.46)]; + [bezier26Path addLineToPoint: CGPointMake(67, 28.32)]; + [bezier26Path addLineToPoint: CGPointMake(66.95, 28.19)]; + [bezier26Path addLineToPoint: CGPointMake(66.9, 28.08)]; + [bezier26Path addLineToPoint: CGPointMake(66.83, 27.97)]; + [bezier26Path addLineToPoint: CGPointMake(66.76, 27.88)]; + [bezier26Path addLineToPoint: CGPointMake(66.67, 27.8)]; + [bezier26Path addLineToPoint: CGPointMake(66.57, 27.73)]; + [bezier26Path addLineToPoint: CGPointMake(66.47, 27.68)]; + [bezier26Path addLineToPoint: CGPointMake(66.36, 27.65)]; + [bezier26Path addLineToPoint: CGPointMake(66.24, 27.64)]; + [bezier26Path addLineToPoint: CGPointMake(66.09, 27.65)]; + [bezier26Path addLineToPoint: CGPointMake(65.95, 27.68)]; + [bezier26Path addLineToPoint: CGPointMake(65.82, 27.72)]; + [bezier26Path addLineToPoint: CGPointMake(65.69, 27.78)]; + [bezier26Path addLineToPoint: CGPointMake(65.57, 27.85)]; + [bezier26Path addLineToPoint: CGPointMake(65.46, 27.94)]; + [bezier26Path addLineToPoint: CGPointMake(65.36, 28.04)]; + [bezier26Path addLineToPoint: CGPointMake(65.26, 28.15)]; + [bezier26Path addLineToPoint: CGPointMake(65.18, 28.27)]; + [bezier26Path addLineToPoint: CGPointMake(65.1, 28.41)]; + [bezier26Path addLineToPoint: CGPointMake(65.02, 28.54)]; + [bezier26Path addLineToPoint: CGPointMake(64.96, 28.69)]; + [bezier26Path addLineToPoint: CGPointMake(64.91, 28.84)]; + [bezier26Path addLineToPoint: CGPointMake(64.86, 29)]; + [bezier26Path addLineToPoint: CGPointMake(64.81, 29.16)]; + [bezier26Path addLineToPoint: CGPointMake(64.78, 29.33)]; + [bezier26Path addLineToPoint: CGPointMake(64.75, 29.58)]; + [bezier26Path addLineToPoint: CGPointMake(64.76, 29.85)]; + [bezier26Path addLineToPoint: CGPointMake(64.8, 30.13)]; + [bezier26Path addLineToPoint: CGPointMake(64.88, 30.4)]; + [bezier26Path addLineToPoint: CGPointMake(64.99, 30.63)]; + [bezier26Path addLineToPoint: CGPointMake(65.14, 30.82)]; + [bezier26Path addLineToPoint: CGPointMake(65.33, 30.94)]; + [bezier26Path addLineToPoint: CGPointMake(65.55, 30.99)]; + [bezier26Path closePath]; + bezier26Path.miterLimit = 4; + + bezier26Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier26Path fill]; + + + //// Bezier 27 Drawing + UIBezierPath* bezier27Path = [UIBezierPath bezierPath]; + [bezier27Path moveToPoint: CGPointMake(30.59, 31.1)]; + [bezier27Path addLineToPoint: CGPointMake(30.36, 32.37)]; + [bezier27Path addLineToPoint: CGPointMake(28.93, 32.37)]; + [bezier27Path addLineToPoint: CGPointMake(28.97, 32.13)]; + [bezier27Path addLineToPoint: CGPointMake(29, 31.92)]; + [bezier27Path addLineToPoint: CGPointMake(29.02, 31.76)]; + [bezier27Path addLineToPoint: CGPointMake(29.04, 31.68)]; + [bezier27Path addLineToPoint: CGPointMake(28.96, 31.77)]; + [bezier27Path addLineToPoint: CGPointMake(28.87, 31.86)]; + [bezier27Path addLineToPoint: CGPointMake(28.76, 31.95)]; + [bezier27Path addLineToPoint: CGPointMake(28.64, 32.03)]; + [bezier27Path addLineToPoint: CGPointMake(28.51, 32.11)]; + [bezier27Path addLineToPoint: CGPointMake(28.36, 32.17)]; + [bezier27Path addLineToPoint: CGPointMake(28.22, 32.24)]; + [bezier27Path addLineToPoint: CGPointMake(28.06, 32.3)]; + [bezier27Path addLineToPoint: CGPointMake(27.9, 32.35)]; + [bezier27Path addLineToPoint: CGPointMake(27.73, 32.39)]; + [bezier27Path addLineToPoint: CGPointMake(27.57, 32.43)]; + [bezier27Path addLineToPoint: CGPointMake(27.4, 32.45)]; + [bezier27Path addLineToPoint: CGPointMake(27.23, 32.46)]; + [bezier27Path addLineToPoint: CGPointMake(27.07, 32.46)]; + [bezier27Path addLineToPoint: CGPointMake(26.91, 32.45)]; + [bezier27Path addLineToPoint: CGPointMake(26.75, 32.43)]; + [bezier27Path addLineToPoint: CGPointMake(26.55, 32.37)]; + [bezier27Path addLineToPoint: CGPointMake(26.37, 32.32)]; + [bezier27Path addLineToPoint: CGPointMake(26.21, 32.24)]; + [bezier27Path addLineToPoint: CGPointMake(26.07, 32.16)]; + [bezier27Path addLineToPoint: CGPointMake(25.94, 32.07)]; + [bezier27Path addLineToPoint: CGPointMake(25.83, 31.96)]; + [bezier27Path addLineToPoint: CGPointMake(25.74, 31.86)]; + [bezier27Path addLineToPoint: CGPointMake(25.66, 31.74)]; + [bezier27Path addLineToPoint: CGPointMake(25.59, 31.62)]; + [bezier27Path addLineToPoint: CGPointMake(25.53, 31.5)]; + [bezier27Path addLineToPoint: CGPointMake(25.49, 31.37)]; + [bezier27Path addLineToPoint: CGPointMake(25.45, 31.25)]; + [bezier27Path addLineToPoint: CGPointMake(25.43, 31.12)]; + [bezier27Path addLineToPoint: CGPointMake(25.41, 30.98)]; + [bezier27Path addLineToPoint: CGPointMake(25.4, 30.86)]; + [bezier27Path addLineToPoint: CGPointMake(25.4, 30.73)]; + [bezier27Path addLineToPoint: CGPointMake(25.42, 30.51)]; + [bezier27Path addLineToPoint: CGPointMake(25.45, 30.3)]; + [bezier27Path addLineToPoint: CGPointMake(25.51, 30.1)]; + [bezier27Path addLineToPoint: CGPointMake(25.59, 29.91)]; + [bezier27Path addLineToPoint: CGPointMake(25.68, 29.73)]; + [bezier27Path addLineToPoint: CGPointMake(25.78, 29.56)]; + [bezier27Path addLineToPoint: CGPointMake(25.9, 29.4)]; + [bezier27Path addLineToPoint: CGPointMake(26.04, 29.26)]; + [bezier27Path addLineToPoint: CGPointMake(26.18, 29.13)]; + [bezier27Path addLineToPoint: CGPointMake(26.34, 29.01)]; + [bezier27Path addLineToPoint: CGPointMake(26.5, 28.9)]; + [bezier27Path addLineToPoint: CGPointMake(26.67, 28.81)]; + [bezier27Path addLineToPoint: CGPointMake(26.85, 28.73)]; + [bezier27Path addLineToPoint: CGPointMake(27.04, 28.67)]; + [bezier27Path addLineToPoint: CGPointMake(27.24, 28.62)]; + [bezier27Path addLineToPoint: CGPointMake(27.44, 28.58)]; + [bezier27Path addLineToPoint: CGPointMake(27.45, 28.58)]; + [bezier27Path addLineToPoint: CGPointMake(27.48, 28.58)]; + [bezier27Path addLineToPoint: CGPointMake(27.52, 28.57)]; + [bezier27Path addLineToPoint: CGPointMake(27.58, 28.56)]; + [bezier27Path addLineToPoint: CGPointMake(27.65, 28.55)]; + [bezier27Path addLineToPoint: CGPointMake(27.73, 28.55)]; + [bezier27Path addLineToPoint: CGPointMake(27.81, 28.54)]; + [bezier27Path addLineToPoint: CGPointMake(27.91, 28.52)]; + [bezier27Path addLineToPoint: CGPointMake(28.01, 28.51)]; + [bezier27Path addLineToPoint: CGPointMake(28.1, 28.5)]; + [bezier27Path addLineToPoint: CGPointMake(28.2, 28.5)]; + [bezier27Path addLineToPoint: CGPointMake(28.3, 28.49)]; + [bezier27Path addLineToPoint: CGPointMake(28.39, 28.48)]; + [bezier27Path addLineToPoint: CGPointMake(28.47, 28.47)]; + [bezier27Path addLineToPoint: CGPointMake(28.55, 28.47)]; + [bezier27Path addLineToPoint: CGPointMake(28.75, 28.47)]; + [bezier27Path addLineToPoint: CGPointMake(28.88, 28.47)]; + [bezier27Path addLineToPoint: CGPointMake(29.01, 28.48)]; + [bezier27Path addLineToPoint: CGPointMake(29.13, 28.48)]; + [bezier27Path addLineToPoint: CGPointMake(29.23, 28.49)]; + [bezier27Path addLineToPoint: CGPointMake(29.31, 28.49)]; + [bezier27Path addLineToPoint: CGPointMake(29.37, 28.5)]; + [bezier27Path addLineToPoint: CGPointMake(29.39, 28.5)]; + [bezier27Path addLineToPoint: CGPointMake(29.4, 28.46)]; + [bezier27Path addLineToPoint: CGPointMake(29.43, 28.35)]; + [bezier27Path addLineToPoint: CGPointMake(29.46, 28.23)]; + [bezier27Path addLineToPoint: CGPointMake(29.47, 28.13)]; + [bezier27Path addLineToPoint: CGPointMake(29.45, 28)]; + [bezier27Path addLineToPoint: CGPointMake(29.4, 27.89)]; + [bezier27Path addLineToPoint: CGPointMake(29.33, 27.78)]; + [bezier27Path addLineToPoint: CGPointMake(29.24, 27.7)]; + [bezier27Path addLineToPoint: CGPointMake(29.13, 27.63)]; + [bezier27Path addLineToPoint: CGPointMake(29.01, 27.57)]; + [bezier27Path addLineToPoint: CGPointMake(28.88, 27.54)]; + [bezier27Path addLineToPoint: CGPointMake(28.73, 27.53)]; + [bezier27Path addLineToPoint: CGPointMake(28.57, 27.52)]; + [bezier27Path addLineToPoint: CGPointMake(28.4, 27.52)]; + [bezier27Path addLineToPoint: CGPointMake(28.22, 27.52)]; + [bezier27Path addLineToPoint: CGPointMake(28.04, 27.52)]; + [bezier27Path addLineToPoint: CGPointMake(27.85, 27.53)]; + [bezier27Path addLineToPoint: CGPointMake(27.67, 27.55)]; + [bezier27Path addLineToPoint: CGPointMake(27.49, 27.57)]; + [bezier27Path addLineToPoint: CGPointMake(27.31, 27.59)]; + [bezier27Path addLineToPoint: CGPointMake(27.14, 27.61)]; + [bezier27Path addLineToPoint: CGPointMake(26.97, 27.64)]; + [bezier27Path addLineToPoint: CGPointMake(26.83, 27.67)]; + [bezier27Path addLineToPoint: CGPointMake(26.69, 27.7)]; + [bezier27Path addLineToPoint: CGPointMake(26.56, 27.73)]; + [bezier27Path addLineToPoint: CGPointMake(26.46, 27.77)]; + [bezier27Path addLineToPoint: CGPointMake(26.38, 27.81)]; + [bezier27Path addLineToPoint: CGPointMake(26.32, 27.84)]; + [bezier27Path addLineToPoint: CGPointMake(26.72, 26.47)]; + [bezier27Path addLineToPoint: CGPointMake(26.85, 26.42)]; + [bezier27Path addLineToPoint: CGPointMake(26.97, 26.37)]; + [bezier27Path addLineToPoint: CGPointMake(27.11, 26.33)]; + [bezier27Path addLineToPoint: CGPointMake(27.25, 26.3)]; + [bezier27Path addLineToPoint: CGPointMake(27.38, 26.28)]; + [bezier27Path addLineToPoint: CGPointMake(27.53, 26.25)]; + [bezier27Path addLineToPoint: CGPointMake(27.68, 26.23)]; + [bezier27Path addLineToPoint: CGPointMake(27.83, 26.22)]; + [bezier27Path addLineToPoint: CGPointMake(27.99, 26.21)]; + [bezier27Path addLineToPoint: CGPointMake(28.16, 26.2)]; + [bezier27Path addLineToPoint: CGPointMake(28.33, 26.2)]; + [bezier27Path addLineToPoint: CGPointMake(28.88, 26.2)]; + [bezier27Path addLineToPoint: CGPointMake(29.08, 26.2)]; + [bezier27Path addLineToPoint: CGPointMake(29.27, 26.21)]; + [bezier27Path addLineToPoint: CGPointMake(29.43, 26.22)]; + [bezier27Path addLineToPoint: CGPointMake(29.61, 26.25)]; + [bezier27Path addLineToPoint: CGPointMake(29.78, 26.29)]; + [bezier27Path addLineToPoint: CGPointMake(29.96, 26.34)]; + [bezier27Path addLineToPoint: CGPointMake(30.14, 26.41)]; + [bezier27Path addLineToPoint: CGPointMake(30.31, 26.49)]; + [bezier27Path addLineToPoint: CGPointMake(30.48, 26.58)]; + [bezier27Path addLineToPoint: CGPointMake(30.64, 26.69)]; + [bezier27Path addLineToPoint: CGPointMake(30.78, 26.82)]; + [bezier27Path addLineToPoint: CGPointMake(30.91, 26.95)]; + [bezier27Path addLineToPoint: CGPointMake(31.02, 27.11)]; + [bezier27Path addLineToPoint: CGPointMake(31.11, 27.28)]; + [bezier27Path addLineToPoint: CGPointMake(31.16, 27.46)]; + [bezier27Path addLineToPoint: CGPointMake(31.2, 27.65)]; + [bezier27Path addLineToPoint: CGPointMake(31.2, 27.87)]; + [bezier27Path addLineToPoint: CGPointMake(31.16, 28.1)]; + [bezier27Path addLineToPoint: CGPointMake(30.59, 31.1)]; + [bezier27Path closePath]; + bezier27Path.miterLimit = 4; + + bezier27Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier27Path fill]; + + + //// Bezier 28 Drawing + UIBezierPath* bezier28Path = [UIBezierPath bezierPath]; + [bezier28Path moveToPoint: CGPointMake(30.59, 31.1)]; + [bezier28Path addLineToPoint: CGPointMake(30.36, 32.37)]; + [bezier28Path addLineToPoint: CGPointMake(28.93, 32.37)]; + [bezier28Path addLineToPoint: CGPointMake(28.97, 32.13)]; + [bezier28Path addLineToPoint: CGPointMake(29, 31.92)]; + [bezier28Path addLineToPoint: CGPointMake(29.02, 31.76)]; + [bezier28Path addLineToPoint: CGPointMake(29.04, 31.68)]; + [bezier28Path addLineToPoint: CGPointMake(28.96, 31.77)]; + [bezier28Path addLineToPoint: CGPointMake(28.87, 31.86)]; + [bezier28Path addLineToPoint: CGPointMake(28.76, 31.95)]; + [bezier28Path addLineToPoint: CGPointMake(28.64, 32.03)]; + [bezier28Path addLineToPoint: CGPointMake(28.51, 32.11)]; + [bezier28Path addLineToPoint: CGPointMake(28.36, 32.17)]; + [bezier28Path addLineToPoint: CGPointMake(28.22, 32.24)]; + [bezier28Path addLineToPoint: CGPointMake(28.06, 32.3)]; + [bezier28Path addLineToPoint: CGPointMake(27.9, 32.35)]; + [bezier28Path addLineToPoint: CGPointMake(27.73, 32.39)]; + [bezier28Path addLineToPoint: CGPointMake(27.57, 32.43)]; + [bezier28Path addLineToPoint: CGPointMake(27.4, 32.45)]; + [bezier28Path addLineToPoint: CGPointMake(27.23, 32.46)]; + [bezier28Path addLineToPoint: CGPointMake(27.07, 32.46)]; + [bezier28Path addLineToPoint: CGPointMake(26.91, 32.45)]; + [bezier28Path addLineToPoint: CGPointMake(26.75, 32.43)]; + [bezier28Path addLineToPoint: CGPointMake(26.55, 32.37)]; + [bezier28Path addLineToPoint: CGPointMake(26.37, 32.32)]; + [bezier28Path addLineToPoint: CGPointMake(26.21, 32.24)]; + [bezier28Path addLineToPoint: CGPointMake(26.07, 32.16)]; + [bezier28Path addLineToPoint: CGPointMake(25.94, 32.07)]; + [bezier28Path addLineToPoint: CGPointMake(25.83, 31.96)]; + [bezier28Path addLineToPoint: CGPointMake(25.74, 31.86)]; + [bezier28Path addLineToPoint: CGPointMake(25.66, 31.74)]; + [bezier28Path addLineToPoint: CGPointMake(25.59, 31.62)]; + [bezier28Path addLineToPoint: CGPointMake(25.53, 31.5)]; + [bezier28Path addLineToPoint: CGPointMake(25.49, 31.37)]; + [bezier28Path addLineToPoint: CGPointMake(25.45, 31.25)]; + [bezier28Path addLineToPoint: CGPointMake(25.43, 31.12)]; + [bezier28Path addLineToPoint: CGPointMake(25.41, 30.98)]; + [bezier28Path addLineToPoint: CGPointMake(25.4, 30.86)]; + [bezier28Path addLineToPoint: CGPointMake(25.4, 30.73)]; + [bezier28Path addLineToPoint: CGPointMake(25.42, 30.51)]; + [bezier28Path addLineToPoint: CGPointMake(25.45, 30.3)]; + [bezier28Path addLineToPoint: CGPointMake(25.51, 30.1)]; + [bezier28Path addLineToPoint: CGPointMake(25.59, 29.91)]; + [bezier28Path addLineToPoint: CGPointMake(25.68, 29.73)]; + [bezier28Path addLineToPoint: CGPointMake(25.78, 29.56)]; + [bezier28Path addLineToPoint: CGPointMake(25.9, 29.4)]; + [bezier28Path addLineToPoint: CGPointMake(26.04, 29.26)]; + [bezier28Path addLineToPoint: CGPointMake(26.18, 29.13)]; + [bezier28Path addLineToPoint: CGPointMake(26.34, 29.01)]; + [bezier28Path addLineToPoint: CGPointMake(26.5, 28.9)]; + [bezier28Path addLineToPoint: CGPointMake(26.67, 28.81)]; + [bezier28Path addLineToPoint: CGPointMake(26.85, 28.73)]; + [bezier28Path addLineToPoint: CGPointMake(27.04, 28.67)]; + [bezier28Path addLineToPoint: CGPointMake(27.24, 28.62)]; + [bezier28Path addLineToPoint: CGPointMake(27.44, 28.58)]; + [bezier28Path addLineToPoint: CGPointMake(27.45, 28.58)]; + [bezier28Path addLineToPoint: CGPointMake(27.48, 28.58)]; + [bezier28Path addLineToPoint: CGPointMake(27.52, 28.57)]; + [bezier28Path addLineToPoint: CGPointMake(27.58, 28.56)]; + [bezier28Path addLineToPoint: CGPointMake(27.65, 28.55)]; + [bezier28Path addLineToPoint: CGPointMake(27.73, 28.55)]; + [bezier28Path addLineToPoint: CGPointMake(27.81, 28.54)]; + [bezier28Path addLineToPoint: CGPointMake(27.91, 28.52)]; + [bezier28Path addLineToPoint: CGPointMake(28.01, 28.51)]; + [bezier28Path addLineToPoint: CGPointMake(28.1, 28.5)]; + [bezier28Path addLineToPoint: CGPointMake(28.2, 28.5)]; + [bezier28Path addLineToPoint: CGPointMake(28.3, 28.49)]; + [bezier28Path addLineToPoint: CGPointMake(28.39, 28.48)]; + [bezier28Path addLineToPoint: CGPointMake(28.47, 28.47)]; + [bezier28Path addLineToPoint: CGPointMake(28.55, 28.47)]; + [bezier28Path addLineToPoint: CGPointMake(28.75, 28.47)]; + [bezier28Path addLineToPoint: CGPointMake(28.88, 28.47)]; + [bezier28Path addLineToPoint: CGPointMake(29.01, 28.48)]; + [bezier28Path addLineToPoint: CGPointMake(29.13, 28.48)]; + [bezier28Path addLineToPoint: CGPointMake(29.23, 28.49)]; + [bezier28Path addLineToPoint: CGPointMake(29.31, 28.49)]; + [bezier28Path addLineToPoint: CGPointMake(29.37, 28.5)]; + [bezier28Path addLineToPoint: CGPointMake(29.39, 28.5)]; + [bezier28Path addLineToPoint: CGPointMake(29.4, 28.46)]; + [bezier28Path addLineToPoint: CGPointMake(29.43, 28.35)]; + [bezier28Path addLineToPoint: CGPointMake(29.46, 28.23)]; + [bezier28Path addLineToPoint: CGPointMake(29.47, 28.13)]; + [bezier28Path addLineToPoint: CGPointMake(29.45, 28)]; + [bezier28Path addLineToPoint: CGPointMake(29.4, 27.89)]; + [bezier28Path addLineToPoint: CGPointMake(29.33, 27.78)]; + [bezier28Path addLineToPoint: CGPointMake(29.24, 27.7)]; + [bezier28Path addLineToPoint: CGPointMake(29.13, 27.63)]; + [bezier28Path addLineToPoint: CGPointMake(29.01, 27.57)]; + [bezier28Path addLineToPoint: CGPointMake(28.88, 27.54)]; + [bezier28Path addLineToPoint: CGPointMake(28.73, 27.53)]; + [bezier28Path addLineToPoint: CGPointMake(28.57, 27.52)]; + [bezier28Path addLineToPoint: CGPointMake(28.4, 27.52)]; + [bezier28Path addLineToPoint: CGPointMake(28.22, 27.52)]; + [bezier28Path addLineToPoint: CGPointMake(28.04, 27.52)]; + [bezier28Path addLineToPoint: CGPointMake(27.85, 27.53)]; + [bezier28Path addLineToPoint: CGPointMake(27.67, 27.55)]; + [bezier28Path addLineToPoint: CGPointMake(27.49, 27.57)]; + [bezier28Path addLineToPoint: CGPointMake(27.31, 27.59)]; + [bezier28Path addLineToPoint: CGPointMake(27.14, 27.61)]; + [bezier28Path addLineToPoint: CGPointMake(26.97, 27.64)]; + [bezier28Path addLineToPoint: CGPointMake(26.83, 27.67)]; + [bezier28Path addLineToPoint: CGPointMake(26.69, 27.7)]; + [bezier28Path addLineToPoint: CGPointMake(26.56, 27.73)]; + [bezier28Path addLineToPoint: CGPointMake(26.46, 27.77)]; + [bezier28Path addLineToPoint: CGPointMake(26.38, 27.81)]; + [bezier28Path addLineToPoint: CGPointMake(26.32, 27.84)]; + [bezier28Path addLineToPoint: CGPointMake(26.72, 26.47)]; + [bezier28Path addLineToPoint: CGPointMake(26.85, 26.42)]; + [bezier28Path addLineToPoint: CGPointMake(26.97, 26.37)]; + [bezier28Path addLineToPoint: CGPointMake(27.11, 26.33)]; + [bezier28Path addLineToPoint: CGPointMake(27.25, 26.3)]; + [bezier28Path addLineToPoint: CGPointMake(27.38, 26.28)]; + [bezier28Path addLineToPoint: CGPointMake(27.53, 26.25)]; + [bezier28Path addLineToPoint: CGPointMake(27.68, 26.23)]; + [bezier28Path addLineToPoint: CGPointMake(27.83, 26.22)]; + [bezier28Path addLineToPoint: CGPointMake(27.99, 26.21)]; + [bezier28Path addLineToPoint: CGPointMake(28.16, 26.2)]; + [bezier28Path addLineToPoint: CGPointMake(28.33, 26.2)]; + [bezier28Path addLineToPoint: CGPointMake(28.88, 26.2)]; + [bezier28Path addLineToPoint: CGPointMake(29.08, 26.2)]; + [bezier28Path addLineToPoint: CGPointMake(29.27, 26.21)]; + [bezier28Path addLineToPoint: CGPointMake(29.43, 26.22)]; + [bezier28Path addLineToPoint: CGPointMake(29.61, 26.25)]; + [bezier28Path addLineToPoint: CGPointMake(29.78, 26.29)]; + [bezier28Path addLineToPoint: CGPointMake(29.96, 26.34)]; + [bezier28Path addLineToPoint: CGPointMake(30.14, 26.41)]; + [bezier28Path addLineToPoint: CGPointMake(30.31, 26.49)]; + [bezier28Path addLineToPoint: CGPointMake(30.48, 26.58)]; + [bezier28Path addLineToPoint: CGPointMake(30.64, 26.69)]; + [bezier28Path addLineToPoint: CGPointMake(30.78, 26.82)]; + [bezier28Path addLineToPoint: CGPointMake(30.91, 26.95)]; + [bezier28Path addLineToPoint: CGPointMake(31.02, 27.11)]; + [bezier28Path addLineToPoint: CGPointMake(31.11, 27.28)]; + [bezier28Path addLineToPoint: CGPointMake(31.16, 27.46)]; + [bezier28Path addLineToPoint: CGPointMake(31.2, 27.65)]; + [bezier28Path addLineToPoint: CGPointMake(31.2, 27.87)]; + [bezier28Path addLineToPoint: CGPointMake(31.16, 28.1)]; + [bezier28Path addLineToPoint: CGPointMake(30.59, 31.1)]; + [bezier28Path closePath]; + bezier28Path.miterLimit = 4; + + bezier28Path.usesEvenOddFillRule = YES; + + [color3 setStroke]; + bezier28Path.lineWidth = 0.5; + [bezier28Path stroke]; + + + //// Bezier 29 Drawing + UIBezierPath* bezier29Path = [UIBezierPath bezierPath]; + [bezier29Path moveToPoint: CGPointMake(29.22, 29.62)]; + [bezier29Path addLineToPoint: CGPointMake(29.21, 29.59)]; + [bezier29Path addLineToPoint: CGPointMake(29.19, 29.56)]; + [bezier29Path addLineToPoint: CGPointMake(29.16, 29.54)]; + [bezier29Path addLineToPoint: CGPointMake(29.1, 29.53)]; + [bezier29Path addLineToPoint: CGPointMake(29.04, 29.52)]; + [bezier29Path addLineToPoint: CGPointMake(28.96, 29.52)]; + [bezier29Path addLineToPoint: CGPointMake(28.79, 29.52)]; + [bezier29Path addLineToPoint: CGPointMake(28.7, 29.52)]; + [bezier29Path addLineToPoint: CGPointMake(28.6, 29.53)]; + [bezier29Path addLineToPoint: CGPointMake(28.51, 29.54)]; + [bezier29Path addLineToPoint: CGPointMake(28.42, 29.56)]; + [bezier29Path addLineToPoint: CGPointMake(28.34, 29.57)]; + [bezier29Path addLineToPoint: CGPointMake(28.26, 29.58)]; + [bezier29Path addLineToPoint: CGPointMake(28.19, 29.6)]; + [bezier29Path addLineToPoint: CGPointMake(28.12, 29.62)]; + [bezier29Path addLineToPoint: CGPointMake(28.08, 29.63)]; + [bezier29Path addLineToPoint: CGPointMake(28.04, 29.65)]; + [bezier29Path addLineToPoint: CGPointMake(27.98, 29.67)]; + [bezier29Path addLineToPoint: CGPointMake(27.91, 29.7)]; + [bezier29Path addLineToPoint: CGPointMake(27.84, 29.73)]; + [bezier29Path addLineToPoint: CGPointMake(27.77, 29.77)]; + [bezier29Path addLineToPoint: CGPointMake(27.69, 29.81)]; + [bezier29Path addLineToPoint: CGPointMake(27.61, 29.86)]; + [bezier29Path addLineToPoint: CGPointMake(27.53, 29.91)]; + [bezier29Path addLineToPoint: CGPointMake(27.46, 29.97)]; + [bezier29Path addLineToPoint: CGPointMake(27.39, 30.04)]; + [bezier29Path addLineToPoint: CGPointMake(27.33, 30.11)]; + [bezier29Path addLineToPoint: CGPointMake(27.27, 30.18)]; + [bezier29Path addLineToPoint: CGPointMake(27.23, 30.26)]; + [bezier29Path addLineToPoint: CGPointMake(27.2, 30.35)]; + [bezier29Path addLineToPoint: CGPointMake(27.18, 30.44)]; + [bezier29Path addLineToPoint: CGPointMake(27.17, 30.64)]; + [bezier29Path addLineToPoint: CGPointMake(27.2, 30.79)]; + [bezier29Path addLineToPoint: CGPointMake(27.26, 30.9)]; + [bezier29Path addLineToPoint: CGPointMake(27.33, 30.99)]; + [bezier29Path addLineToPoint: CGPointMake(27.42, 31.05)]; + [bezier29Path addLineToPoint: CGPointMake(27.52, 31.08)]; + [bezier29Path addLineToPoint: CGPointMake(27.61, 31.1)]; + [bezier29Path addLineToPoint: CGPointMake(27.7, 31.1)]; + [bezier29Path addLineToPoint: CGPointMake(27.87, 31.1)]; + [bezier29Path addLineToPoint: CGPointMake(28.02, 31.08)]; + [bezier29Path addLineToPoint: CGPointMake(28.17, 31.06)]; + [bezier29Path addLineToPoint: CGPointMake(28.3, 31.02)]; + [bezier29Path addLineToPoint: CGPointMake(28.41, 30.98)]; + [bezier29Path addLineToPoint: CGPointMake(28.52, 30.93)]; + [bezier29Path addLineToPoint: CGPointMake(28.62, 30.88)]; + [bezier29Path addLineToPoint: CGPointMake(28.71, 30.82)]; + [bezier29Path addLineToPoint: CGPointMake(28.78, 30.76)]; + [bezier29Path addLineToPoint: CGPointMake(28.85, 30.69)]; + [bezier29Path addLineToPoint: CGPointMake(28.9, 30.63)]; + [bezier29Path addLineToPoint: CGPointMake(28.95, 30.56)]; + [bezier29Path addLineToPoint: CGPointMake(28.99, 30.5)]; + [bezier29Path addLineToPoint: CGPointMake(29.02, 30.43)]; + [bezier29Path addLineToPoint: CGPointMake(29.05, 30.36)]; + [bezier29Path addLineToPoint: CGPointMake(29.07, 30.3)]; + [bezier29Path addLineToPoint: CGPointMake(29.12, 30.14)]; + [bezier29Path addLineToPoint: CGPointMake(29.16, 29.95)]; + [bezier29Path addLineToPoint: CGPointMake(29.19, 29.77)]; + [bezier29Path addLineToPoint: CGPointMake(29.22, 29.62)]; + [bezier29Path closePath]; + bezier29Path.miterLimit = 4; + + bezier29Path.usesEvenOddFillRule = YES; + + [color2 setFill]; + [bezier29Path fill]; + + + //// Bezier 30 Drawing + UIBezierPath* bezier30Path = [UIBezierPath bezierPath]; + [bezier30Path moveToPoint: CGPointMake(18.61, 32.37)]; + [bezier30Path addLineToPoint: CGPointMake(17.06, 32.37)]; + [bezier30Path addLineToPoint: CGPointMake(18.35, 24.89)]; + [bezier30Path addLineToPoint: CGPointMake(21.05, 24.89)]; + [bezier30Path addLineToPoint: CGPointMake(21.3, 29.33)]; + [bezier30Path addLineToPoint: CGPointMake(23.17, 24.89)]; + [bezier30Path addLineToPoint: CGPointMake(25.98, 24.89)]; + [bezier30Path addLineToPoint: CGPointMake(24.66, 32.37)]; + [bezier30Path addLineToPoint: CGPointMake(23.11, 32.37)]; + [bezier30Path addLineToPoint: CGPointMake(24.09, 26.78)]; + [bezier30Path addLineToPoint: CGPointMake(24.03, 26.78)]; + [bezier30Path addLineToPoint: CGPointMake(21.71, 32.37)]; + [bezier30Path addLineToPoint: CGPointMake(19.96, 32.37)]; + [bezier30Path addLineToPoint: CGPointMake(19.95, 32.13)]; + [bezier30Path addLineToPoint: CGPointMake(19.91, 31.51)]; + [bezier30Path addLineToPoint: CGPointMake(19.86, 30.63)]; + [bezier30Path addLineToPoint: CGPointMake(19.74, 28.6)]; + [bezier30Path addLineToPoint: CGPointMake(19.69, 27.71)]; + [bezier30Path addLineToPoint: CGPointMake(19.65, 27.06)]; + [bezier30Path addLineToPoint: CGPointMake(19.64, 26.78)]; + [bezier30Path addLineToPoint: CGPointMake(19.56, 26.78)]; + [bezier30Path addLineToPoint: CGPointMake(18.61, 32.37)]; + [bezier30Path closePath]; + bezier30Path.miterLimit = 4; + + bezier30Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier30Path fill]; + + + //// Bezier 31 Drawing + UIBezierPath* bezier31Path = [UIBezierPath bezierPath]; + [bezier31Path moveToPoint: CGPointMake(18.61, 32.37)]; + [bezier31Path addLineToPoint: CGPointMake(17.06, 32.37)]; + [bezier31Path addLineToPoint: CGPointMake(18.35, 24.89)]; + [bezier31Path addLineToPoint: CGPointMake(21.05, 24.89)]; + [bezier31Path addLineToPoint: CGPointMake(21.3, 29.33)]; + [bezier31Path addLineToPoint: CGPointMake(23.17, 24.89)]; + [bezier31Path addLineToPoint: CGPointMake(25.98, 24.89)]; + [bezier31Path addLineToPoint: CGPointMake(24.66, 32.37)]; + [bezier31Path addLineToPoint: CGPointMake(23.11, 32.37)]; + [bezier31Path addLineToPoint: CGPointMake(24.09, 26.78)]; + [bezier31Path addLineToPoint: CGPointMake(24.03, 26.78)]; + [bezier31Path addLineToPoint: CGPointMake(21.71, 32.37)]; + [bezier31Path addLineToPoint: CGPointMake(19.96, 32.37)]; + [bezier31Path addLineToPoint: CGPointMake(19.95, 32.13)]; + [bezier31Path addLineToPoint: CGPointMake(19.91, 31.51)]; + [bezier31Path addLineToPoint: CGPointMake(19.86, 30.63)]; + [bezier31Path addLineToPoint: CGPointMake(19.74, 28.6)]; + [bezier31Path addLineToPoint: CGPointMake(19.69, 27.71)]; + [bezier31Path addLineToPoint: CGPointMake(19.65, 27.06)]; + [bezier31Path addLineToPoint: CGPointMake(19.64, 26.78)]; + [bezier31Path addLineToPoint: CGPointMake(19.56, 26.78)]; + [bezier31Path addLineToPoint: CGPointMake(18.61, 32.37)]; + [bezier31Path closePath]; + bezier31Path.miterLimit = 4; + + bezier31Path.usesEvenOddFillRule = YES; + + [color3 setStroke]; + bezier31Path.lineWidth = 0.5; + [bezier31Path stroke]; + + + //// Bezier 32 Drawing + UIBezierPath* bezier32Path = [UIBezierPath bezierPath]; + [bezier32Path moveToPoint: CGPointMake(58.85, 31.1)]; + [bezier32Path addLineToPoint: CGPointMake(58.61, 32.37)]; + [bezier32Path addLineToPoint: CGPointMake(57.18, 32.37)]; + [bezier32Path addLineToPoint: CGPointMake(57.2, 32.13)]; + [bezier32Path addLineToPoint: CGPointMake(57.2, 31.93)]; + [bezier32Path addLineToPoint: CGPointMake(57.2, 31.78)]; + [bezier32Path addLineToPoint: CGPointMake(57.21, 31.71)]; + [bezier32Path addLineToPoint: CGPointMake(57.14, 31.79)]; + [bezier32Path addLineToPoint: CGPointMake(57.05, 31.88)]; + [bezier32Path addLineToPoint: CGPointMake(56.95, 31.96)]; + [bezier32Path addLineToPoint: CGPointMake(56.84, 32.04)]; + [bezier32Path addLineToPoint: CGPointMake(56.72, 32.11)]; + [bezier32Path addLineToPoint: CGPointMake(56.58, 32.18)]; + [bezier32Path addLineToPoint: CGPointMake(56.44, 32.25)]; + [bezier32Path addLineToPoint: CGPointMake(56.3, 32.31)]; + [bezier32Path addLineToPoint: CGPointMake(56.14, 32.35)]; + [bezier32Path addLineToPoint: CGPointMake(55.98, 32.4)]; + [bezier32Path addLineToPoint: CGPointMake(55.82, 32.43)]; + [bezier32Path addLineToPoint: CGPointMake(55.66, 32.45)]; + [bezier32Path addLineToPoint: CGPointMake(55.5, 32.46)]; + [bezier32Path addLineToPoint: CGPointMake(55.34, 32.46)]; + [bezier32Path addLineToPoint: CGPointMake(55.19, 32.45)]; + [bezier32Path addLineToPoint: CGPointMake(55.03, 32.43)]; + [bezier32Path addLineToPoint: CGPointMake(54.83, 32.37)]; + [bezier32Path addLineToPoint: CGPointMake(54.65, 32.32)]; + [bezier32Path addLineToPoint: CGPointMake(54.49, 32.24)]; + [bezier32Path addLineToPoint: CGPointMake(54.34, 32.16)]; + [bezier32Path addLineToPoint: CGPointMake(54.21, 32.07)]; + [bezier32Path addLineToPoint: CGPointMake(54.1, 31.96)]; + [bezier32Path addLineToPoint: CGPointMake(54.01, 31.86)]; + [bezier32Path addLineToPoint: CGPointMake(53.93, 31.74)]; + [bezier32Path addLineToPoint: CGPointMake(53.87, 31.62)]; + [bezier32Path addLineToPoint: CGPointMake(53.81, 31.5)]; + [bezier32Path addLineToPoint: CGPointMake(53.77, 31.37)]; + [bezier32Path addLineToPoint: CGPointMake(53.74, 31.25)]; + [bezier32Path addLineToPoint: CGPointMake(53.72, 31.12)]; + [bezier32Path addLineToPoint: CGPointMake(53.7, 30.98)]; + [bezier32Path addLineToPoint: CGPointMake(53.69, 30.86)]; + [bezier32Path addLineToPoint: CGPointMake(53.69, 30.73)]; + [bezier32Path addLineToPoint: CGPointMake(53.7, 30.51)]; + [bezier32Path addLineToPoint: CGPointMake(53.73, 30.3)]; + [bezier32Path addLineToPoint: CGPointMake(53.79, 30.1)]; + [bezier32Path addLineToPoint: CGPointMake(53.86, 29.91)]; + [bezier32Path addLineToPoint: CGPointMake(53.95, 29.73)]; + [bezier32Path addLineToPoint: CGPointMake(54.05, 29.56)]; + [bezier32Path addLineToPoint: CGPointMake(54.17, 29.4)]; + [bezier32Path addLineToPoint: CGPointMake(54.3, 29.26)]; + [bezier32Path addLineToPoint: CGPointMake(54.45, 29.13)]; + [bezier32Path addLineToPoint: CGPointMake(54.61, 29.01)]; + [bezier32Path addLineToPoint: CGPointMake(54.77, 28.9)]; + [bezier32Path addLineToPoint: CGPointMake(54.95, 28.81)]; + [bezier32Path addLineToPoint: CGPointMake(55.12, 28.73)]; + [bezier32Path addLineToPoint: CGPointMake(55.31, 28.67)]; + [bezier32Path addLineToPoint: CGPointMake(55.5, 28.62)]; + [bezier32Path addLineToPoint: CGPointMake(55.69, 28.58)]; + [bezier32Path addLineToPoint: CGPointMake(55.7, 28.58)]; + [bezier32Path addLineToPoint: CGPointMake(55.73, 28.58)]; + [bezier32Path addLineToPoint: CGPointMake(55.77, 28.57)]; + [bezier32Path addLineToPoint: CGPointMake(55.83, 28.56)]; + [bezier32Path addLineToPoint: CGPointMake(55.9, 28.55)]; + [bezier32Path addLineToPoint: CGPointMake(55.98, 28.55)]; + [bezier32Path addLineToPoint: CGPointMake(56.07, 28.54)]; + [bezier32Path addLineToPoint: CGPointMake(56.16, 28.52)]; + [bezier32Path addLineToPoint: CGPointMake(56.26, 28.51)]; + [bezier32Path addLineToPoint: CGPointMake(56.36, 28.5)]; + [bezier32Path addLineToPoint: CGPointMake(56.46, 28.5)]; + [bezier32Path addLineToPoint: CGPointMake(56.55, 28.49)]; + [bezier32Path addLineToPoint: CGPointMake(56.64, 28.48)]; + [bezier32Path addLineToPoint: CGPointMake(56.72, 28.47)]; + [bezier32Path addLineToPoint: CGPointMake(56.8, 28.47)]; + [bezier32Path addLineToPoint: CGPointMake(57, 28.47)]; + [bezier32Path addLineToPoint: CGPointMake(57.14, 28.47)]; + [bezier32Path addLineToPoint: CGPointMake(57.27, 28.48)]; + [bezier32Path addLineToPoint: CGPointMake(57.4, 28.48)]; + [bezier32Path addLineToPoint: CGPointMake(57.5, 28.49)]; + [bezier32Path addLineToPoint: CGPointMake(57.59, 28.49)]; + [bezier32Path addLineToPoint: CGPointMake(57.65, 28.5)]; + [bezier32Path addLineToPoint: CGPointMake(57.67, 28.5)]; + [bezier32Path addLineToPoint: CGPointMake(57.68, 28.46)]; + [bezier32Path addLineToPoint: CGPointMake(57.7, 28.35)]; + [bezier32Path addLineToPoint: CGPointMake(57.71, 28.23)]; + [bezier32Path addLineToPoint: CGPointMake(57.73, 28.13)]; + [bezier32Path addLineToPoint: CGPointMake(57.7, 28)]; + [bezier32Path addLineToPoint: CGPointMake(57.66, 27.89)]; + [bezier32Path addLineToPoint: CGPointMake(57.58, 27.78)]; + [bezier32Path addLineToPoint: CGPointMake(57.5, 27.7)]; + [bezier32Path addLineToPoint: CGPointMake(57.4, 27.63)]; + [bezier32Path addLineToPoint: CGPointMake(57.28, 27.57)]; + [bezier32Path addLineToPoint: CGPointMake(57.15, 27.54)]; + [bezier32Path addLineToPoint: CGPointMake(57.01, 27.53)]; + [bezier32Path addLineToPoint: CGPointMake(56.85, 27.52)]; + [bezier32Path addLineToPoint: CGPointMake(56.68, 27.52)]; + [bezier32Path addLineToPoint: CGPointMake(56.51, 27.52)]; + [bezier32Path addLineToPoint: CGPointMake(56.32, 27.52)]; + [bezier32Path addLineToPoint: CGPointMake(56.14, 27.53)]; + [bezier32Path addLineToPoint: CGPointMake(55.95, 27.55)]; + [bezier32Path addLineToPoint: CGPointMake(55.77, 27.57)]; + [bezier32Path addLineToPoint: CGPointMake(55.6, 27.59)]; + [bezier32Path addLineToPoint: CGPointMake(55.43, 27.61)]; + [bezier32Path addLineToPoint: CGPointMake(55.26, 27.64)]; + [bezier32Path addLineToPoint: CGPointMake(55.11, 27.67)]; + [bezier32Path addLineToPoint: CGPointMake(54.98, 27.7)]; + [bezier32Path addLineToPoint: CGPointMake(54.85, 27.73)]; + [bezier32Path addLineToPoint: CGPointMake(54.75, 27.77)]; + [bezier32Path addLineToPoint: CGPointMake(54.67, 27.81)]; + [bezier32Path addLineToPoint: CGPointMake(54.61, 27.84)]; + [bezier32Path addLineToPoint: CGPointMake(55, 26.47)]; + [bezier32Path addLineToPoint: CGPointMake(55.13, 26.42)]; + [bezier32Path addLineToPoint: CGPointMake(55.26, 26.37)]; + [bezier32Path addLineToPoint: CGPointMake(55.39, 26.33)]; + [bezier32Path addLineToPoint: CGPointMake(55.53, 26.3)]; + [bezier32Path addLineToPoint: CGPointMake(55.67, 26.28)]; + [bezier32Path addLineToPoint: CGPointMake(55.81, 26.25)]; + [bezier32Path addLineToPoint: CGPointMake(55.96, 26.23)]; + [bezier32Path addLineToPoint: CGPointMake(56.11, 26.22)]; + [bezier32Path addLineToPoint: CGPointMake(56.27, 26.21)]; + [bezier32Path addLineToPoint: CGPointMake(56.44, 26.2)]; + [bezier32Path addLineToPoint: CGPointMake(56.6, 26.2)]; + [bezier32Path addLineToPoint: CGPointMake(57.14, 26.2)]; + [bezier32Path addLineToPoint: CGPointMake(57.33, 26.2)]; + [bezier32Path addLineToPoint: CGPointMake(57.53, 26.21)]; + [bezier32Path addLineToPoint: CGPointMake(57.69, 26.22)]; + [bezier32Path addLineToPoint: CGPointMake(57.86, 26.25)]; + [bezier32Path addLineToPoint: CGPointMake(58.03, 26.29)]; + [bezier32Path addLineToPoint: CGPointMake(58.22, 26.34)]; + [bezier32Path addLineToPoint: CGPointMake(58.39, 26.41)]; + [bezier32Path addLineToPoint: CGPointMake(58.57, 26.49)]; + [bezier32Path addLineToPoint: CGPointMake(58.74, 26.58)]; + [bezier32Path addLineToPoint: CGPointMake(58.9, 26.69)]; + [bezier32Path addLineToPoint: CGPointMake(59.04, 26.82)]; + [bezier32Path addLineToPoint: CGPointMake(59.17, 26.95)]; + [bezier32Path addLineToPoint: CGPointMake(59.29, 27.11)]; + [bezier32Path addLineToPoint: CGPointMake(59.37, 27.28)]; + [bezier32Path addLineToPoint: CGPointMake(59.43, 27.46)]; + [bezier32Path addLineToPoint: CGPointMake(59.47, 27.65)]; + [bezier32Path addLineToPoint: CGPointMake(59.47, 27.87)]; + [bezier32Path addLineToPoint: CGPointMake(59.44, 28.1)]; + [bezier32Path addLineToPoint: CGPointMake(58.85, 31.1)]; + [bezier32Path closePath]; + bezier32Path.miterLimit = 4; + + bezier32Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier32Path fill]; + + + //// Bezier 33 Drawing + UIBezierPath* bezier33Path = [UIBezierPath bezierPath]; + [bezier33Path moveToPoint: CGPointMake(58.61, 32.41)]; + [bezier33Path addLineToPoint: CGPointMake(58.65, 32.37)]; + [bezier33Path addLineToPoint: CGPointMake(58.88, 31.11)]; + [bezier33Path addLineToPoint: CGPointMake(58.81, 31.1)]; + [bezier33Path addLineToPoint: CGPointMake(58.58, 32.36)]; + [bezier33Path addLineToPoint: CGPointMake(58.61, 32.33)]; + [bezier33Path addLineToPoint: CGPointMake(58.61, 32.41)]; + [bezier33Path addLineToPoint: CGPointMake(58.64, 32.4)]; + [bezier33Path addLineToPoint: CGPointMake(58.65, 32.37)]; + [bezier33Path addLineToPoint: CGPointMake(58.61, 32.41)]; + [bezier33Path closePath]; + bezier33Path.miterLimit = 4; + + bezier33Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier33Path fill]; + + + //// Bezier 34 Drawing + UIBezierPath* bezier34Path = [UIBezierPath bezierPath]; + [bezier34Path moveToPoint: CGPointMake(57.15, 32.37)]; + [bezier34Path addLineToPoint: CGPointMake(57.18, 32.41)]; + [bezier34Path addLineToPoint: CGPointMake(58.61, 32.41)]; + [bezier34Path addLineToPoint: CGPointMake(58.61, 32.33)]; + [bezier34Path addLineToPoint: CGPointMake(57.18, 32.33)]; + [bezier34Path addLineToPoint: CGPointMake(57.22, 32.37)]; + [bezier34Path addLineToPoint: CGPointMake(57.15, 32.37)]; + [bezier34Path addLineToPoint: CGPointMake(57.14, 32.41)]; + [bezier34Path addLineToPoint: CGPointMake(57.18, 32.41)]; + [bezier34Path addLineToPoint: CGPointMake(57.15, 32.37)]; + [bezier34Path closePath]; + bezier34Path.miterLimit = 4; + + bezier34Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier34Path fill]; + + + //// Bezier 35 Drawing + UIBezierPath* bezier35Path = [UIBezierPath bezierPath]; + [bezier35Path moveToPoint: CGPointMake(57.24, 31.73)]; + [bezier35Path addLineToPoint: CGPointMake(57.19, 31.69)]; + [bezier35Path addLineToPoint: CGPointMake(57.17, 31.78)]; + [bezier35Path addLineToPoint: CGPointMake(57.16, 31.93)]; + [bezier35Path addLineToPoint: CGPointMake(57.16, 32.13)]; + [bezier35Path addLineToPoint: CGPointMake(57.15, 32.37)]; + [bezier35Path addLineToPoint: CGPointMake(57.22, 32.37)]; + [bezier35Path addLineToPoint: CGPointMake(57.23, 32.13)]; + [bezier35Path addLineToPoint: CGPointMake(57.24, 31.93)]; + [bezier35Path addLineToPoint: CGPointMake(57.24, 31.78)]; + [bezier35Path addLineToPoint: CGPointMake(57.24, 31.73)]; + [bezier35Path addLineToPoint: CGPointMake(57.18, 31.69)]; + [bezier35Path addLineToPoint: CGPointMake(57.24, 31.73)]; + [bezier35Path closePath]; + bezier35Path.miterLimit = 4; + + bezier35Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier35Path fill]; + + + //// Bezier 36 Drawing + UIBezierPath* bezier36Path = [UIBezierPath bezierPath]; + [bezier36Path moveToPoint: CGPointMake(55.03, 32.46)]; + [bezier36Path addLineToPoint: CGPointMake(55.03, 32.46)]; + [bezier36Path addLineToPoint: CGPointMake(55.19, 32.48)]; + [bezier36Path addLineToPoint: CGPointMake(55.34, 32.5)]; + [bezier36Path addLineToPoint: CGPointMake(55.5, 32.49)]; + [bezier36Path addLineToPoint: CGPointMake(55.66, 32.48)]; + [bezier36Path addLineToPoint: CGPointMake(55.83, 32.46)]; + [bezier36Path addLineToPoint: CGPointMake(55.99, 32.43)]; + [bezier36Path addLineToPoint: CGPointMake(56.15, 32.39)]; + [bezier36Path addLineToPoint: CGPointMake(56.31, 32.34)]; + [bezier36Path addLineToPoint: CGPointMake(56.45, 32.28)]; + [bezier36Path addLineToPoint: CGPointMake(56.6, 32.21)]; + [bezier36Path addLineToPoint: CGPointMake(56.73, 32.15)]; + [bezier36Path addLineToPoint: CGPointMake(56.85, 32.07)]; + [bezier36Path addLineToPoint: CGPointMake(56.97, 31.99)]; + [bezier36Path addLineToPoint: CGPointMake(57.08, 31.91)]; + [bezier36Path addLineToPoint: CGPointMake(57.17, 31.82)]; + [bezier36Path addLineToPoint: CGPointMake(57.24, 31.73)]; + [bezier36Path addLineToPoint: CGPointMake(57.18, 31.69)]; + [bezier36Path addLineToPoint: CGPointMake(57.11, 31.77)]; + [bezier36Path addLineToPoint: CGPointMake(57.03, 31.85)]; + [bezier36Path addLineToPoint: CGPointMake(56.93, 31.93)]; + [bezier36Path addLineToPoint: CGPointMake(56.82, 32.01)]; + [bezier36Path addLineToPoint: CGPointMake(56.7, 32.08)]; + [bezier36Path addLineToPoint: CGPointMake(56.56, 32.15)]; + [bezier36Path addLineToPoint: CGPointMake(56.43, 32.21)]; + [bezier36Path addLineToPoint: CGPointMake(56.29, 32.27)]; + [bezier36Path addLineToPoint: CGPointMake(56.14, 32.32)]; + [bezier36Path addLineToPoint: CGPointMake(55.98, 32.36)]; + [bezier36Path addLineToPoint: CGPointMake(55.82, 32.39)]; + [bezier36Path addLineToPoint: CGPointMake(55.66, 32.41)]; + [bezier36Path addLineToPoint: CGPointMake(55.5, 32.43)]; + [bezier36Path addLineToPoint: CGPointMake(55.34, 32.43)]; + [bezier36Path addLineToPoint: CGPointMake(55.19, 32.41)]; + [bezier36Path addLineToPoint: CGPointMake(55.04, 32.39)]; + [bezier36Path addLineToPoint: CGPointMake(55.03, 32.46)]; + [bezier36Path closePath]; + bezier36Path.miterLimit = 4; + + bezier36Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier36Path fill]; + + + //// Bezier 37 Drawing + UIBezierPath* bezier37Path = [UIBezierPath bezierPath]; + [bezier37Path moveToPoint: CGPointMake(53.65, 30.73)]; + [bezier37Path addLineToPoint: CGPointMake(53.65, 30.73)]; + [bezier37Path addLineToPoint: CGPointMake(53.65, 30.86)]; + [bezier37Path addLineToPoint: CGPointMake(53.67, 30.98)]; + [bezier37Path addLineToPoint: CGPointMake(53.68, 31.12)]; + [bezier37Path addLineToPoint: CGPointMake(53.71, 31.25)]; + [bezier37Path addLineToPoint: CGPointMake(53.73, 31.38)]; + [bezier37Path addLineToPoint: CGPointMake(53.78, 31.51)]; + [bezier37Path addLineToPoint: CGPointMake(53.83, 31.64)]; + [bezier37Path addLineToPoint: CGPointMake(53.91, 31.76)]; + [bezier37Path addLineToPoint: CGPointMake(53.99, 31.88)]; + [bezier37Path addLineToPoint: CGPointMake(54.08, 31.99)]; + [bezier37Path addLineToPoint: CGPointMake(54.19, 32.09)]; + [bezier37Path addLineToPoint: CGPointMake(54.32, 32.19)]; + [bezier37Path addLineToPoint: CGPointMake(54.47, 32.28)]; + [bezier37Path addLineToPoint: CGPointMake(54.63, 32.35)]; + [bezier37Path addLineToPoint: CGPointMake(54.82, 32.41)]; + [bezier37Path addLineToPoint: CGPointMake(55.03, 32.46)]; + [bezier37Path addLineToPoint: CGPointMake(55.04, 32.39)]; + [bezier37Path addLineToPoint: CGPointMake(54.83, 32.34)]; + [bezier37Path addLineToPoint: CGPointMake(54.66, 32.28)]; + [bezier37Path addLineToPoint: CGPointMake(54.5, 32.21)]; + [bezier37Path addLineToPoint: CGPointMake(54.36, 32.13)]; + [bezier37Path addLineToPoint: CGPointMake(54.24, 32.04)]; + [bezier37Path addLineToPoint: CGPointMake(54.13, 31.94)]; + [bezier37Path addLineToPoint: CGPointMake(54.04, 31.83)]; + [bezier37Path addLineToPoint: CGPointMake(53.96, 31.72)]; + [bezier37Path addLineToPoint: CGPointMake(53.9, 31.61)]; + [bezier37Path addLineToPoint: CGPointMake(53.85, 31.49)]; + [bezier37Path addLineToPoint: CGPointMake(53.8, 31.37)]; + [bezier37Path addLineToPoint: CGPointMake(53.77, 31.24)]; + [bezier37Path addLineToPoint: CGPointMake(53.75, 31.11)]; + [bezier37Path addLineToPoint: CGPointMake(53.73, 30.98)]; + [bezier37Path addLineToPoint: CGPointMake(53.72, 30.86)]; + [bezier37Path addLineToPoint: CGPointMake(53.73, 30.73)]; + [bezier37Path addLineToPoint: CGPointMake(53.65, 30.73)]; + [bezier37Path closePath]; + bezier37Path.miterLimit = 4; + + bezier37Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier37Path fill]; + + + //// Bezier 38 Drawing + UIBezierPath* bezier38Path = [UIBezierPath bezierPath]; + [bezier38Path moveToPoint: CGPointMake(55.69, 28.55)]; + [bezier38Path addLineToPoint: CGPointMake(55.69, 28.55)]; + [bezier38Path addLineToPoint: CGPointMake(55.49, 28.58)]; + [bezier38Path addLineToPoint: CGPointMake(55.3, 28.63)]; + [bezier38Path addLineToPoint: CGPointMake(55.11, 28.7)]; + [bezier38Path addLineToPoint: CGPointMake(54.93, 28.78)]; + [bezier38Path addLineToPoint: CGPointMake(54.75, 28.87)]; + [bezier38Path addLineToPoint: CGPointMake(54.58, 28.98)]; + [bezier38Path addLineToPoint: CGPointMake(54.43, 29.1)]; + [bezier38Path addLineToPoint: CGPointMake(54.28, 29.24)]; + [bezier38Path addLineToPoint: CGPointMake(54.14, 29.38)]; + [bezier38Path addLineToPoint: CGPointMake(54.02, 29.54)]; + [bezier38Path addLineToPoint: CGPointMake(53.91, 29.71)]; + [bezier38Path addLineToPoint: CGPointMake(53.83, 29.9)]; + [bezier38Path addLineToPoint: CGPointMake(53.75, 30.09)]; + [bezier38Path addLineToPoint: CGPointMake(53.7, 30.3)]; + [bezier38Path addLineToPoint: CGPointMake(53.67, 30.51)]; + [bezier38Path addLineToPoint: CGPointMake(53.65, 30.73)]; + [bezier38Path addLineToPoint: CGPointMake(53.73, 30.73)]; + [bezier38Path addLineToPoint: CGPointMake(53.73, 30.51)]; + [bezier38Path addLineToPoint: CGPointMake(53.77, 30.31)]; + [bezier38Path addLineToPoint: CGPointMake(53.82, 30.11)]; + [bezier38Path addLineToPoint: CGPointMake(53.89, 29.92)]; + [bezier38Path addLineToPoint: CGPointMake(53.98, 29.74)]; + [bezier38Path addLineToPoint: CGPointMake(54.08, 29.58)]; + [bezier38Path addLineToPoint: CGPointMake(54.2, 29.42)]; + [bezier38Path addLineToPoint: CGPointMake(54.33, 29.28)]; + [bezier38Path addLineToPoint: CGPointMake(54.47, 29.16)]; + [bezier38Path addLineToPoint: CGPointMake(54.63, 29.04)]; + [bezier38Path addLineToPoint: CGPointMake(54.79, 28.94)]; + [bezier38Path addLineToPoint: CGPointMake(54.96, 28.84)]; + [bezier38Path addLineToPoint: CGPointMake(55.13, 28.76)]; + [bezier38Path addLineToPoint: CGPointMake(55.32, 28.7)]; + [bezier38Path addLineToPoint: CGPointMake(55.51, 28.65)]; + [bezier38Path addLineToPoint: CGPointMake(55.69, 28.62)]; + [bezier38Path addLineToPoint: CGPointMake(55.69, 28.55)]; + [bezier38Path closePath]; + bezier38Path.miterLimit = 4; + + bezier38Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier38Path fill]; + + + //// Bezier 39 Drawing + UIBezierPath* bezier39Path = [UIBezierPath bezierPath]; + [bezier39Path moveToPoint: CGPointMake(56.87, 28.43)]; + [bezier39Path addLineToPoint: CGPointMake(56.8, 28.43)]; + [bezier39Path addLineToPoint: CGPointMake(56.72, 28.44)]; + [bezier39Path addLineToPoint: CGPointMake(56.64, 28.45)]; + [bezier39Path addLineToPoint: CGPointMake(56.55, 28.45)]; + [bezier39Path addLineToPoint: CGPointMake(56.46, 28.46)]; + [bezier39Path addLineToPoint: CGPointMake(56.36, 28.47)]; + [bezier39Path addLineToPoint: CGPointMake(56.26, 28.48)]; + [bezier39Path addLineToPoint: CGPointMake(56.16, 28.49)]; + [bezier39Path addLineToPoint: CGPointMake(56.07, 28.5)]; + [bezier39Path addLineToPoint: CGPointMake(55.98, 28.51)]; + [bezier39Path addLineToPoint: CGPointMake(55.9, 28.52)]; + [bezier39Path addLineToPoint: CGPointMake(55.83, 28.53)]; + [bezier39Path addLineToPoint: CGPointMake(55.77, 28.54)]; + [bezier39Path addLineToPoint: CGPointMake(55.73, 28.54)]; + [bezier39Path addLineToPoint: CGPointMake(55.7, 28.55)]; + [bezier39Path addLineToPoint: CGPointMake(55.69, 28.55)]; + [bezier39Path addLineToPoint: CGPointMake(55.69, 28.62)]; + [bezier39Path addLineToPoint: CGPointMake(55.7, 28.62)]; + [bezier39Path addLineToPoint: CGPointMake(55.74, 28.61)]; + [bezier39Path addLineToPoint: CGPointMake(55.77, 28.6)]; + [bezier39Path addLineToPoint: CGPointMake(55.83, 28.6)]; + [bezier39Path addLineToPoint: CGPointMake(55.9, 28.59)]; + [bezier39Path addLineToPoint: CGPointMake(55.98, 28.58)]; + [bezier39Path addLineToPoint: CGPointMake(56.07, 28.57)]; + [bezier39Path addLineToPoint: CGPointMake(56.16, 28.56)]; + [bezier39Path addLineToPoint: CGPointMake(56.26, 28.55)]; + [bezier39Path addLineToPoint: CGPointMake(56.36, 28.54)]; + [bezier39Path addLineToPoint: CGPointMake(56.46, 28.53)]; + [bezier39Path addLineToPoint: CGPointMake(56.55, 28.52)]; + [bezier39Path addLineToPoint: CGPointMake(56.64, 28.51)]; + [bezier39Path addLineToPoint: CGPointMake(56.72, 28.51)]; + [bezier39Path addLineToPoint: CGPointMake(56.87, 28.51)]; + [bezier39Path addLineToPoint: CGPointMake(56.87, 28.43)]; + [bezier39Path closePath]; + bezier39Path.miterLimit = 4; + + bezier39Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier39Path fill]; + + + //// Bezier 40 Drawing + UIBezierPath* bezier40Path = [UIBezierPath bezierPath]; + [bezier40Path moveToPoint: CGPointMake(57.63, 28.49)]; + [bezier40Path addLineToPoint: CGPointMake(57.67, 28.46)]; + [bezier40Path addLineToPoint: CGPointMake(57.65, 28.46)]; + [bezier40Path addLineToPoint: CGPointMake(57.59, 28.46)]; + [bezier40Path addLineToPoint: CGPointMake(57.5, 28.45)]; + [bezier40Path addLineToPoint: CGPointMake(57.4, 28.44)]; + [bezier40Path addLineToPoint: CGPointMake(57.14, 28.44)]; + [bezier40Path addLineToPoint: CGPointMake(57, 28.43)]; + [bezier40Path addLineToPoint: CGPointMake(56.87, 28.43)]; + [bezier40Path addLineToPoint: CGPointMake(56.87, 28.51)]; + [bezier40Path addLineToPoint: CGPointMake(57.14, 28.51)]; + [bezier40Path addLineToPoint: CGPointMake(57.27, 28.52)]; + [bezier40Path addLineToPoint: CGPointMake(57.5, 28.52)]; + [bezier40Path addLineToPoint: CGPointMake(57.59, 28.52)]; + [bezier40Path addLineToPoint: CGPointMake(57.65, 28.53)]; + [bezier40Path addLineToPoint: CGPointMake(57.67, 28.53)]; + [bezier40Path addLineToPoint: CGPointMake(57.7, 28.5)]; + [bezier40Path addLineToPoint: CGPointMake(57.67, 28.53)]; + [bezier40Path addLineToPoint: CGPointMake(57.7, 28.54)]; + [bezier40Path addLineToPoint: CGPointMake(57.7, 28.5)]; + [bezier40Path addLineToPoint: CGPointMake(57.63, 28.49)]; + [bezier40Path closePath]; + bezier40Path.miterLimit = 4; + + bezier40Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier40Path fill]; + + + //// Bezier 41 Drawing + UIBezierPath* bezier41Path = [UIBezierPath bezierPath]; + [bezier41Path moveToPoint: CGPointMake(57.69, 28.13)]; + [bezier41Path addLineToPoint: CGPointMake(57.69, 28.13)]; + [bezier41Path addLineToPoint: CGPointMake(57.68, 28.23)]; + [bezier41Path addLineToPoint: CGPointMake(57.66, 28.35)]; + [bezier41Path addLineToPoint: CGPointMake(57.65, 28.45)]; + [bezier41Path addLineToPoint: CGPointMake(57.63, 28.49)]; + [bezier41Path addLineToPoint: CGPointMake(57.7, 28.5)]; + [bezier41Path addLineToPoint: CGPointMake(57.71, 28.46)]; + [bezier41Path addLineToPoint: CGPointMake(57.73, 28.36)]; + [bezier41Path addLineToPoint: CGPointMake(57.75, 28.23)]; + [bezier41Path addLineToPoint: CGPointMake(57.77, 28.13)]; + [bezier41Path addLineToPoint: CGPointMake(57.69, 28.13)]; + [bezier41Path closePath]; + bezier41Path.miterLimit = 4; + + bezier41Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier41Path fill]; + + + //// Bezier 42 Drawing + UIBezierPath* bezier42Path = [UIBezierPath bezierPath]; + [bezier42Path moveToPoint: CGPointMake(57.01, 27.56)]; + [bezier42Path addLineToPoint: CGPointMake(57.01, 27.57)]; + [bezier42Path addLineToPoint: CGPointMake(57.14, 27.57)]; + [bezier42Path addLineToPoint: CGPointMake(57.26, 27.61)]; + [bezier42Path addLineToPoint: CGPointMake(57.38, 27.66)]; + [bezier42Path addLineToPoint: CGPointMake(57.48, 27.73)]; + [bezier42Path addLineToPoint: CGPointMake(57.55, 27.81)]; + [bezier42Path addLineToPoint: CGPointMake(57.62, 27.9)]; + [bezier42Path addLineToPoint: CGPointMake(57.67, 28.01)]; + [bezier42Path addLineToPoint: CGPointMake(57.69, 28.13)]; + [bezier42Path addLineToPoint: CGPointMake(57.76, 28.13)]; + [bezier42Path addLineToPoint: CGPointMake(57.74, 28)]; + [bezier42Path addLineToPoint: CGPointMake(57.69, 27.87)]; + [bezier42Path addLineToPoint: CGPointMake(57.61, 27.76)]; + [bezier42Path addLineToPoint: CGPointMake(57.52, 27.67)]; + [bezier42Path addLineToPoint: CGPointMake(57.41, 27.59)]; + [bezier42Path addLineToPoint: CGPointMake(57.29, 27.54)]; + [bezier42Path addLineToPoint: CGPointMake(57.16, 27.51)]; + [bezier42Path addLineToPoint: CGPointMake(57.01, 27.49)]; + [bezier42Path addLineToPoint: CGPointMake(57.01, 27.56)]; + [bezier42Path closePath]; + bezier42Path.miterLimit = 4; + + bezier42Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier42Path fill]; + + + //// Bezier 43 Drawing + UIBezierPath* bezier43Path = [UIBezierPath bezierPath]; + [bezier43Path moveToPoint: CGPointMake(54.57, 27.84)]; + [bezier43Path addLineToPoint: CGPointMake(54.63, 27.87)]; + [bezier43Path addLineToPoint: CGPointMake(54.69, 27.84)]; + [bezier43Path addLineToPoint: CGPointMake(54.76, 27.8)]; + [bezier43Path addLineToPoint: CGPointMake(54.86, 27.77)]; + [bezier43Path addLineToPoint: CGPointMake(54.98, 27.73)]; + [bezier43Path addLineToPoint: CGPointMake(55.12, 27.71)]; + [bezier43Path addLineToPoint: CGPointMake(55.27, 27.68)]; + [bezier43Path addLineToPoint: CGPointMake(55.43, 27.65)]; + [bezier43Path addLineToPoint: CGPointMake(55.6, 27.63)]; + [bezier43Path addLineToPoint: CGPointMake(55.77, 27.6)]; + [bezier43Path addLineToPoint: CGPointMake(55.95, 27.59)]; + [bezier43Path addLineToPoint: CGPointMake(56.14, 27.57)]; + [bezier43Path addLineToPoint: CGPointMake(56.32, 27.56)]; + [bezier43Path addLineToPoint: CGPointMake(56.85, 27.56)]; + [bezier43Path addLineToPoint: CGPointMake(57.01, 27.56)]; + [bezier43Path addLineToPoint: CGPointMake(57.01, 27.49)]; + [bezier43Path addLineToPoint: CGPointMake(56.85, 27.49)]; + [bezier43Path addLineToPoint: CGPointMake(56.68, 27.48)]; + [bezier43Path addLineToPoint: CGPointMake(56.51, 27.48)]; + [bezier43Path addLineToPoint: CGPointMake(56.32, 27.49)]; + [bezier43Path addLineToPoint: CGPointMake(56.14, 27.5)]; + [bezier43Path addLineToPoint: CGPointMake(55.95, 27.52)]; + [bezier43Path addLineToPoint: CGPointMake(55.77, 27.53)]; + [bezier43Path addLineToPoint: CGPointMake(55.6, 27.56)]; + [bezier43Path addLineToPoint: CGPointMake(55.42, 27.58)]; + [bezier43Path addLineToPoint: CGPointMake(55.25, 27.61)]; + [bezier43Path addLineToPoint: CGPointMake(55.11, 27.64)]; + [bezier43Path addLineToPoint: CGPointMake(54.97, 27.67)]; + [bezier43Path addLineToPoint: CGPointMake(54.84, 27.7)]; + [bezier43Path addLineToPoint: CGPointMake(54.74, 27.73)]; + [bezier43Path addLineToPoint: CGPointMake(54.65, 27.77)]; + [bezier43Path addLineToPoint: CGPointMake(54.58, 27.81)]; + [bezier43Path addLineToPoint: CGPointMake(54.64, 27.85)]; + [bezier43Path addLineToPoint: CGPointMake(54.57, 27.84)]; + [bezier43Path closePath]; + bezier43Path.miterLimit = 4; + + bezier43Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier43Path fill]; + + + //// Bezier 44 Drawing + UIBezierPath* bezier44Path = [UIBezierPath bezierPath]; + [bezier44Path moveToPoint: CGPointMake(54.99, 26.44)]; + [bezier44Path addLineToPoint: CGPointMake(54.97, 26.46)]; + [bezier44Path addLineToPoint: CGPointMake(54.57, 27.84)]; + [bezier44Path addLineToPoint: CGPointMake(54.64, 27.85)]; + [bezier44Path addLineToPoint: CGPointMake(55.04, 26.48)]; + [bezier44Path addLineToPoint: CGPointMake(55.02, 26.5)]; + [bezier44Path addLineToPoint: CGPointMake(54.99, 26.44)]; + [bezier44Path addLineToPoint: CGPointMake(54.98, 26.44)]; + [bezier44Path addLineToPoint: CGPointMake(54.97, 26.46)]; + [bezier44Path addLineToPoint: CGPointMake(54.99, 26.44)]; + [bezier44Path closePath]; + bezier44Path.miterLimit = 4; + + bezier44Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier44Path fill]; + + + //// Bezier 45 Drawing + UIBezierPath* bezier45Path = [UIBezierPath bezierPath]; + [bezier45Path moveToPoint: CGPointMake(57.53, 26.17)]; + [bezier45Path addLineToPoint: CGPointMake(57.53, 26.17)]; + [bezier45Path addLineToPoint: CGPointMake(57.33, 26.16)]; + [bezier45Path addLineToPoint: CGPointMake(57.14, 26.16)]; + [bezier45Path addLineToPoint: CGPointMake(56.6, 26.16)]; + [bezier45Path addLineToPoint: CGPointMake(56.44, 26.17)]; + [bezier45Path addLineToPoint: CGPointMake(56.27, 26.17)]; + [bezier45Path addLineToPoint: CGPointMake(56.11, 26.19)]; + [bezier45Path addLineToPoint: CGPointMake(55.96, 26.2)]; + [bezier45Path addLineToPoint: CGPointMake(55.81, 26.22)]; + [bezier45Path addLineToPoint: CGPointMake(55.66, 26.24)]; + [bezier45Path addLineToPoint: CGPointMake(55.52, 26.27)]; + [bezier45Path addLineToPoint: CGPointMake(55.39, 26.3)]; + [bezier45Path addLineToPoint: CGPointMake(55.25, 26.34)]; + [bezier45Path addLineToPoint: CGPointMake(55.12, 26.38)]; + [bezier45Path addLineToPoint: CGPointMake(54.99, 26.44)]; + [bezier45Path addLineToPoint: CGPointMake(55.02, 26.5)]; + [bezier45Path addLineToPoint: CGPointMake(55.14, 26.45)]; + [bezier45Path addLineToPoint: CGPointMake(55.27, 26.41)]; + [bezier45Path addLineToPoint: CGPointMake(55.4, 26.37)]; + [bezier45Path addLineToPoint: CGPointMake(55.53, 26.34)]; + [bezier45Path addLineToPoint: CGPointMake(55.68, 26.31)]; + [bezier45Path addLineToPoint: CGPointMake(55.82, 26.29)]; + [bezier45Path addLineToPoint: CGPointMake(55.96, 26.26)]; + [bezier45Path addLineToPoint: CGPointMake(56.11, 26.25)]; + [bezier45Path addLineToPoint: CGPointMake(56.27, 26.24)]; + [bezier45Path addLineToPoint: CGPointMake(56.44, 26.24)]; + [bezier45Path addLineToPoint: CGPointMake(57.14, 26.24)]; + [bezier45Path addLineToPoint: CGPointMake(57.33, 26.24)]; + [bezier45Path addLineToPoint: CGPointMake(57.53, 26.24)]; + [bezier45Path addLineToPoint: CGPointMake(57.53, 26.17)]; + [bezier45Path closePath]; + bezier45Path.miterLimit = 4; + + bezier45Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier45Path fill]; + + + //// Bezier 46 Drawing + UIBezierPath* bezier46Path = [UIBezierPath bezierPath]; + [bezier46Path moveToPoint: CGPointMake(59.48, 28.1)]; + [bezier46Path addLineToPoint: CGPointMake(59.48, 28.1)]; + [bezier46Path addLineToPoint: CGPointMake(59.51, 27.87)]; + [bezier46Path addLineToPoint: CGPointMake(59.51, 27.65)]; + [bezier46Path addLineToPoint: CGPointMake(59.47, 27.45)]; + [bezier46Path addLineToPoint: CGPointMake(59.41, 27.27)]; + [bezier46Path addLineToPoint: CGPointMake(59.31, 27.09)]; + [bezier46Path addLineToPoint: CGPointMake(59.2, 26.93)]; + [bezier46Path addLineToPoint: CGPointMake(59.06, 26.79)]; + [bezier46Path addLineToPoint: CGPointMake(58.92, 26.66)]; + [bezier46Path addLineToPoint: CGPointMake(58.76, 26.55)]; + [bezier46Path addLineToPoint: CGPointMake(58.59, 26.45)]; + [bezier46Path addLineToPoint: CGPointMake(58.4, 26.37)]; + [bezier46Path addLineToPoint: CGPointMake(58.23, 26.3)]; + [bezier46Path addLineToPoint: CGPointMake(58.04, 26.25)]; + [bezier46Path addLineToPoint: CGPointMake(57.86, 26.21)]; + [bezier46Path addLineToPoint: CGPointMake(57.69, 26.19)]; + [bezier46Path addLineToPoint: CGPointMake(57.53, 26.17)]; + [bezier46Path addLineToPoint: CGPointMake(57.53, 26.24)]; + [bezier46Path addLineToPoint: CGPointMake(57.69, 26.25)]; + [bezier46Path addLineToPoint: CGPointMake(57.85, 26.28)]; + [bezier46Path addLineToPoint: CGPointMake(58.03, 26.32)]; + [bezier46Path addLineToPoint: CGPointMake(58.2, 26.37)]; + [bezier46Path addLineToPoint: CGPointMake(58.38, 26.44)]; + [bezier46Path addLineToPoint: CGPointMake(58.55, 26.52)]; + [bezier46Path addLineToPoint: CGPointMake(58.72, 26.61)]; + [bezier46Path addLineToPoint: CGPointMake(58.88, 26.72)]; + [bezier46Path addLineToPoint: CGPointMake(59.02, 26.85)]; + [bezier46Path addLineToPoint: CGPointMake(59.14, 26.98)]; + [bezier46Path addLineToPoint: CGPointMake(59.26, 27.12)]; + [bezier46Path addLineToPoint: CGPointMake(59.34, 27.29)]; + [bezier46Path addLineToPoint: CGPointMake(59.4, 27.47)]; + [bezier46Path addLineToPoint: CGPointMake(59.44, 27.65)]; + [bezier46Path addLineToPoint: CGPointMake(59.44, 27.87)]; + [bezier46Path addLineToPoint: CGPointMake(59.41, 28.09)]; + [bezier46Path addLineToPoint: CGPointMake(59.48, 28.1)]; + [bezier46Path closePath]; + bezier46Path.miterLimit = 4; + + bezier46Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier46Path fill]; + + + //// Bezier 47 Drawing + UIBezierPath* bezier47Path = [UIBezierPath bezierPath]; + [bezier47Path moveToPoint: CGPointMake(58.88, 31.11)]; + [bezier47Path addLineToPoint: CGPointMake(58.88, 31.11)]; + [bezier47Path addLineToPoint: CGPointMake(59.48, 28.1)]; + [bezier47Path addLineToPoint: CGPointMake(59.41, 28.09)]; + [bezier47Path addLineToPoint: CGPointMake(58.81, 31.1)]; + [bezier47Path addLineToPoint: CGPointMake(58.88, 31.11)]; + [bezier47Path closePath]; + bezier47Path.miterLimit = 4; + + bezier47Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier47Path fill]; + + + //// Bezier 48 Drawing + UIBezierPath* bezier48Path = [UIBezierPath bezierPath]; + [bezier48Path moveToPoint: CGPointMake(57.47, 29.62)]; + [bezier48Path addLineToPoint: CGPointMake(57.46, 29.58)]; + [bezier48Path addLineToPoint: CGPointMake(57.44, 29.56)]; + [bezier48Path addLineToPoint: CGPointMake(57.4, 29.54)]; + [bezier48Path addLineToPoint: CGPointMake(57.34, 29.52)]; + [bezier48Path addLineToPoint: CGPointMake(57.28, 29.52)]; + [bezier48Path addLineToPoint: CGPointMake(57.2, 29.51)]; + [bezier48Path addLineToPoint: CGPointMake(57.12, 29.51)]; + [bezier48Path addLineToPoint: CGPointMake(57.03, 29.52)]; + [bezier48Path addLineToPoint: CGPointMake(56.94, 29.53)]; + [bezier48Path addLineToPoint: CGPointMake(56.85, 29.54)]; + [bezier48Path addLineToPoint: CGPointMake(56.76, 29.55)]; + [bezier48Path addLineToPoint: CGPointMake(56.67, 29.56)]; + [bezier48Path addLineToPoint: CGPointMake(56.59, 29.58)]; + [bezier48Path addLineToPoint: CGPointMake(56.51, 29.59)]; + [bezier48Path addLineToPoint: CGPointMake(56.44, 29.61)]; + [bezier48Path addLineToPoint: CGPointMake(56.38, 29.62)]; + [bezier48Path addLineToPoint: CGPointMake(56.34, 29.62)]; + [bezier48Path addLineToPoint: CGPointMake(56.3, 29.64)]; + [bezier48Path addLineToPoint: CGPointMake(56.24, 29.66)]; + [bezier48Path addLineToPoint: CGPointMake(56.18, 29.68)]; + [bezier48Path addLineToPoint: CGPointMake(56.1, 29.71)]; + [bezier48Path addLineToPoint: CGPointMake(56.03, 29.75)]; + [bezier48Path addLineToPoint: CGPointMake(55.95, 29.79)]; + [bezier48Path addLineToPoint: CGPointMake(55.88, 29.84)]; + [bezier48Path addLineToPoint: CGPointMake(55.81, 29.89)]; + [bezier48Path addLineToPoint: CGPointMake(55.73, 29.95)]; + [bezier48Path addLineToPoint: CGPointMake(55.67, 30.02)]; + [bezier48Path addLineToPoint: CGPointMake(55.61, 30.09)]; + [bezier48Path addLineToPoint: CGPointMake(55.56, 30.17)]; + [bezier48Path addLineToPoint: CGPointMake(55.52, 30.26)]; + [bezier48Path addLineToPoint: CGPointMake(55.48, 30.35)]; + [bezier48Path addLineToPoint: CGPointMake(55.47, 30.44)]; + [bezier48Path addLineToPoint: CGPointMake(55.46, 30.64)]; + [bezier48Path addLineToPoint: CGPointMake(55.49, 30.79)]; + [bezier48Path addLineToPoint: CGPointMake(55.53, 30.9)]; + [bezier48Path addLineToPoint: CGPointMake(55.6, 30.99)]; + [bezier48Path addLineToPoint: CGPointMake(55.69, 31.05)]; + [bezier48Path addLineToPoint: CGPointMake(55.78, 31.08)]; + [bezier48Path addLineToPoint: CGPointMake(55.88, 31.1)]; + [bezier48Path addLineToPoint: CGPointMake(55.98, 31.1)]; + [bezier48Path addLineToPoint: CGPointMake(56.15, 31.1)]; + [bezier48Path addLineToPoint: CGPointMake(56.31, 31.08)]; + [bezier48Path addLineToPoint: CGPointMake(56.46, 31.05)]; + [bezier48Path addLineToPoint: CGPointMake(56.59, 31.01)]; + [bezier48Path addLineToPoint: CGPointMake(56.71, 30.97)]; + [bezier48Path addLineToPoint: CGPointMake(56.82, 30.92)]; + [bezier48Path addLineToPoint: CGPointMake(56.92, 30.86)]; + [bezier48Path addLineToPoint: CGPointMake(57.01, 30.79)]; + [bezier48Path addLineToPoint: CGPointMake(57.09, 30.73)]; + [bezier48Path addLineToPoint: CGPointMake(57.16, 30.65)]; + [bezier48Path addLineToPoint: CGPointMake(57.22, 30.59)]; + [bezier48Path addLineToPoint: CGPointMake(57.28, 30.51)]; + [bezier48Path addLineToPoint: CGPointMake(57.32, 30.44)]; + [bezier48Path addLineToPoint: CGPointMake(57.34, 30.38)]; + [bezier48Path addLineToPoint: CGPointMake(57.37, 30.31)]; + [bezier48Path addLineToPoint: CGPointMake(57.38, 30.24)]; + [bezier48Path addLineToPoint: CGPointMake(57.41, 30.08)]; + [bezier48Path addLineToPoint: CGPointMake(57.44, 29.92)]; + [bezier48Path addLineToPoint: CGPointMake(57.46, 29.76)]; + [bezier48Path addLineToPoint: CGPointMake(57.47, 29.62)]; + [bezier48Path closePath]; + bezier48Path.miterLimit = 4; + + bezier48Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier48Path fill]; + + + //// Bezier 49 Drawing + UIBezierPath* bezier49Path = [UIBezierPath bezierPath]; + [bezier49Path moveToPoint: CGPointMake(59.27, 32.37)]; + [bezier49Path addLineToPoint: CGPointMake(60.88, 32.37)]; + [bezier49Path addLineToPoint: CGPointMake(61.46, 29.13)]; + [bezier49Path addLineToPoint: CGPointMake(61.48, 29)]; + [bezier49Path addLineToPoint: CGPointMake(61.51, 28.88)]; + [bezier49Path addLineToPoint: CGPointMake(61.55, 28.75)]; + [bezier49Path addLineToPoint: CGPointMake(61.59, 28.63)]; + [bezier49Path addLineToPoint: CGPointMake(61.65, 28.5)]; + [bezier49Path addLineToPoint: CGPointMake(61.72, 28.38)]; + [bezier49Path addLineToPoint: CGPointMake(61.79, 28.27)]; + [bezier49Path addLineToPoint: CGPointMake(61.88, 28.16)]; + [bezier49Path addLineToPoint: CGPointMake(61.98, 28.06)]; + [bezier49Path addLineToPoint: CGPointMake(62.1, 27.97)]; + [bezier49Path addLineToPoint: CGPointMake(62.23, 27.89)]; + [bezier49Path addLineToPoint: CGPointMake(62.38, 27.82)]; + [bezier49Path addLineToPoint: CGPointMake(62.54, 27.76)]; + [bezier49Path addLineToPoint: CGPointMake(62.72, 27.72)]; + [bezier49Path addLineToPoint: CGPointMake(62.92, 27.68)]; + [bezier49Path addLineToPoint: CGPointMake(63.15, 27.67)]; + [bezier49Path addLineToPoint: CGPointMake(63.29, 27.67)]; + [bezier49Path addLineToPoint: CGPointMake(63.54, 26.21)]; + [bezier49Path addLineToPoint: CGPointMake(63.38, 26.22)]; + [bezier49Path addLineToPoint: CGPointMake(63.23, 26.24)]; + [bezier49Path addLineToPoint: CGPointMake(63.09, 26.26)]; + [bezier49Path addLineToPoint: CGPointMake(62.95, 26.3)]; + [bezier49Path addLineToPoint: CGPointMake(62.83, 26.35)]; + [bezier49Path addLineToPoint: CGPointMake(62.71, 26.41)]; + [bezier49Path addLineToPoint: CGPointMake(62.59, 26.47)]; + [bezier49Path addLineToPoint: CGPointMake(62.49, 26.54)]; + [bezier49Path addLineToPoint: CGPointMake(62.38, 26.62)]; + [bezier49Path addLineToPoint: CGPointMake(62.29, 26.7)]; + [bezier49Path addLineToPoint: CGPointMake(62.19, 26.79)]; + [bezier49Path addLineToPoint: CGPointMake(62.1, 26.88)]; + [bezier49Path addLineToPoint: CGPointMake(62.02, 26.98)]; + [bezier49Path addLineToPoint: CGPointMake(61.93, 27.08)]; + [bezier49Path addLineToPoint: CGPointMake(61.85, 27.19)]; + [bezier49Path addLineToPoint: CGPointMake(61.77, 27.3)]; + [bezier49Path addLineToPoint: CGPointMake(61.94, 26.27)]; + [bezier49Path addLineToPoint: CGPointMake(60.34, 26.27)]; + [bezier49Path addLineToPoint: CGPointMake(59.27, 32.37)]; + [bezier49Path closePath]; + bezier49Path.miterLimit = 4; + + bezier49Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier49Path fill]; + + + //// Bezier 50 Drawing + UIBezierPath* bezier50Path = [UIBezierPath bezierPath]; + [bezier50Path moveToPoint: CGPointMake(59.27, 32.37)]; + [bezier50Path addLineToPoint: CGPointMake(60.88, 32.37)]; + [bezier50Path addLineToPoint: CGPointMake(61.46, 29.13)]; + [bezier50Path addLineToPoint: CGPointMake(61.48, 29)]; + [bezier50Path addLineToPoint: CGPointMake(61.51, 28.88)]; + [bezier50Path addLineToPoint: CGPointMake(61.55, 28.75)]; + [bezier50Path addLineToPoint: CGPointMake(61.59, 28.63)]; + [bezier50Path addLineToPoint: CGPointMake(61.65, 28.5)]; + [bezier50Path addLineToPoint: CGPointMake(61.72, 28.38)]; + [bezier50Path addLineToPoint: CGPointMake(61.79, 28.27)]; + [bezier50Path addLineToPoint: CGPointMake(61.88, 28.16)]; + [bezier50Path addLineToPoint: CGPointMake(61.98, 28.06)]; + [bezier50Path addLineToPoint: CGPointMake(62.1, 27.97)]; + [bezier50Path addLineToPoint: CGPointMake(62.23, 27.89)]; + [bezier50Path addLineToPoint: CGPointMake(62.38, 27.82)]; + [bezier50Path addLineToPoint: CGPointMake(62.54, 27.76)]; + [bezier50Path addLineToPoint: CGPointMake(62.72, 27.72)]; + [bezier50Path addLineToPoint: CGPointMake(62.92, 27.68)]; + [bezier50Path addLineToPoint: CGPointMake(63.15, 27.67)]; + [bezier50Path addLineToPoint: CGPointMake(63.29, 27.67)]; + [bezier50Path addLineToPoint: CGPointMake(63.54, 26.21)]; + [bezier50Path addLineToPoint: CGPointMake(63.38, 26.22)]; + [bezier50Path addLineToPoint: CGPointMake(63.23, 26.24)]; + [bezier50Path addLineToPoint: CGPointMake(63.09, 26.26)]; + [bezier50Path addLineToPoint: CGPointMake(62.95, 26.3)]; + [bezier50Path addLineToPoint: CGPointMake(62.83, 26.35)]; + [bezier50Path addLineToPoint: CGPointMake(62.71, 26.41)]; + [bezier50Path addLineToPoint: CGPointMake(62.59, 26.47)]; + [bezier50Path addLineToPoint: CGPointMake(62.49, 26.54)]; + [bezier50Path addLineToPoint: CGPointMake(62.38, 26.62)]; + [bezier50Path addLineToPoint: CGPointMake(62.29, 26.7)]; + [bezier50Path addLineToPoint: CGPointMake(62.19, 26.79)]; + [bezier50Path addLineToPoint: CGPointMake(62.1, 26.88)]; + [bezier50Path addLineToPoint: CGPointMake(62.02, 26.98)]; + [bezier50Path addLineToPoint: CGPointMake(61.93, 27.08)]; + [bezier50Path addLineToPoint: CGPointMake(61.85, 27.19)]; + [bezier50Path addLineToPoint: CGPointMake(61.77, 27.3)]; + [bezier50Path addLineToPoint: CGPointMake(61.94, 26.27)]; + [bezier50Path addLineToPoint: CGPointMake(60.34, 26.27)]; + [bezier50Path addLineToPoint: CGPointMake(59.27, 32.37)]; + [bezier50Path closePath]; + bezier50Path.miterLimit = 4; + + bezier50Path.usesEvenOddFillRule = YES; + + [color3 setStroke]; + bezier50Path.lineWidth = 0.5; + [bezier50Path stroke]; + + + //// Bezier 51 Drawing + UIBezierPath* bezier51Path = [UIBezierPath bezierPath]; + [bezier51Path moveToPoint: CGPointMake(44.2, 32.37)]; + [bezier51Path addLineToPoint: CGPointMake(45.83, 32.37)]; + [bezier51Path addLineToPoint: CGPointMake(46.38, 29.13)]; + [bezier51Path addLineToPoint: CGPointMake(46.4, 29)]; + [bezier51Path addLineToPoint: CGPointMake(46.46, 28.76)]; + [bezier51Path addLineToPoint: CGPointMake(46.5, 28.65)]; + [bezier51Path addLineToPoint: CGPointMake(46.54, 28.54)]; + [bezier51Path addLineToPoint: CGPointMake(46.6, 28.43)]; + [bezier51Path addLineToPoint: CGPointMake(46.67, 28.33)]; + [bezier51Path addLineToPoint: CGPointMake(46.75, 28.23)]; + [bezier51Path addLineToPoint: CGPointMake(46.84, 28.14)]; + [bezier51Path addLineToPoint: CGPointMake(46.94, 28.06)]; + [bezier51Path addLineToPoint: CGPointMake(47.07, 27.99)]; + [bezier51Path addLineToPoint: CGPointMake(47.2, 27.93)]; + [bezier51Path addLineToPoint: CGPointMake(47.36, 27.88)]; + [bezier51Path addLineToPoint: CGPointMake(47.54, 27.83)]; + [bezier51Path addLineToPoint: CGPointMake(47.73, 27.8)]; + [bezier51Path addLineToPoint: CGPointMake(47.96, 27.78)]; + [bezier51Path addLineToPoint: CGPointMake(47.97, 27.78)]; + [bezier51Path addLineToPoint: CGPointMake(48, 27.79)]; + [bezier51Path addLineToPoint: CGPointMake(48.02, 27.8)]; + [bezier51Path addLineToPoint: CGPointMake(48.05, 27.8)]; + [bezier51Path addLineToPoint: CGPointMake(48.08, 27.8)]; + [bezier51Path addLineToPoint: CGPointMake(48.1, 27.81)]; + [bezier51Path addLineToPoint: CGPointMake(48.12, 27.81)]; + [bezier51Path addLineToPoint: CGPointMake(48.13, 27.81)]; + [bezier51Path addLineToPoint: CGPointMake(48.13, 27.79)]; + [bezier51Path addLineToPoint: CGPointMake(48.15, 27.72)]; + [bezier51Path addLineToPoint: CGPointMake(48.17, 27.62)]; + [bezier51Path addLineToPoint: CGPointMake(48.2, 27.49)]; + [bezier51Path addLineToPoint: CGPointMake(48.24, 27.35)]; + [bezier51Path addLineToPoint: CGPointMake(48.28, 27.19)]; + [bezier51Path addLineToPoint: CGPointMake(48.33, 27.03)]; + [bezier51Path addLineToPoint: CGPointMake(48.38, 26.87)]; + [bezier51Path addLineToPoint: CGPointMake(48.43, 26.76)]; + [bezier51Path addLineToPoint: CGPointMake(48.49, 26.65)]; + [bezier51Path addLineToPoint: CGPointMake(48.54, 26.54)]; + [bezier51Path addLineToPoint: CGPointMake(48.6, 26.45)]; + [bezier51Path addLineToPoint: CGPointMake(48.65, 26.36)]; + [bezier51Path addLineToPoint: CGPointMake(48.69, 26.29)]; + [bezier51Path addLineToPoint: CGPointMake(48.72, 26.25)]; + [bezier51Path addLineToPoint: CGPointMake(48.73, 26.24)]; + [bezier51Path addLineToPoint: CGPointMake(48.72, 26.24)]; + [bezier51Path addLineToPoint: CGPointMake(48.7, 26.23)]; + [bezier51Path addLineToPoint: CGPointMake(48.67, 26.22)]; + [bezier51Path addLineToPoint: CGPointMake(48.63, 26.22)]; + [bezier51Path addLineToPoint: CGPointMake(48.59, 26.22)]; + [bezier51Path addLineToPoint: CGPointMake(48.55, 26.21)]; + [bezier51Path addLineToPoint: CGPointMake(48.51, 26.21)]; + [bezier51Path addLineToPoint: CGPointMake(48.47, 26.21)]; + [bezier51Path addLineToPoint: CGPointMake(48.29, 26.22)]; + [bezier51Path addLineToPoint: CGPointMake(48.13, 26.24)]; + [bezier51Path addLineToPoint: CGPointMake(47.98, 26.26)]; + [bezier51Path addLineToPoint: CGPointMake(47.85, 26.3)]; + [bezier51Path addLineToPoint: CGPointMake(47.72, 26.34)]; + [bezier51Path addLineToPoint: CGPointMake(47.6, 26.4)]; + [bezier51Path addLineToPoint: CGPointMake(47.49, 26.46)]; + [bezier51Path addLineToPoint: CGPointMake(47.39, 26.53)]; + [bezier51Path addLineToPoint: CGPointMake(47.29, 26.6)]; + [bezier51Path addLineToPoint: CGPointMake(47.2, 26.69)]; + [bezier51Path addLineToPoint: CGPointMake(47.11, 26.77)]; + [bezier51Path addLineToPoint: CGPointMake(47.03, 26.87)]; + [bezier51Path addLineToPoint: CGPointMake(46.94, 26.96)]; + [bezier51Path addLineToPoint: CGPointMake(46.86, 27.07)]; + [bezier51Path addLineToPoint: CGPointMake(46.78, 27.19)]; + [bezier51Path addLineToPoint: CGPointMake(46.69, 27.3)]; + [bezier51Path addLineToPoint: CGPointMake(46.9, 26.27)]; + [bezier51Path addLineToPoint: CGPointMake(45.26, 26.27)]; + [bezier51Path addLineToPoint: CGPointMake(44.2, 32.37)]; + [bezier51Path closePath]; + bezier51Path.miterLimit = 4; + + bezier51Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier51Path fill]; + + + //// Bezier 52 Drawing + UIBezierPath* bezier52Path = [UIBezierPath bezierPath]; + [bezier52Path moveToPoint: CGPointMake(44.2, 32.37)]; + [bezier52Path addLineToPoint: CGPointMake(45.83, 32.37)]; + [bezier52Path addLineToPoint: CGPointMake(46.38, 29.13)]; + [bezier52Path addLineToPoint: CGPointMake(46.4, 29)]; + [bezier52Path addLineToPoint: CGPointMake(46.46, 28.76)]; + [bezier52Path addLineToPoint: CGPointMake(46.5, 28.65)]; + [bezier52Path addLineToPoint: CGPointMake(46.54, 28.54)]; + [bezier52Path addLineToPoint: CGPointMake(46.6, 28.43)]; + [bezier52Path addLineToPoint: CGPointMake(46.67, 28.33)]; + [bezier52Path addLineToPoint: CGPointMake(46.75, 28.23)]; + [bezier52Path addLineToPoint: CGPointMake(46.84, 28.14)]; + [bezier52Path addLineToPoint: CGPointMake(46.94, 28.06)]; + [bezier52Path addLineToPoint: CGPointMake(47.07, 27.99)]; + [bezier52Path addLineToPoint: CGPointMake(47.2, 27.93)]; + [bezier52Path addLineToPoint: CGPointMake(47.36, 27.88)]; + [bezier52Path addLineToPoint: CGPointMake(47.54, 27.83)]; + [bezier52Path addLineToPoint: CGPointMake(47.73, 27.8)]; + [bezier52Path addLineToPoint: CGPointMake(47.96, 27.78)]; + [bezier52Path addLineToPoint: CGPointMake(47.97, 27.78)]; + [bezier52Path addLineToPoint: CGPointMake(48, 27.79)]; + [bezier52Path addLineToPoint: CGPointMake(48.02, 27.8)]; + [bezier52Path addLineToPoint: CGPointMake(48.05, 27.8)]; + [bezier52Path addLineToPoint: CGPointMake(48.08, 27.8)]; + [bezier52Path addLineToPoint: CGPointMake(48.1, 27.81)]; + [bezier52Path addLineToPoint: CGPointMake(48.12, 27.81)]; + [bezier52Path addLineToPoint: CGPointMake(48.13, 27.81)]; + [bezier52Path addLineToPoint: CGPointMake(48.13, 27.79)]; + [bezier52Path addLineToPoint: CGPointMake(48.15, 27.72)]; + [bezier52Path addLineToPoint: CGPointMake(48.17, 27.62)]; + [bezier52Path addLineToPoint: CGPointMake(48.2, 27.49)]; + [bezier52Path addLineToPoint: CGPointMake(48.24, 27.35)]; + [bezier52Path addLineToPoint: CGPointMake(48.28, 27.19)]; + [bezier52Path addLineToPoint: CGPointMake(48.33, 27.03)]; + [bezier52Path addLineToPoint: CGPointMake(48.38, 26.87)]; + [bezier52Path addLineToPoint: CGPointMake(48.43, 26.76)]; + [bezier52Path addLineToPoint: CGPointMake(48.49, 26.65)]; + [bezier52Path addLineToPoint: CGPointMake(48.54, 26.54)]; + [bezier52Path addLineToPoint: CGPointMake(48.6, 26.45)]; + [bezier52Path addLineToPoint: CGPointMake(48.65, 26.36)]; + [bezier52Path addLineToPoint: CGPointMake(48.69, 26.29)]; + [bezier52Path addLineToPoint: CGPointMake(48.72, 26.25)]; + [bezier52Path addLineToPoint: CGPointMake(48.73, 26.24)]; + [bezier52Path addLineToPoint: CGPointMake(48.72, 26.24)]; + [bezier52Path addLineToPoint: CGPointMake(48.7, 26.23)]; + [bezier52Path addLineToPoint: CGPointMake(48.67, 26.22)]; + [bezier52Path addLineToPoint: CGPointMake(48.63, 26.22)]; + [bezier52Path addLineToPoint: CGPointMake(48.59, 26.22)]; + [bezier52Path addLineToPoint: CGPointMake(48.55, 26.21)]; + [bezier52Path addLineToPoint: CGPointMake(48.51, 26.21)]; + [bezier52Path addLineToPoint: CGPointMake(48.47, 26.21)]; + [bezier52Path addLineToPoint: CGPointMake(48.29, 26.22)]; + [bezier52Path addLineToPoint: CGPointMake(48.13, 26.24)]; + [bezier52Path addLineToPoint: CGPointMake(47.98, 26.26)]; + [bezier52Path addLineToPoint: CGPointMake(47.85, 26.3)]; + [bezier52Path addLineToPoint: CGPointMake(47.72, 26.34)]; + [bezier52Path addLineToPoint: CGPointMake(47.6, 26.4)]; + [bezier52Path addLineToPoint: CGPointMake(47.49, 26.46)]; + [bezier52Path addLineToPoint: CGPointMake(47.39, 26.53)]; + [bezier52Path addLineToPoint: CGPointMake(47.29, 26.6)]; + [bezier52Path addLineToPoint: CGPointMake(47.2, 26.69)]; + [bezier52Path addLineToPoint: CGPointMake(47.11, 26.77)]; + [bezier52Path addLineToPoint: CGPointMake(47.03, 26.87)]; + [bezier52Path addLineToPoint: CGPointMake(46.94, 26.96)]; + [bezier52Path addLineToPoint: CGPointMake(46.86, 27.07)]; + [bezier52Path addLineToPoint: CGPointMake(46.78, 27.19)]; + [bezier52Path addLineToPoint: CGPointMake(46.69, 27.3)]; + [bezier52Path addLineToPoint: CGPointMake(46.9, 26.27)]; + [bezier52Path addLineToPoint: CGPointMake(45.26, 26.27)]; + [bezier52Path addLineToPoint: CGPointMake(44.2, 32.37)]; + [bezier52Path closePath]; + bezier52Path.miterLimit = 4; + + bezier52Path.usesEvenOddFillRule = YES; + + [color3 setStroke]; + bezier52Path.lineWidth = 0.5; + [bezier52Path stroke]; + } + } + } +} +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalMonogramCardView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalMonogramCardView.h new file mode 100644 index 0000000..829b5d8 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalMonogramCardView.h @@ -0,0 +1,5 @@ +#import "BTUICardVectorArtView.h" + +@interface BTUIPayPalMonogramCardView : BTUICardVectorArtView + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalMonogramCardView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalMonogramCardView.m new file mode 100644 index 0000000..8067f79 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalMonogramCardView.m @@ -0,0 +1,147 @@ +#import "BTUIPayPalMonogramCardView.h" + +@implementation BTUIPayPalMonogramCardView + +- (void)drawArt { + //// Color Declarations + UIColor* color3 = [UIColor colorWithRed: 0.092 green: 0.106 blue: 0.242 alpha: 1]; + UIColor* color2 = [UIColor colorWithRed: 0.132 green: 0.488 blue: 0.713 alpha: 1]; + UIColor* color1 = [UIColor colorWithRed: 0.115 green: 0.145 blue: 0.34 alpha: 1]; + + //// Page-1 + { + //// PayPal + { + //// pp_m_rgb + { + //// Group-5 + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(60.96, 32.7)]; + [bezierPath addCurveToPoint: CGPointMake(62.99, 27.37) controlPoint1: CGPointMake(61.89, 31.21) controlPoint2: CGPointMake(62.58, 29.42)]; + [bezierPath addCurveToPoint: CGPointMake(63.2, 22.57) controlPoint1: CGPointMake(63.36, 25.57) controlPoint2: CGPointMake(63.43, 23.95)]; + [bezierPath addCurveToPoint: CGPointMake(61.44, 18.87) controlPoint1: CGPointMake(62.96, 21.11) controlPoint2: CGPointMake(62.36, 19.86)]; + [bezierPath addCurveToPoint: CGPointMake(59.32, 17.31) controlPoint1: CGPointMake(60.89, 18.26) controlPoint2: CGPointMake(60.17, 17.74)]; + [bezierPath addLineToPoint: CGPointMake(59.29, 17.29)]; + [bezierPath addLineToPoint: CGPointMake(59.29, 17.28)]; + [bezierPath addLineToPoint: CGPointMake(59.3, 17.26)]; + [bezierPath addCurveToPoint: CGPointMake(59.26, 12.67) controlPoint1: CGPointMake(59.59, 15.46) controlPoint2: CGPointMake(59.58, 13.96)]; + [bezierPath addCurveToPoint: CGPointMake(57.27, 9.1) controlPoint1: CGPointMake(58.94, 11.37) controlPoint2: CGPointMake(58.29, 10.2)]; + [bezierPath addCurveToPoint: CGPointMake(45.87, 5.66) controlPoint1: CGPointMake(55.17, 6.81) controlPoint2: CGPointMake(51.33, 5.66)]; + [bezierPath addLineToPoint: CGPointMake(30.88, 5.66)]; + [bezierPath addCurveToPoint: CGPointMake(28.81, 7.34) controlPoint1: CGPointMake(29.84, 5.66) controlPoint2: CGPointMake(28.97, 6.36)]; + [bezierPath addLineToPoint: CGPointMake(22.56, 45)]; + [bezierPath addCurveToPoint: CGPointMake(22.85, 45.95) controlPoint1: CGPointMake(22.51, 45.34) controlPoint2: CGPointMake(22.61, 45.69)]; + [bezierPath addCurveToPoint: CGPointMake(23.79, 46.36) controlPoint1: CGPointMake(23.08, 46.21) controlPoint2: CGPointMake(23.43, 46.36)]; + [bezierPath addLineToPoint: CGPointMake(33.1, 46.36)]; + [bezierPath addLineToPoint: CGPointMake(33.09, 46.42)]; + [bezierPath addLineToPoint: CGPointMake(32.45, 50.27)]; + [bezierPath addCurveToPoint: CGPointMake(32.7, 51.09) controlPoint1: CGPointMake(32.4, 50.57) controlPoint2: CGPointMake(32.49, 50.87)]; + [bezierPath addCurveToPoint: CGPointMake(33.52, 51.45) controlPoint1: CGPointMake(32.9, 51.32) controlPoint2: CGPointMake(33.2, 51.45)]; + [bezierPath addLineToPoint: CGPointMake(41.32, 51.45)]; + [bezierPath addCurveToPoint: CGPointMake(43.13, 49.99) controlPoint1: CGPointMake(42.22, 51.45) controlPoint2: CGPointMake(42.98, 50.84)]; + [bezierPath addLineToPoint: CGPointMake(43.2, 49.61)]; + [bezierPath addLineToPoint: CGPointMake(44.67, 40.74)]; + [bezierPath addLineToPoint: CGPointMake(44.77, 40.25)]; + [bezierPath addCurveToPoint: CGPointMake(46.67, 38.71) controlPoint1: CGPointMake(44.92, 39.36) controlPoint2: CGPointMake(45.72, 38.71)]; + [bezierPath addLineToPoint: CGPointMake(47.84, 38.71)]; + [bezierPath addCurveToPoint: CGPointMake(57.6, 36.2) controlPoint1: CGPointMake(51.85, 38.71) controlPoint2: CGPointMake(55.14, 37.86)]; + [bezierPath addCurveToPoint: CGPointMake(60.96, 32.7) controlPoint1: CGPointMake(58.94, 35.29) controlPoint2: CGPointMake(60.07, 34.11)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + bezierPath.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezierPath fill]; + + + //// Bezier 2 Drawing + UIBezierPath* bezier2Path = [UIBezierPath bezierPath]; + [bezier2Path moveToPoint: CGPointMake(37.87, 17.32)]; + [bezier2Path addCurveToPoint: CGPointMake(38.91, 15.98) controlPoint1: CGPointMake(37.97, 16.72) controlPoint2: CGPointMake(38.37, 16.23)]; + [bezier2Path addCurveToPoint: CGPointMake(39.72, 15.81) controlPoint1: CGPointMake(39.16, 15.87) controlPoint2: CGPointMake(39.43, 15.81)]; + [bezier2Path addLineToPoint: CGPointMake(51.48, 15.81)]; + [bezier2Path addCurveToPoint: CGPointMake(55.35, 16.08) controlPoint1: CGPointMake(52.87, 15.81) controlPoint2: CGPointMake(54.17, 15.89)]; + [bezier2Path addCurveToPoint: CGPointMake(56.34, 16.26) controlPoint1: CGPointMake(55.69, 16.13) controlPoint2: CGPointMake(56.02, 16.19)]; + [bezier2Path addCurveToPoint: CGPointMake(57.28, 16.48) controlPoint1: CGPointMake(56.66, 16.32) controlPoint2: CGPointMake(56.97, 16.4)]; + [bezier2Path addCurveToPoint: CGPointMake(57.72, 16.62) controlPoint1: CGPointMake(57.43, 16.53) controlPoint2: CGPointMake(57.57, 16.57)]; + [bezier2Path addCurveToPoint: CGPointMake(59.35, 17.27) controlPoint1: CGPointMake(58.3, 16.8) controlPoint2: CGPointMake(58.85, 17.02)]; + [bezier2Path addCurveToPoint: CGPointMake(57.31, 9.07) controlPoint1: CGPointMake(59.93, 13.7) controlPoint2: CGPointMake(59.34, 11.27)]; + [bezier2Path addCurveToPoint: CGPointMake(45.87, 5.61) controlPoint1: CGPointMake(55.08, 6.65) controlPoint2: CGPointMake(51.04, 5.61)]; + [bezier2Path addLineToPoint: CGPointMake(30.88, 5.61)]; + [bezier2Path addCurveToPoint: CGPointMake(28.76, 7.33) controlPoint1: CGPointMake(29.82, 5.61) controlPoint2: CGPointMake(28.92, 6.34)]; + [bezier2Path addLineToPoint: CGPointMake(22.52, 44.99)]; + [bezier2Path addCurveToPoint: CGPointMake(23.79, 46.41) controlPoint1: CGPointMake(22.39, 45.74) controlPoint2: CGPointMake(23, 46.41)]; + [bezier2Path addLineToPoint: CGPointMake(33.04, 46.41)]; + [bezier2Path addLineToPoint: CGPointMake(37.87, 17.32)]; + [bezier2Path closePath]; + bezier2Path.miterLimit = 4; + + bezier2Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier2Path fill]; + + + //// Bezier 3 Drawing + UIBezierPath* bezier3Path = [UIBezierPath bezierPath]; + [bezier3Path moveToPoint: CGPointMake(59.35, 17.27)]; + [bezier3Path addLineToPoint: CGPointMake(59.35, 17.27)]; + [bezier3Path addCurveToPoint: CGPointMake(59.19, 18.1) controlPoint1: CGPointMake(59.3, 17.54) controlPoint2: CGPointMake(59.25, 17.82)]; + [bezier3Path addCurveToPoint: CGPointMake(41.81, 31.1) controlPoint1: CGPointMake(57.21, 27.76) controlPoint2: CGPointMake(50.45, 31.1)]; + [bezier3Path addLineToPoint: CGPointMake(37.41, 31.1)]; + [bezier3Path addCurveToPoint: CGPointMake(35.3, 32.82) controlPoint1: CGPointMake(36.35, 31.1) controlPoint2: CGPointMake(35.46, 31.83)]; + [bezier3Path addLineToPoint: CGPointMake(32.41, 50.26)]; + [bezier3Path addCurveToPoint: CGPointMake(33.52, 51.5) controlPoint1: CGPointMake(32.3, 50.91) controlPoint2: CGPointMake(32.83, 51.5)]; + [bezier3Path addLineToPoint: CGPointMake(41.32, 51.5)]; + [bezier3Path addCurveToPoint: CGPointMake(43.17, 49.99) controlPoint1: CGPointMake(42.24, 51.5) controlPoint2: CGPointMake(43.03, 50.86)]; + [bezier3Path addLineToPoint: CGPointMake(43.25, 49.62)]; + [bezier3Path addLineToPoint: CGPointMake(44.72, 40.75)]; + [bezier3Path addLineToPoint: CGPointMake(44.82, 40.26)]; + [bezier3Path addCurveToPoint: CGPointMake(46.67, 38.75) controlPoint1: CGPointMake(44.96, 39.39) controlPoint2: CGPointMake(45.75, 38.75)]; + [bezier3Path addLineToPoint: CGPointMake(47.84, 38.75)]; + [bezier3Path addCurveToPoint: CGPointMake(63.04, 27.38) controlPoint1: CGPointMake(55.39, 38.75) controlPoint2: CGPointMake(61.31, 35.83)]; + [bezier3Path addCurveToPoint: CGPointMake(61.48, 18.84) controlPoint1: CGPointMake(63.77, 23.85) controlPoint2: CGPointMake(63.39, 20.91)]; + [bezier3Path addCurveToPoint: CGPointMake(59.35, 17.27) controlPoint1: CGPointMake(60.9, 18.21) controlPoint2: CGPointMake(60.18, 17.69)]; + [bezier3Path closePath]; + bezier3Path.miterLimit = 4; + + bezier3Path.usesEvenOddFillRule = YES; + + [color2 setFill]; + [bezier3Path fill]; + } + + + //// Bezier 4 Drawing + UIBezierPath* bezier4Path = [UIBezierPath bezierPath]; + [bezier4Path moveToPoint: CGPointMake(54.19, 19.56)]; + [bezier4Path addCurveToPoint: CGPointMake(53.5, 19.4) controlPoint1: CGPointMake(53.97, 19.5) controlPoint2: CGPointMake(53.74, 19.45)]; + [bezier4Path addCurveToPoint: CGPointMake(52.76, 19.26) controlPoint1: CGPointMake(53.26, 19.35) controlPoint2: CGPointMake(53.01, 19.3)]; + [bezier4Path addCurveToPoint: CGPointMake(49.88, 19.06) controlPoint1: CGPointMake(51.88, 19.13) controlPoint2: CGPointMake(50.92, 19.06)]; + [bezier4Path addLineToPoint: CGPointMake(41.15, 19.06)]; + [bezier4Path addCurveToPoint: CGPointMake(40.55, 19.19) controlPoint1: CGPointMake(40.94, 19.06) controlPoint2: CGPointMake(40.73, 19.11)]; + [bezier4Path addCurveToPoint: CGPointMake(39.77, 20.18) controlPoint1: CGPointMake(40.15, 19.38) controlPoint2: CGPointMake(39.85, 19.74)]; + [bezier4Path addLineToPoint: CGPointMake(37.92, 31.39)]; + [bezier4Path addLineToPoint: CGPointMake(37.86, 31.71)]; + [bezier4Path addCurveToPoint: CGPointMake(39.43, 30.43) controlPoint1: CGPointMake(37.99, 30.98) controlPoint2: CGPointMake(38.65, 30.43)]; + [bezier4Path addLineToPoint: CGPointMake(42.7, 30.43)]; + [bezier4Path addCurveToPoint: CGPointMake(55.61, 20.77) controlPoint1: CGPointMake(49.12, 30.43) controlPoint2: CGPointMake(54.15, 27.95)]; + [bezier4Path addCurveToPoint: CGPointMake(55.73, 20.15) controlPoint1: CGPointMake(55.66, 20.56) controlPoint2: CGPointMake(55.69, 20.35)]; + [bezier4Path addCurveToPoint: CGPointMake(54.52, 19.66) controlPoint1: CGPointMake(55.36, 19.96) controlPoint2: CGPointMake(54.95, 19.8)]; + [bezier4Path addCurveToPoint: CGPointMake(54.19, 19.56) controlPoint1: CGPointMake(54.41, 19.63) controlPoint2: CGPointMake(54.3, 19.6)]; + [bezier4Path closePath]; + bezier4Path.miterLimit = 4; + + bezier4Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier4Path fill]; + } + } + } +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalWordmarkCompactVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalWordmarkCompactVectorArtView.h new file mode 100644 index 0000000..e148dfa --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalWordmarkCompactVectorArtView.h @@ -0,0 +1,5 @@ +#import "BTUIPayPalWordmarkVectorArtView.h" + +@interface BTUIPayPalWordmarkCompactVectorArtView : BTUIPayPalWordmarkVectorArtView + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalWordmarkCompactVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalWordmarkCompactVectorArtView.m new file mode 100644 index 0000000..8f8caed --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalWordmarkCompactVectorArtView.m @@ -0,0 +1,395 @@ +#import "BTUIPayPalWordmarkCompactVectorArtView.h" +#import "BTUI.h" + +@interface BTUIPayPalWordmarkCompactVectorArtView () +@property (nonatomic, assign) BOOL includePadding; +@end + +@implementation BTUIPayPalWordmarkCompactVectorArtView + +- (instancetype)initWithPadding { + self = [super init]; + if (self) { + self.includePadding = YES; + [self setupWithArtDimensions:CGSizeMake(158, 88)]; + } + return self; +} + +- (instancetype)init { + self = [super init]; + if (self) { + [self setupWithArtDimensions:CGSizeMake(284.0f, 80.0f)]; + } + return self; +} + +- (void)setupWithArtDimensions:(CGSize)artDimensions { + self.artDimensions = artDimensions; + self.opaque = NO; + self.theme = [BTUI braintreeTheme]; +} + +- (void)drawArt +{ + if (self.includePadding) { + //// Color Declarations + UIColor* payColor = [self.theme payBlue]; //[UIColor colorWithRed: 0.005 green: 0.123 blue: 0.454 alpha: 1]; + UIColor* palColor = [self.theme palBlue]; //[UIColor colorWithRed: 0.066 green: 0.536 blue: 0.839 alpha: 1]; + + //// Assets + { + //// button-paypal + { + //// Rectangle Drawing + + + //// logo/paypal + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(102.29, 34.76)]; + [bezierPath addCurveToPoint: CGPointMake(96.25, 38.4) controlPoint1: CGPointMake(101.73, 38.4) controlPoint2: CGPointMake(98.95, 38.4)]; + [bezierPath addLineToPoint: CGPointMake(94.72, 38.4)]; + [bezierPath addLineToPoint: CGPointMake(95.8, 31.6)]; + [bezierPath addCurveToPoint: CGPointMake(96.63, 30.89) controlPoint1: CGPointMake(95.86, 31.19) controlPoint2: CGPointMake(96.22, 30.89)]; + [bezierPath addLineToPoint: CGPointMake(97.33, 30.89)]; + [bezierPath addCurveToPoint: CGPointMake(101.79, 31.93) controlPoint1: CGPointMake(99.17, 30.89) controlPoint2: CGPointMake(100.9, 30.89)]; + [bezierPath addCurveToPoint: CGPointMake(102.29, 34.76) controlPoint1: CGPointMake(102.33, 32.55) controlPoint2: CGPointMake(102.49, 33.48)]; + [bezierPath addLineToPoint: CGPointMake(102.29, 34.76)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(91, 25)]; + [bezierPath addCurveToPoint: CGPointMake(89.56, 26.45) controlPoint1: CGPointMake(90.31, 25) controlPoint2: CGPointMake(89.67, 25.76)]; + [bezierPath addLineToPoint: CGPointMake(85.5, 53)]; + [bezierPath addCurveToPoint: CGPointMake(86.5, 54) controlPoint1: CGPointMake(85.42, 53.51) controlPoint2: CGPointMake(85.98, 54)]; + [bezierPath addLineToPoint: CGPointMake(91.5, 54)]; + [bezierPath addCurveToPoint: CGPointMake(92.5, 53) controlPoint1: CGPointMake(91.99, 54) controlPoint2: CGPointMake(92.42, 53.48)]; + [bezierPath addLineToPoint: CGPointMake(93.64, 45.22)]; + [bezierPath addCurveToPoint: CGPointMake(95.04, 44.03) controlPoint1: CGPointMake(93.75, 44.54) controlPoint2: CGPointMake(94.34, 44.03)]; + [bezierPath addLineToPoint: CGPointMake(98.25, 44.03)]; + [bezierPath addCurveToPoint: CGPointMake(109.81, 34.4) controlPoint1: CGPointMake(104.94, 44.03) controlPoint2: CGPointMake(108.8, 40.8)]; + [bezierPath addCurveToPoint: CGPointMake(108.52, 27.85) controlPoint1: CGPointMake(110.27, 31.59) controlPoint2: CGPointMake(109.83, 29.39)]; + [bezierPath addCurveToPoint: CGPointMake(101, 25) controlPoint1: CGPointMake(107.07, 26.16) controlPoint2: CGPointMake(104.4, 25)]; + [bezierPath addLineToPoint: CGPointMake(91, 25)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(123.7, 44.09)]; + [bezierPath addCurveToPoint: CGPointMake(118.21, 48.73) controlPoint1: CGPointMake(123.22, 46.87) controlPoint2: CGPointMake(121.02, 48.73)]; + [bezierPath addCurveToPoint: CGPointMake(114.94, 47.42) controlPoint1: CGPointMake(116.79, 48.73) controlPoint2: CGPointMake(115.67, 48.28)]; + [bezierPath addCurveToPoint: CGPointMake(114.18, 44.01) controlPoint1: CGPointMake(114.22, 46.57) controlPoint2: CGPointMake(113.95, 45.36)]; + [bezierPath addCurveToPoint: CGPointMake(119.63, 39.33) controlPoint1: CGPointMake(114.61, 41.26) controlPoint2: CGPointMake(116.86, 39.33)]; + [bezierPath addCurveToPoint: CGPointMake(122.87, 40.66) controlPoint1: CGPointMake(121.01, 39.33) controlPoint2: CGPointMake(122.13, 39.79)]; + [bezierPath addCurveToPoint: CGPointMake(123.7, 44.09) controlPoint1: CGPointMake(123.62, 41.53) controlPoint2: CGPointMake(123.91, 42.75)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(131.15, 34.46)]; + [bezierPath addLineToPoint: CGPointMake(126.25, 34.46)]; + [bezierPath addCurveToPoint: CGPointMake(125.41, 35.19) controlPoint1: CGPointMake(125.83, 34.46) controlPoint2: CGPointMake(125.48, 34.77)]; + [bezierPath addLineToPoint: CGPointMake(125.2, 36.57)]; + [bezierPath addLineToPoint: CGPointMake(124.85, 36.07)]; + [bezierPath addCurveToPoint: CGPointMake(119.07, 34) controlPoint1: CGPointMake(123.79, 34.52) controlPoint2: CGPointMake(121.43, 34)]; + [bezierPath addCurveToPoint: CGPointMake(108.15, 43.92) controlPoint1: CGPointMake(113.67, 34) controlPoint2: CGPointMake(109.05, 38.13)]; + [bezierPath addCurveToPoint: CGPointMake(109.97, 51.49) controlPoint1: CGPointMake(107.68, 46.81) controlPoint2: CGPointMake(108.34, 49.57)]; + [bezierPath addCurveToPoint: CGPointMake(116.13, 54) controlPoint1: CGPointMake(111.46, 53.26) controlPoint2: CGPointMake(113.59, 54)]; + [bezierPath addCurveToPoint: CGPointMake(122.91, 51.18) controlPoint1: CGPointMake(120.49, 54) controlPoint2: CGPointMake(122.91, 51.18)]; + [bezierPath addLineToPoint: CGPointMake(122.69, 52.55)]; + [bezierPath addCurveToPoint: CGPointMake(123.53, 53.54) controlPoint1: CGPointMake(122.61, 53.07) controlPoint2: CGPointMake(123.01, 53.54)]; + [bezierPath addLineToPoint: CGPointMake(127.94, 53.54)]; + [bezierPath addCurveToPoint: CGPointMake(129.34, 52.33) controlPoint1: CGPointMake(128.64, 53.54) controlPoint2: CGPointMake(129.23, 53.03)]; + [bezierPath addLineToPoint: CGPointMake(131.99, 35.46)]; + [bezierPath addCurveToPoint: CGPointMake(131.15, 34.46) controlPoint1: CGPointMake(132.07, 34.94) controlPoint2: CGPointMake(131.67, 34.46)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(137, 27)]; + [bezierPath addLineToPoint: CGPointMake(133, 53)]; + [bezierPath addCurveToPoint: CGPointMake(134, 54) controlPoint1: CGPointMake(132.93, 53.54) controlPoint2: CGPointMake(133.34, 54)]; + [bezierPath addLineToPoint: CGPointMake(138, 54)]; + [bezierPath addCurveToPoint: CGPointMake(140, 53) controlPoint1: CGPointMake(138.98, 54) controlPoint2: CGPointMake(139.59, 53.5)]; + [bezierPath addLineToPoint: CGPointMake(144, 27)]; + [bezierPath addCurveToPoint: CGPointMake(143, 26) controlPoint1: CGPointMake(144.07, 26.46) controlPoint2: CGPointMake(143.66, 26)]; + [bezierPath addLineToPoint: CGPointMake(138, 26)]; + [bezierPath addCurveToPoint: CGPointMake(137, 27) controlPoint1: CGPointMake(137.79, 26) controlPoint2: CGPointMake(137.42, 26.3)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + bezierPath.usesEvenOddFillRule = YES; + + [palColor setFill]; + [bezierPath fill]; + + + //// Bezier 2 Drawing + UIBezierPath* bezier2Path = [UIBezierPath bezierPath]; + [bezier2Path moveToPoint: CGPointMake(29.84, 34.76)]; + [bezier2Path addCurveToPoint: CGPointMake(23.81, 38.4) controlPoint1: CGPointMake(29.29, 38.4) controlPoint2: CGPointMake(26.5, 38.4)]; + [bezier2Path addLineToPoint: CGPointMake(22.28, 38.4)]; + [bezier2Path addLineToPoint: CGPointMake(23.35, 31.6)]; + [bezier2Path addCurveToPoint: CGPointMake(24.19, 30.89) controlPoint1: CGPointMake(23.42, 31.19) controlPoint2: CGPointMake(23.77, 30.89)]; + [bezier2Path addLineToPoint: CGPointMake(24.89, 30.89)]; + [bezier2Path addCurveToPoint: CGPointMake(29.35, 31.93) controlPoint1: CGPointMake(26.72, 30.89) controlPoint2: CGPointMake(28.45, 30.89)]; + [bezier2Path addCurveToPoint: CGPointMake(29.84, 34.76) controlPoint1: CGPointMake(29.88, 32.55) controlPoint2: CGPointMake(30.04, 33.48)]; + [bezier2Path addLineToPoint: CGPointMake(29.84, 34.76)]; + [bezier2Path closePath]; + [bezier2Path moveToPoint: CGPointMake(18.5, 25)]; + [bezier2Path addCurveToPoint: CGPointMake(17, 26.5) controlPoint1: CGPointMake(17.81, 25) controlPoint2: CGPointMake(17.11, 25.82)]; + [bezier2Path addLineToPoint: CGPointMake(13, 53)]; + [bezier2Path addCurveToPoint: CGPointMake(14, 54) controlPoint1: CGPointMake(12.92, 53.51) controlPoint2: CGPointMake(13.48, 54)]; + [bezier2Path addLineToPoint: CGPointMake(18.5, 54)]; + [bezier2Path addCurveToPoint: CGPointMake(20, 52.5) controlPoint1: CGPointMake(19.19, 54) controlPoint2: CGPointMake(19.89, 53.18)]; + [bezier2Path addLineToPoint: CGPointMake(21.2, 45.22)]; + [bezier2Path addCurveToPoint: CGPointMake(22.59, 44.03) controlPoint1: CGPointMake(21.31, 44.54) controlPoint2: CGPointMake(21.9, 44.03)]; + [bezier2Path addLineToPoint: CGPointMake(25.81, 44.03)]; + [bezier2Path addCurveToPoint: CGPointMake(37.37, 34.4) controlPoint1: CGPointMake(32.5, 44.03) controlPoint2: CGPointMake(36.36, 40.8)]; + [bezier2Path addCurveToPoint: CGPointMake(36.07, 27.85) controlPoint1: CGPointMake(37.82, 31.59) controlPoint2: CGPointMake(37.39, 29.39)]; + [bezier2Path addCurveToPoint: CGPointMake(28.5, 25) controlPoint1: CGPointMake(34.63, 26.16) controlPoint2: CGPointMake(31.9, 25)]; + [bezier2Path addLineToPoint: CGPointMake(18.5, 25)]; + [bezier2Path closePath]; + [bezier2Path moveToPoint: CGPointMake(52.25, 44.09)]; + [bezier2Path addCurveToPoint: CGPointMake(46.76, 48.73) controlPoint1: CGPointMake(51.78, 46.87) controlPoint2: CGPointMake(49.57, 48.73)]; + [bezier2Path addCurveToPoint: CGPointMake(43.49, 47.42) controlPoint1: CGPointMake(45.35, 48.73) controlPoint2: CGPointMake(44.22, 48.28)]; + [bezier2Path addCurveToPoint: CGPointMake(42.73, 44.01) controlPoint1: CGPointMake(42.77, 46.57) controlPoint2: CGPointMake(42.5, 45.36)]; + [bezier2Path addCurveToPoint: CGPointMake(48.18, 39.33) controlPoint1: CGPointMake(43.17, 41.26) controlPoint2: CGPointMake(45.41, 39.33)]; + [bezier2Path addCurveToPoint: CGPointMake(51.42, 40.66) controlPoint1: CGPointMake(49.56, 39.33) controlPoint2: CGPointMake(50.69, 39.79)]; + [bezier2Path addCurveToPoint: CGPointMake(52.25, 44.09) controlPoint1: CGPointMake(52.17, 41.53) controlPoint2: CGPointMake(52.46, 42.75)]; + [bezier2Path closePath]; + [bezier2Path moveToPoint: CGPointMake(54.5, 34)]; + [bezier2Path addCurveToPoint: CGPointMake(53.5, 35) controlPoint1: CGPointMake(54.08, 34) controlPoint2: CGPointMake(53.56, 34.58)]; + [bezier2Path addLineToPoint: CGPointMake(53.2, 36.57)]; + [bezier2Path addLineToPoint: CGPointMake(52.85, 36.07)]; + [bezier2Path addCurveToPoint: CGPointMake(47.07, 34) controlPoint1: CGPointMake(51.79, 34.52) controlPoint2: CGPointMake(49.43, 34)]; + [bezier2Path addCurveToPoint: CGPointMake(36.15, 43.92) controlPoint1: CGPointMake(41.67, 34) controlPoint2: CGPointMake(37.05, 38.13)]; + [bezier2Path addCurveToPoint: CGPointMake(37.97, 51.49) controlPoint1: CGPointMake(35.68, 46.81) controlPoint2: CGPointMake(36.34, 49.57)]; + [bezier2Path addCurveToPoint: CGPointMake(44.13, 54) controlPoint1: CGPointMake(39.46, 53.26) controlPoint2: CGPointMake(41.59, 54)]; + [bezier2Path addCurveToPoint: CGPointMake(50.91, 51.18) controlPoint1: CGPointMake(48.49, 54) controlPoint2: CGPointMake(50.91, 51.18)]; + [bezier2Path addLineToPoint: CGPointMake(50.5, 53)]; + [bezier2Path addCurveToPoint: CGPointMake(51.5, 54) controlPoint1: CGPointMake(50.42, 53.52) controlPoint2: CGPointMake(50.98, 54)]; + [bezier2Path addLineToPoint: CGPointMake(56, 54)]; + [bezier2Path addCurveToPoint: CGPointMake(57.5, 52.5) controlPoint1: CGPointMake(56.7, 54) controlPoint2: CGPointMake(57.39, 53.2)]; + [bezier2Path addLineToPoint: CGPointMake(60, 35)]; + [bezier2Path addCurveToPoint: CGPointMake(59, 34) controlPoint1: CGPointMake(60.08, 34.48) controlPoint2: CGPointMake(59.52, 34)]; + [bezier2Path addLineToPoint: CGPointMake(54.5, 34)]; + [bezier2Path closePath]; + [bezier2Path moveToPoint: CGPointMake(80, 34)]; + [bezier2Path addCurveToPoint: CGPointMake(79, 35.04) controlPoint1: CGPointMake(79.67, 34) controlPoint2: CGPointMake(79.22, 34.24)]; + [bezier2Path addLineToPoint: CGPointMake(72, 44.4)]; + [bezier2Path addLineToPoint: CGPointMake(69, 35.04)]; + [bezier2Path addCurveToPoint: CGPointMake(68, 34) controlPoint1: CGPointMake(68.97, 34.42) controlPoint2: CGPointMake(68.41, 34)]; + [bezier2Path addLineToPoint: CGPointMake(63, 34)]; + [bezier2Path addCurveToPoint: CGPointMake(62, 35.04) controlPoint1: CGPointMake(62.27, 34) controlPoint2: CGPointMake(61.86, 34.58)]; + [bezier2Path addLineToPoint: CGPointMake(68, 51.68)]; + [bezier2Path addLineToPoint: CGPointMake(62, 58.96)]; + [bezier2Path addCurveToPoint: CGPointMake(63, 60) controlPoint1: CGPointMake(61.97, 59.21) controlPoint2: CGPointMake(62.38, 60)]; + [bezier2Path addLineToPoint: CGPointMake(68, 60)]; + [bezier2Path addCurveToPoint: CGPointMake(69, 58.96) controlPoint1: CGPointMake(68.54, 60) controlPoint2: CGPointMake(68.98, 59.77)]; + [bezier2Path addLineToPoint: CGPointMake(86, 35.04)]; + [bezier2Path addCurveToPoint: CGPointMake(85, 34) controlPoint1: CGPointMake(86.24, 34.79) controlPoint2: CGPointMake(85.83, 34)]; + [bezier2Path addLineToPoint: CGPointMake(80, 34)]; + [bezier2Path closePath]; + bezier2Path.miterLimit = 4; + + bezier2Path.usesEvenOddFillRule = YES; + + [payColor setFill]; + [bezier2Path fill]; + } + } + } + } else { + //// Color Declarations + UIColor* color0 = [self.theme palBlue]; + UIColor* color1 = [self.theme payBlue]; + + //// PayPal + { + //// Group 2 + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(189.07, 1.49)]; + [bezierPath addLineToPoint: CGPointMake(167.92, 1.49)]; + [bezierPath addCurveToPoint: CGPointMake(165.02, 3.97) controlPoint1: CGPointMake(166.48, 1.49) controlPoint2: CGPointMake(165.24, 2.54)]; + [bezierPath addLineToPoint: CGPointMake(156.47, 58.2)]; + [bezierPath addCurveToPoint: CGPointMake(158.21, 60.24) controlPoint1: CGPointMake(156.3, 59.27) controlPoint2: CGPointMake(157.12, 60.24)]; + [bezierPath addLineToPoint: CGPointMake(169.06, 60.24)]; + [bezierPath addCurveToPoint: CGPointMake(171.09, 58.5) controlPoint1: CGPointMake(170.07, 60.24) controlPoint2: CGPointMake(170.93, 59.5)]; + [bezierPath addLineToPoint: CGPointMake(173.52, 43.13)]; + [bezierPath addCurveToPoint: CGPointMake(176.42, 40.65) controlPoint1: CGPointMake(173.74, 41.7) controlPoint2: CGPointMake(174.97, 40.65)]; + [bezierPath addLineToPoint: CGPointMake(183.11, 40.65)]; + [bezierPath addCurveToPoint: CGPointMake(207.18, 20.54) controlPoint1: CGPointMake(197.04, 40.65) controlPoint2: CGPointMake(205.08, 33.91)]; + [bezierPath addCurveToPoint: CGPointMake(204.49, 6.89) controlPoint1: CGPointMake(208.13, 14.7) controlPoint2: CGPointMake(207.22, 10.11)]; + [bezierPath addCurveToPoint: CGPointMake(189.07, 1.49) controlPoint1: CGPointMake(201.48, 3.36) controlPoint2: CGPointMake(196.15, 1.49)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(191.51, 21.3)]; + [bezierPath addCurveToPoint: CGPointMake(178.95, 28.89) controlPoint1: CGPointMake(190.36, 28.89) controlPoint2: CGPointMake(184.56, 28.89)]; + [bezierPath addLineToPoint: CGPointMake(175.76, 28.89)]; + [bezierPath addLineToPoint: CGPointMake(178, 14.71)]; + [bezierPath addCurveToPoint: CGPointMake(179.74, 13.23) controlPoint1: CGPointMake(178.13, 13.86) controlPoint2: CGPointMake(178.87, 13.23)]; + [bezierPath addLineToPoint: CGPointMake(181.2, 13.23)]; + [bezierPath addCurveToPoint: CGPointMake(190.48, 15.4) controlPoint1: CGPointMake(185.02, 13.23) controlPoint2: CGPointMake(188.62, 13.23)]; + [bezierPath addCurveToPoint: CGPointMake(191.51, 21.3) controlPoint1: CGPointMake(191.6, 16.7) controlPoint2: CGPointMake(191.93, 18.63)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + [color0 setFill]; + [bezierPath fill]; + + + //// Bezier 2 Drawing + UIBezierPath* bezier2Path = [UIBezierPath bezierPath]; + [bezier2Path moveToPoint: CGPointMake(38.22, 1.49)]; + [bezier2Path addLineToPoint: CGPointMake(17.07, 1.49)]; + [bezier2Path addCurveToPoint: CGPointMake(14.17, 3.97) controlPoint1: CGPointMake(15.62, 1.49) controlPoint2: CGPointMake(14.39, 2.54)]; + [bezier2Path addLineToPoint: CGPointMake(5.61, 58.2)]; + [bezier2Path addCurveToPoint: CGPointMake(7.36, 60.24) controlPoint1: CGPointMake(5.45, 59.27) controlPoint2: CGPointMake(6.27, 60.24)]; + [bezier2Path addLineToPoint: CGPointMake(17.45, 60.24)]; + [bezier2Path addCurveToPoint: CGPointMake(20.36, 57.76) controlPoint1: CGPointMake(18.9, 60.24) controlPoint2: CGPointMake(20.13, 59.19)]; + [bezier2Path addLineToPoint: CGPointMake(22.67, 43.13)]; + [bezier2Path addCurveToPoint: CGPointMake(25.57, 40.65) controlPoint1: CGPointMake(22.89, 41.7) controlPoint2: CGPointMake(24.12, 40.65)]; + [bezier2Path addLineToPoint: CGPointMake(32.26, 40.65)]; + [bezier2Path addCurveToPoint: CGPointMake(56.33, 20.54) controlPoint1: CGPointMake(46.19, 40.65) controlPoint2: CGPointMake(54.23, 33.91)]; + [bezier2Path addCurveToPoint: CGPointMake(53.64, 6.89) controlPoint1: CGPointMake(57.28, 14.7) controlPoint2: CGPointMake(56.37, 10.11)]; + [bezier2Path addCurveToPoint: CGPointMake(38.22, 1.49) controlPoint1: CGPointMake(50.63, 3.36) controlPoint2: CGPointMake(45.3, 1.49)]; + [bezier2Path closePath]; + [bezier2Path moveToPoint: CGPointMake(40.66, 21.3)]; + [bezier2Path addCurveToPoint: CGPointMake(28.1, 28.89) controlPoint1: CGPointMake(39.51, 28.89) controlPoint2: CGPointMake(33.71, 28.89)]; + [bezier2Path addLineToPoint: CGPointMake(24.91, 28.89)]; + [bezier2Path addLineToPoint: CGPointMake(27.15, 14.71)]; + [bezier2Path addCurveToPoint: CGPointMake(28.89, 13.23) controlPoint1: CGPointMake(27.28, 13.86) controlPoint2: CGPointMake(28.02, 13.23)]; + [bezier2Path addLineToPoint: CGPointMake(30.35, 13.23)]; + [bezier2Path addCurveToPoint: CGPointMake(39.63, 15.4) controlPoint1: CGPointMake(34.17, 13.23) controlPoint2: CGPointMake(37.77, 13.23)]; + [bezier2Path addCurveToPoint: CGPointMake(40.66, 21.3) controlPoint1: CGPointMake(40.74, 16.7) controlPoint2: CGPointMake(41.08, 18.63)]; + [bezier2Path closePath]; + bezier2Path.miterLimit = 4; + + [color1 setFill]; + [bezier2Path fill]; + + + //// Bezier 3 Drawing + UIBezierPath* bezier3Path = [UIBezierPath bezierPath]; + [bezier3Path moveToPoint: CGPointMake(101.44, 21.06)]; + [bezier3Path addLineToPoint: CGPointMake(91.31, 21.06)]; + [bezier3Path addCurveToPoint: CGPointMake(89.57, 22.54) controlPoint1: CGPointMake(90.44, 21.06) controlPoint2: CGPointMake(89.7, 21.69)]; + [bezier3Path addLineToPoint: CGPointMake(89.12, 25.38)]; + [bezier3Path addLineToPoint: CGPointMake(88.41, 24.35)]; + [bezier3Path addCurveToPoint: CGPointMake(76.45, 20.1) controlPoint1: CGPointMake(86.22, 21.17) controlPoint2: CGPointMake(81.33, 20.1)]; + [bezier3Path addCurveToPoint: CGPointMake(53.85, 40.47) controlPoint1: CGPointMake(65.26, 20.1) controlPoint2: CGPointMake(55.71, 28.58)]; + [bezier3Path addCurveToPoint: CGPointMake(57.62, 56.03) controlPoint1: CGPointMake(52.88, 46.41) controlPoint2: CGPointMake(54.25, 52.08)]; + [bezier3Path addCurveToPoint: CGPointMake(70.37, 61.18) controlPoint1: CGPointMake(60.71, 59.67) controlPoint2: CGPointMake(65.12, 61.18)]; + [bezier3Path addCurveToPoint: CGPointMake(84.39, 55.39) controlPoint1: CGPointMake(79.39, 61.18) controlPoint2: CGPointMake(84.39, 55.39)]; + [bezier3Path addLineToPoint: CGPointMake(83.94, 58.2)]; + [bezier3Path addCurveToPoint: CGPointMake(85.68, 60.24) controlPoint1: CGPointMake(83.77, 59.27) controlPoint2: CGPointMake(84.6, 60.24)]; + [bezier3Path addLineToPoint: CGPointMake(94.8, 60.24)]; + [bezier3Path addCurveToPoint: CGPointMake(97.7, 57.76) controlPoint1: CGPointMake(96.25, 60.24) controlPoint2: CGPointMake(97.48, 59.19)]; + [bezier3Path addLineToPoint: CGPointMake(103.18, 23.09)]; + [bezier3Path addCurveToPoint: CGPointMake(101.44, 21.06) controlPoint1: CGPointMake(103.35, 22.02) controlPoint2: CGPointMake(102.52, 21.06)]; + [bezier3Path closePath]; + [bezier3Path moveToPoint: CGPointMake(87.32, 40.77)]; + [bezier3Path addCurveToPoint: CGPointMake(75.89, 50.44) controlPoint1: CGPointMake(86.34, 46.55) controlPoint2: CGPointMake(81.75, 50.44)]; + [bezier3Path addCurveToPoint: CGPointMake(69.09, 47.71) controlPoint1: CGPointMake(72.95, 50.44) controlPoint2: CGPointMake(70.6, 49.49)]; + [bezier3Path addCurveToPoint: CGPointMake(67.5, 40.59) controlPoint1: CGPointMake(67.59, 45.93) controlPoint2: CGPointMake(67.03, 43.4)]; + [bezier3Path addCurveToPoint: CGPointMake(78.85, 30.85) controlPoint1: CGPointMake(68.42, 34.86) controlPoint2: CGPointMake(73.08, 30.85)]; + [bezier3Path addCurveToPoint: CGPointMake(85.61, 33.61) controlPoint1: CGPointMake(81.73, 30.85) controlPoint2: CGPointMake(84.07, 31.8)]; + [bezier3Path addCurveToPoint: CGPointMake(87.32, 40.77) controlPoint1: CGPointMake(87.16, 35.42) controlPoint2: CGPointMake(87.77, 37.97)]; + [bezier3Path closePath]; + bezier3Path.miterLimit = 4; + + [color1 setFill]; + [bezier3Path fill]; + + + //// Bezier 4 Drawing + UIBezierPath* bezier4Path = [UIBezierPath bezierPath]; + [bezier4Path moveToPoint: CGPointMake(252.29, 21.06)]; + [bezier4Path addLineToPoint: CGPointMake(242.16, 21.06)]; + [bezier4Path addCurveToPoint: CGPointMake(240.42, 22.54) controlPoint1: CGPointMake(241.29, 21.06) controlPoint2: CGPointMake(240.55, 21.69)]; + [bezier4Path addLineToPoint: CGPointMake(239.97, 25.38)]; + [bezier4Path addLineToPoint: CGPointMake(239.27, 24.35)]; + [bezier4Path addCurveToPoint: CGPointMake(227.3, 20.1) controlPoint1: CGPointMake(237.07, 21.17) controlPoint2: CGPointMake(232.18, 20.1)]; + [bezier4Path addCurveToPoint: CGPointMake(204.7, 40.47) controlPoint1: CGPointMake(216.12, 20.1) controlPoint2: CGPointMake(206.56, 28.58)]; + [bezier4Path addCurveToPoint: CGPointMake(208.47, 56.03) controlPoint1: CGPointMake(203.73, 46.41) controlPoint2: CGPointMake(205.1, 52.08)]; + [bezier4Path addCurveToPoint: CGPointMake(221.22, 61.18) controlPoint1: CGPointMake(211.56, 59.67) controlPoint2: CGPointMake(215.97, 61.18)]; + [bezier4Path addCurveToPoint: CGPointMake(235.24, 55.39) controlPoint1: CGPointMake(230.24, 61.18) controlPoint2: CGPointMake(235.24, 55.39)]; + [bezier4Path addLineToPoint: CGPointMake(234.79, 58.2)]; + [bezier4Path addCurveToPoint: CGPointMake(236.53, 60.24) controlPoint1: CGPointMake(234.62, 59.27) controlPoint2: CGPointMake(235.45, 60.24)]; + [bezier4Path addLineToPoint: CGPointMake(245.65, 60.24)]; + [bezier4Path addCurveToPoint: CGPointMake(248.56, 57.76) controlPoint1: CGPointMake(247.1, 60.24) controlPoint2: CGPointMake(248.33, 59.19)]; + [bezier4Path addLineToPoint: CGPointMake(254.03, 23.09)]; + [bezier4Path addCurveToPoint: CGPointMake(252.29, 21.06) controlPoint1: CGPointMake(254.2, 22.02) controlPoint2: CGPointMake(253.37, 21.06)]; + [bezier4Path closePath]; + [bezier4Path moveToPoint: CGPointMake(238.17, 40.77)]; + [bezier4Path addCurveToPoint: CGPointMake(226.74, 50.44) controlPoint1: CGPointMake(237.19, 46.55) controlPoint2: CGPointMake(232.6, 50.44)]; + [bezier4Path addCurveToPoint: CGPointMake(219.94, 47.71) controlPoint1: CGPointMake(223.8, 50.44) controlPoint2: CGPointMake(221.45, 49.49)]; + [bezier4Path addCurveToPoint: CGPointMake(218.35, 40.59) controlPoint1: CGPointMake(218.44, 45.93) controlPoint2: CGPointMake(217.88, 43.4)]; + [bezier4Path addCurveToPoint: CGPointMake(229.7, 30.85) controlPoint1: CGPointMake(219.26, 34.86) controlPoint2: CGPointMake(223.93, 30.85)]; + [bezier4Path addCurveToPoint: CGPointMake(236.46, 33.61) controlPoint1: CGPointMake(232.58, 30.85) controlPoint2: CGPointMake(234.91, 31.8)]; + [bezier4Path addCurveToPoint: CGPointMake(238.17, 40.77) controlPoint1: CGPointMake(238.01, 35.42) controlPoint2: CGPointMake(238.62, 37.97)]; + [bezier4Path closePath]; + bezier4Path.miterLimit = 4; + + [color0 setFill]; + [bezier4Path fill]; + + + //// Bezier 5 Drawing + UIBezierPath* bezier5Path = [UIBezierPath bezierPath]; + [bezier5Path moveToPoint: CGPointMake(155.38, 21.06)]; + [bezier5Path addLineToPoint: CGPointMake(145.2, 21.06)]; + [bezier5Path addCurveToPoint: CGPointMake(142.76, 22.34) controlPoint1: CGPointMake(144.22, 21.06) controlPoint2: CGPointMake(143.31, 21.54)]; + [bezier5Path addLineToPoint: CGPointMake(128.72, 43.02)]; + [bezier5Path addLineToPoint: CGPointMake(122.77, 23.15)]; + [bezier5Path addCurveToPoint: CGPointMake(119.96, 21.06) controlPoint1: CGPointMake(122.4, 21.91) controlPoint2: CGPointMake(121.26, 21.06)]; + [bezier5Path addLineToPoint: CGPointMake(109.95, 21.06)]; + [bezier5Path addCurveToPoint: CGPointMake(108.28, 23.39) controlPoint1: CGPointMake(108.74, 21.06) controlPoint2: CGPointMake(107.89, 22.24)]; + [bezier5Path addLineToPoint: CGPointMake(119.49, 56.29)]; + [bezier5Path addLineToPoint: CGPointMake(108.95, 71.16)]; + [bezier5Path addCurveToPoint: CGPointMake(110.39, 73.95) controlPoint1: CGPointMake(108.12, 72.33) controlPoint2: CGPointMake(108.96, 73.95)]; + [bezier5Path addLineToPoint: CGPointMake(120.56, 73.95)]; + [bezier5Path addCurveToPoint: CGPointMake(122.97, 72.68) controlPoint1: CGPointMake(121.52, 73.95) controlPoint2: CGPointMake(122.42, 73.47)]; + [bezier5Path addLineToPoint: CGPointMake(156.82, 23.82)]; + [bezier5Path addCurveToPoint: CGPointMake(155.38, 21.06) controlPoint1: CGPointMake(157.63, 22.65) controlPoint2: CGPointMake(156.8, 21.06)]; + [bezier5Path closePath]; + bezier5Path.miterLimit = 4; + + [color1 setFill]; + [bezier5Path fill]; + + + //// Bezier 6 Drawing + UIBezierPath* bezier6Path = [UIBezierPath bezierPath]; + [bezier6Path moveToPoint: CGPointMake(264.22, 2.98)]; + [bezier6Path addLineToPoint: CGPointMake(255.54, 58.21)]; + [bezier6Path addCurveToPoint: CGPointMake(257.29, 60.24) controlPoint1: CGPointMake(255.38, 59.27) controlPoint2: CGPointMake(256.2, 60.24)]; + [bezier6Path addLineToPoint: CGPointMake(266.01, 60.24)]; + [bezier6Path addCurveToPoint: CGPointMake(268.92, 57.76) controlPoint1: CGPointMake(267.46, 60.24) controlPoint2: CGPointMake(268.69, 59.19)]; + [bezier6Path addLineToPoint: CGPointMake(277.48, 3.53)]; + [bezier6Path addCurveToPoint: CGPointMake(275.73, 1.49) controlPoint1: CGPointMake(277.64, 2.46) controlPoint2: CGPointMake(276.82, 1.49)]; + [bezier6Path addLineToPoint: CGPointMake(265.96, 1.49)]; + [bezier6Path addCurveToPoint: CGPointMake(264.22, 2.98) controlPoint1: CGPointMake(265.1, 1.49) controlPoint2: CGPointMake(264.36, 2.12)]; + [bezier6Path closePath]; + bezier6Path.miterLimit = 4; + + [color0 setFill]; + [bezier6Path fill]; + } + } + } +} + +- (void)updateConstraints { + NSLayoutConstraint *aspectRatioConstraint = [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeWidth + relatedBy:NSLayoutRelationEqual + toItem:self + attribute:NSLayoutAttributeHeight + multiplier:(self.artDimensions.width / self.artDimensions.height) + constant:0.0f]; + aspectRatioConstraint.priority = UILayoutPriorityRequired; + + [self addConstraint:aspectRatioConstraint]; + + [super updateConstraints]; +} + +- (UILayoutPriority)contentCompressionResistancePriorityForAxis:(__unused UILayoutConstraintAxis)axis { + return UILayoutPriorityRequired; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalWordmarkVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalWordmarkVectorArtView.h new file mode 100644 index 0000000..aaa4bcc --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalWordmarkVectorArtView.h @@ -0,0 +1,28 @@ +#import +#import "BTUIVectorArtView.h" + +@class BTUI; + +@interface BTUIPayPalWordmarkVectorArtView : BTUIVectorArtView + +@property (nonatomic, strong) BTUI *theme; + +/** + @brief Initializes a PayPal Wordmark with padding + + @discussion This view includes built-in padding to ensure consistent typographical baseline alignment with Venmo and Coinbase wordmarks. + + @return A PayPal Wordmark with padding +*/ +- (instancetype)initWithPadding; + +/** + @brief Initializes a PayPal Wordmark + + @discusion This view does not include built-in padding. + + @return A PayPal Wordmark +*/ +- (instancetype)init; + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalWordmarkVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalWordmarkVectorArtView.m new file mode 100644 index 0000000..fad6788 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIPayPalWordmarkVectorArtView.m @@ -0,0 +1,375 @@ +#import "BTUIPayPalWordmarkVectorArtView.h" +#import "BTUI.h" + +@interface BTUIPayPalWordmarkVectorArtView () +@property (nonatomic, assign) BOOL includePadding; +@end + +@implementation BTUIPayPalWordmarkVectorArtView + +- (instancetype)initWithPadding { + self = [super init]; + if (self) { + self.includePadding = YES; + [self setupWithArtDimensions:CGSizeMake(200, 50)]; + } + return self; +} + +- (instancetype)init { + self = [super init]; + if (self) { + [self setupWithArtDimensions:CGSizeMake(284.0f, 80.0f)]; + } + return self; +} + +- (void)setupWithArtDimensions:(CGSize)artDimensions { + self.artDimensions = artDimensions; + self.opaque = NO; + self.theme = [BTUI braintreeTheme]; +} + +- (void)drawArt +{ + if (!self.includePadding) { + [self drawWithoutPadding]; + } else { + [self drawWithPadding]; + } +} + +- (void)drawWithoutPadding { +} + +- (void)drawWithPadding { + //// Color Declarations + UIColor* color2 = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 0.68]; + UIColor* color3 = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 0.7]; + UIColor* color1 = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + + //// Page-1 + { + //// paypal_monogram-wordmark-3d-copy + { + //// Group 4 + { + //// logo + { + //// wordmark + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(81.45, 22.34)]; + [bezierPath addCurveToPoint: CGPointMake(78.78, 24) controlPoint1: CGPointMake(81.2, 24) controlPoint2: CGPointMake(79.97, 24)]; + [bezierPath addLineToPoint: CGPointMake(78.1, 24)]; + [bezierPath addLineToPoint: CGPointMake(78.58, 20.9)]; + [bezierPath addCurveToPoint: CGPointMake(78.95, 20.57) controlPoint1: CGPointMake(78.61, 20.71) controlPoint2: CGPointMake(78.76, 20.57)]; + [bezierPath addLineToPoint: CGPointMake(79.26, 20.57)]; + [bezierPath addCurveToPoint: CGPointMake(81.23, 21.05) controlPoint1: CGPointMake(80.07, 20.57) controlPoint2: CGPointMake(80.83, 20.57)]; + [bezierPath addCurveToPoint: CGPointMake(81.45, 22.34) controlPoint1: CGPointMake(81.46, 21.33) controlPoint2: CGPointMake(81.54, 21.75)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(80.93, 18)]; + [bezierPath addLineToPoint: CGPointMake(76.44, 18)]; + [bezierPath addCurveToPoint: CGPointMake(75.82, 18.54) controlPoint1: CGPointMake(76.13, 18) controlPoint2: CGPointMake(75.87, 18.23)]; + [bezierPath addLineToPoint: CGPointMake(74, 30.42)]; + [bezierPath addCurveToPoint: CGPointMake(74.37, 30.87) controlPoint1: CGPointMake(73.97, 30.66) controlPoint2: CGPointMake(74.14, 30.87)]; + [bezierPath addLineToPoint: CGPointMake(76.68, 30.87)]; + [bezierPath addCurveToPoint: CGPointMake(77.11, 30.49) controlPoint1: CGPointMake(76.89, 30.87) controlPoint2: CGPointMake(77.08, 30.71)]; + [bezierPath addLineToPoint: CGPointMake(77.63, 27.12)]; + [bezierPath addCurveToPoint: CGPointMake(78.24, 26.58) controlPoint1: CGPointMake(77.67, 26.81) controlPoint2: CGPointMake(77.93, 26.58)]; + [bezierPath addLineToPoint: CGPointMake(79.66, 26.58)]; + [bezierPath addCurveToPoint: CGPointMake(84.77, 22.17) controlPoint1: CGPointMake(82.62, 26.58) controlPoint2: CGPointMake(84.33, 25.1)]; + [bezierPath addCurveToPoint: CGPointMake(84.2, 19.18) controlPoint1: CGPointMake(84.98, 20.89) controlPoint2: CGPointMake(84.78, 19.89)]; + [bezierPath addCurveToPoint: CGPointMake(80.93, 18) controlPoint1: CGPointMake(83.56, 18.41) controlPoint2: CGPointMake(82.43, 18)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + bezierPath.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezierPath fill]; + + + //// Bezier 2 Drawing + UIBezierPath* bezier2Path = [UIBezierPath bezierPath]; + [bezier2Path moveToPoint: CGPointMake(49.45, 22.34)]; + [bezier2Path addCurveToPoint: CGPointMake(46.78, 24) controlPoint1: CGPointMake(49.2, 24) controlPoint2: CGPointMake(47.97, 24)]; + [bezier2Path addLineToPoint: CGPointMake(46.1, 24)]; + [bezier2Path addLineToPoint: CGPointMake(46.58, 20.9)]; + [bezier2Path addCurveToPoint: CGPointMake(46.95, 20.57) controlPoint1: CGPointMake(46.6, 20.71) controlPoint2: CGPointMake(46.76, 20.57)]; + [bezier2Path addLineToPoint: CGPointMake(47.26, 20.57)]; + [bezier2Path addCurveToPoint: CGPointMake(49.23, 21.05) controlPoint1: CGPointMake(48.07, 20.57) controlPoint2: CGPointMake(48.83, 20.57)]; + [bezier2Path addCurveToPoint: CGPointMake(49.45, 22.34) controlPoint1: CGPointMake(49.46, 21.33) controlPoint2: CGPointMake(49.54, 21.75)]; + [bezier2Path closePath]; + [bezier2Path moveToPoint: CGPointMake(48.93, 18)]; + [bezier2Path addLineToPoint: CGPointMake(44.44, 18)]; + [bezier2Path addCurveToPoint: CGPointMake(43.82, 18.54) controlPoint1: CGPointMake(44.13, 18) controlPoint2: CGPointMake(43.87, 18.23)]; + [bezier2Path addLineToPoint: CGPointMake(42, 30.42)]; + [bezier2Path addCurveToPoint: CGPointMake(42.37, 30.87) controlPoint1: CGPointMake(41.97, 30.66) controlPoint2: CGPointMake(42.14, 30.87)]; + [bezier2Path addLineToPoint: CGPointMake(44.52, 30.87)]; + [bezier2Path addCurveToPoint: CGPointMake(45.13, 30.32) controlPoint1: CGPointMake(44.83, 30.87) controlPoint2: CGPointMake(45.09, 30.64)]; + [bezier2Path addLineToPoint: CGPointMake(45.62, 27.12)]; + [bezier2Path addCurveToPoint: CGPointMake(46.24, 26.58) controlPoint1: CGPointMake(45.67, 26.81) controlPoint2: CGPointMake(45.93, 26.58)]; + [bezier2Path addLineToPoint: CGPointMake(47.66, 26.58)]; + [bezier2Path addCurveToPoint: CGPointMake(52.77, 22.17) controlPoint1: CGPointMake(50.62, 26.58) controlPoint2: CGPointMake(52.33, 25.1)]; + [bezier2Path addCurveToPoint: CGPointMake(52.2, 19.18) controlPoint1: CGPointMake(52.97, 20.89) controlPoint2: CGPointMake(52.78, 19.89)]; + [bezier2Path addCurveToPoint: CGPointMake(48.93, 18) controlPoint1: CGPointMake(51.56, 18.41) controlPoint2: CGPointMake(50.43, 18)]; + [bezier2Path closePath]; + bezier2Path.miterLimit = 4; + + bezier2Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier2Path fill]; + + + //// Bezier 3 Drawing + UIBezierPath* bezier3Path = [UIBezierPath bezierPath]; + [bezier3Path moveToPoint: CGPointMake(59.17, 26.53)]; + [bezier3Path addCurveToPoint: CGPointMake(56.75, 28.64) controlPoint1: CGPointMake(58.97, 27.79) controlPoint2: CGPointMake(57.99, 28.64)]; + [bezier3Path addCurveToPoint: CGPointMake(55.3, 28.05) controlPoint1: CGPointMake(56.12, 28.64) controlPoint2: CGPointMake(55.62, 28.44)]; + [bezier3Path addCurveToPoint: CGPointMake(54.97, 26.49) controlPoint1: CGPointMake(54.98, 27.66) controlPoint2: CGPointMake(54.86, 27.1)]; + [bezier3Path addCurveToPoint: CGPointMake(57.38, 24.35) controlPoint1: CGPointMake(55.16, 25.23) controlPoint2: CGPointMake(56.15, 24.35)]; + [bezier3Path addCurveToPoint: CGPointMake(58.81, 24.96) controlPoint1: CGPointMake(57.99, 24.35) controlPoint2: CGPointMake(58.48, 24.56)]; + [bezier3Path addCurveToPoint: CGPointMake(59.17, 26.53) controlPoint1: CGPointMake(59.14, 25.36) controlPoint2: CGPointMake(59.27, 25.91)]; + [bezier3Path closePath]; + [bezier3Path moveToPoint: CGPointMake(62.17, 22.21)]; + [bezier3Path addLineToPoint: CGPointMake(60.02, 22.21)]; + [bezier3Path addCurveToPoint: CGPointMake(59.65, 22.54) controlPoint1: CGPointMake(59.84, 22.21) controlPoint2: CGPointMake(59.68, 22.35)]; + [bezier3Path addLineToPoint: CGPointMake(59.56, 23.15)]; + [bezier3Path addLineToPoint: CGPointMake(59.41, 22.93)]; + [bezier3Path addCurveToPoint: CGPointMake(56.87, 22) controlPoint1: CGPointMake(58.94, 22.23) controlPoint2: CGPointMake(57.9, 22)]; + [bezier3Path addCurveToPoint: CGPointMake(52.06, 26.46) controlPoint1: CGPointMake(54.49, 22) controlPoint2: CGPointMake(52.46, 23.86)]; + [bezier3Path addCurveToPoint: CGPointMake(52.87, 29.87) controlPoint1: CGPointMake(51.86, 27.76) controlPoint2: CGPointMake(52.15, 29)]; + [bezier3Path addCurveToPoint: CGPointMake(55.57, 31) controlPoint1: CGPointMake(53.52, 30.67) controlPoint2: CGPointMake(54.46, 31)]; + [bezier3Path addCurveToPoint: CGPointMake(58.55, 29.73) controlPoint1: CGPointMake(57.49, 31) controlPoint2: CGPointMake(58.55, 29.73)]; + [bezier3Path addLineToPoint: CGPointMake(58.46, 30.34)]; + [bezier3Path addCurveToPoint: CGPointMake(58.82, 30.79) controlPoint1: CGPointMake(58.42, 30.58) controlPoint2: CGPointMake(58.59, 30.79)]; + [bezier3Path addLineToPoint: CGPointMake(60.76, 30.79)]; + [bezier3Path addCurveToPoint: CGPointMake(61.38, 30.25) controlPoint1: CGPointMake(61.07, 30.79) controlPoint2: CGPointMake(61.33, 30.56)]; + [bezier3Path addLineToPoint: CGPointMake(62.54, 22.65)]; + [bezier3Path addCurveToPoint: CGPointMake(62.17, 22.21) controlPoint1: CGPointMake(62.58, 22.42) controlPoint2: CGPointMake(62.4, 22.21)]; + [bezier3Path closePath]; + bezier3Path.miterLimit = 4; + + bezier3Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier3Path fill]; + + + //// Bezier 4 Drawing + UIBezierPath* bezier4Path = [UIBezierPath bezierPath]; + [bezier4Path moveToPoint: CGPointMake(91.18, 26.53)]; + [bezier4Path addCurveToPoint: CGPointMake(88.75, 28.64) controlPoint1: CGPointMake(90.97, 27.79) controlPoint2: CGPointMake(89.99, 28.64)]; + [bezier4Path addCurveToPoint: CGPointMake(87.3, 28.05) controlPoint1: CGPointMake(88.12, 28.64) controlPoint2: CGPointMake(87.62, 28.44)]; + [bezier4Path addCurveToPoint: CGPointMake(86.97, 26.49) controlPoint1: CGPointMake(86.99, 27.66) controlPoint2: CGPointMake(86.87, 27.1)]; + [bezier4Path addCurveToPoint: CGPointMake(89.38, 24.35) controlPoint1: CGPointMake(87.16, 25.23) controlPoint2: CGPointMake(88.15, 24.35)]; + [bezier4Path addCurveToPoint: CGPointMake(90.81, 24.96) controlPoint1: CGPointMake(89.99, 24.35) controlPoint2: CGPointMake(90.48, 24.56)]; + [bezier4Path addCurveToPoint: CGPointMake(91.18, 26.53) controlPoint1: CGPointMake(91.14, 25.36) controlPoint2: CGPointMake(91.27, 25.91)]; + [bezier4Path closePath]; + [bezier4Path moveToPoint: CGPointMake(94.18, 22.21)]; + [bezier4Path addLineToPoint: CGPointMake(92.02, 22.21)]; + [bezier4Path addCurveToPoint: CGPointMake(91.65, 22.54) controlPoint1: CGPointMake(91.84, 22.21) controlPoint2: CGPointMake(91.68, 22.35)]; + [bezier4Path addLineToPoint: CGPointMake(91.56, 23.15)]; + [bezier4Path addLineToPoint: CGPointMake(91.41, 22.93)]; + [bezier4Path addCurveToPoint: CGPointMake(88.87, 22) controlPoint1: CGPointMake(90.94, 22.23) controlPoint2: CGPointMake(89.9, 22)]; + [bezier4Path addCurveToPoint: CGPointMake(84.06, 26.46) controlPoint1: CGPointMake(86.49, 22) controlPoint2: CGPointMake(84.46, 23.86)]; + [bezier4Path addCurveToPoint: CGPointMake(84.87, 29.87) controlPoint1: CGPointMake(83.86, 27.76) controlPoint2: CGPointMake(84.15, 29)]; + [bezier4Path addCurveToPoint: CGPointMake(87.58, 31) controlPoint1: CGPointMake(85.52, 30.67) controlPoint2: CGPointMake(86.46, 31)]; + [bezier4Path addCurveToPoint: CGPointMake(90.55, 29.73) controlPoint1: CGPointMake(89.49, 31) controlPoint2: CGPointMake(90.55, 29.73)]; + [bezier4Path addLineToPoint: CGPointMake(90.46, 30.34)]; + [bezier4Path addCurveToPoint: CGPointMake(90.83, 30.79) controlPoint1: CGPointMake(90.42, 30.58) controlPoint2: CGPointMake(90.6, 30.79)]; + [bezier4Path addLineToPoint: CGPointMake(92.77, 30.79)]; + [bezier4Path addCurveToPoint: CGPointMake(93.38, 30.25) controlPoint1: CGPointMake(93.07, 30.79) controlPoint2: CGPointMake(93.33, 30.56)]; + [bezier4Path addLineToPoint: CGPointMake(94.55, 22.65)]; + [bezier4Path addCurveToPoint: CGPointMake(94.18, 22.21) controlPoint1: CGPointMake(94.58, 22.42) controlPoint2: CGPointMake(94.41, 22.21)]; + [bezier4Path closePath]; + bezier4Path.miterLimit = 4; + + bezier4Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier4Path fill]; + + + //// Bezier 5 Drawing + UIBezierPath* bezier5Path = [UIBezierPath bezierPath]; + [bezier5Path moveToPoint: CGPointMake(73.02, 22)]; + [bezier5Path addLineToPoint: CGPointMake(70.86, 22)]; + [bezier5Path addCurveToPoint: CGPointMake(70.35, 22.28) controlPoint1: CGPointMake(70.66, 22) controlPoint2: CGPointMake(70.46, 22.11)]; + [bezier5Path addLineToPoint: CGPointMake(67.36, 26.81)]; + [bezier5Path addLineToPoint: CGPointMake(66.1, 22.46)]; + [bezier5Path addCurveToPoint: CGPointMake(65.5, 22) controlPoint1: CGPointMake(66.02, 22.19) controlPoint2: CGPointMake(65.78, 22)]; + [bezier5Path addLineToPoint: CGPointMake(63.37, 22)]; + [bezier5Path addCurveToPoint: CGPointMake(63.02, 22.51) controlPoint1: CGPointMake(63.12, 22) controlPoint2: CGPointMake(62.94, 22.26)]; + [bezier5Path addLineToPoint: CGPointMake(65.4, 29.72)]; + [bezier5Path addLineToPoint: CGPointMake(63.16, 32.97)]; + [bezier5Path addCurveToPoint: CGPointMake(63.47, 33.58) controlPoint1: CGPointMake(62.99, 33.23) controlPoint2: CGPointMake(63.16, 33.58)]; + [bezier5Path addLineToPoint: CGPointMake(65.63, 33.58)]; + [bezier5Path addCurveToPoint: CGPointMake(66.14, 33.31) controlPoint1: CGPointMake(65.83, 33.58) controlPoint2: CGPointMake(66.02, 33.48)]; + [bezier5Path addLineToPoint: CGPointMake(73.33, 22.61)]; + [bezier5Path addCurveToPoint: CGPointMake(73.02, 22) controlPoint1: CGPointMake(73.5, 22.35) controlPoint2: CGPointMake(73.33, 22)]; + [bezier5Path closePath]; + bezier5Path.miterLimit = 4; + + bezier5Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier5Path fill]; + + + //// Bezier 6 Drawing + UIBezierPath* bezier6Path = [UIBezierPath bezierPath]; + [bezier6Path moveToPoint: CGPointMake(96.85, 18.33)]; + [bezier6Path addLineToPoint: CGPointMake(95, 30.42)]; + [bezier6Path addCurveToPoint: CGPointMake(95.37, 30.87) controlPoint1: CGPointMake(94.97, 30.66) controlPoint2: CGPointMake(95.14, 30.87)]; + [bezier6Path addLineToPoint: CGPointMake(97.23, 30.87)]; + [bezier6Path addCurveToPoint: CGPointMake(97.84, 30.32) controlPoint1: CGPointMake(97.54, 30.87) controlPoint2: CGPointMake(97.8, 30.64)]; + [bezier6Path addLineToPoint: CGPointMake(99.66, 18.45)]; + [bezier6Path addCurveToPoint: CGPointMake(99.29, 18) controlPoint1: CGPointMake(99.7, 18.21) controlPoint2: CGPointMake(99.52, 18)]; + [bezier6Path addLineToPoint: CGPointMake(97.22, 18)]; + [bezier6Path addCurveToPoint: CGPointMake(96.85, 18.33) controlPoint1: CGPointMake(97.03, 18) controlPoint2: CGPointMake(96.88, 18.14)]; + [bezier6Path closePath]; + bezier6Path.miterLimit = 4; + + bezier6Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier6Path fill]; + } + + + //// monogram + { + //// Bezier 7 Drawing + UIBezierPath* bezier7Path = [UIBezierPath bezierPath]; + [bezier7Path moveToPoint: CGPointMake(37.4, 24.5)]; + [bezier7Path addCurveToPoint: CGPointMake(37.48, 22.4) controlPoint1: CGPointMake(37.55, 23.71) controlPoint2: CGPointMake(37.57, 23)]; + [bezier7Path addCurveToPoint: CGPointMake(36.77, 20.78) controlPoint1: CGPointMake(37.38, 21.76) controlPoint2: CGPointMake(37.14, 21.22)]; + [bezier7Path addCurveToPoint: CGPointMake(35.91, 20.1) controlPoint1: CGPointMake(36.54, 20.52) controlPoint2: CGPointMake(36.25, 20.29)]; + [bezier7Path addCurveToPoint: CGPointMake(35.88, 18.08) controlPoint1: CGPointMake(36.02, 19.3) controlPoint2: CGPointMake(36.01, 18.64)]; + [bezier7Path addCurveToPoint: CGPointMake(35.08, 16.52) controlPoint1: CGPointMake(35.75, 17.51) controlPoint2: CGPointMake(35.49, 17)]; + [bezier7Path addCurveToPoint: CGPointMake(30.46, 15.02) controlPoint1: CGPointMake(34.23, 15.53) controlPoint2: CGPointMake(32.67, 15.02)]; + [bezier7Path addLineToPoint: CGPointMake(24.39, 15.02)]; + [bezier7Path addCurveToPoint: CGPointMake(23.55, 15.75) controlPoint1: CGPointMake(23.97, 15.02) controlPoint2: CGPointMake(23.62, 15.33)]; + [bezier7Path addLineToPoint: CGPointMake(21.03, 32.18)]; + [bezier7Path addCurveToPoint: CGPointMake(21.14, 32.6) controlPoint1: CGPointMake(21, 32.33) controlPoint2: CGPointMake(21.04, 32.48)]; + [bezier7Path addCurveToPoint: CGPointMake(21.52, 32.78) controlPoint1: CGPointMake(21.24, 32.71) controlPoint2: CGPointMake(21.37, 32.78)]; + [bezier7Path addLineToPoint: CGPointMake(25.29, 32.78)]; + [bezier7Path addLineToPoint: CGPointMake(25.03, 34.48)]; + [bezier7Path addCurveToPoint: CGPointMake(25.13, 34.84) controlPoint1: CGPointMake(25.01, 34.61) controlPoint2: CGPointMake(25.05, 34.74)]; + [bezier7Path addCurveToPoint: CGPointMake(25.46, 35) controlPoint1: CGPointMake(25.21, 34.94) controlPoint2: CGPointMake(25.33, 35)]; + [bezier7Path addLineToPoint: CGPointMake(28.62, 35)]; + [bezier7Path addCurveToPoint: CGPointMake(29.35, 34.36) controlPoint1: CGPointMake(28.99, 35) controlPoint2: CGPointMake(29.29, 34.73)]; + [bezier7Path addLineToPoint: CGPointMake(29.38, 34.19)]; + [bezier7Path addLineToPoint: CGPointMake(29.98, 30.33)]; + [bezier7Path addLineToPoint: CGPointMake(30.02, 30.11)]; + [bezier7Path addCurveToPoint: CGPointMake(30.79, 29.44) controlPoint1: CGPointMake(30.08, 29.72) controlPoint2: CGPointMake(30.4, 29.44)]; + [bezier7Path addLineToPoint: CGPointMake(31.26, 29.44)]; + [bezier7Path addCurveToPoint: CGPointMake(35.21, 28.34) controlPoint1: CGPointMake(32.88, 29.44) controlPoint2: CGPointMake(34.21, 29.07)]; + [bezier7Path addCurveToPoint: CGPointMake(36.57, 26.82) controlPoint1: CGPointMake(35.76, 27.95) controlPoint2: CGPointMake(36.21, 27.43)]; + [bezier7Path addCurveToPoint: CGPointMake(37.4, 24.5) controlPoint1: CGPointMake(36.95, 26.17) controlPoint2: CGPointMake(37.23, 25.39)]; + [bezier7Path closePath]; + bezier7Path.miterLimit = 4; + + bezier7Path.usesEvenOddFillRule = YES; + + [color2 setFill]; + [bezier7Path fill]; + + + //// Bezier 8 Drawing + UIBezierPath* bezier8Path = [UIBezierPath bezierPath]; + [bezier8Path moveToPoint: CGPointMake(27.34, 20.29)]; + [bezier8Path addCurveToPoint: CGPointMake(27.91, 19.71) controlPoint1: CGPointMake(27.25, 19.81) controlPoint2: CGPointMake(27.41, 19.59)]; + [bezier8Path addCurveToPoint: CGPointMake(27.91, 19.12) controlPoint1: CGPointMake(27.73, 19.44) controlPoint2: CGPointMake(27.84, 19.41)]; + [bezier8Path addLineToPoint: CGPointMake(32.52, 19.12)]; + [bezier8Path addCurveToPoint: CGPointMake(34.25, 19.71) controlPoint1: CGPointMake(33.27, 19.41) controlPoint2: CGPointMake(33.8, 19.45)]; + [bezier8Path addCurveToPoint: CGPointMake(34.82, 19.71) controlPoint1: CGPointMake(34.41, 19.55) controlPoint2: CGPointMake(34.55, 19.58)]; + [bezier8Path addCurveToPoint: CGPointMake(34.82, 19.71) controlPoint1: CGPointMake(34.8, 19.63) controlPoint2: CGPointMake(34.93, 19.67)]; + [bezier8Path addCurveToPoint: CGPointMake(35.4, 19.71) controlPoint1: CGPointMake(35.11, 19.72) controlPoint2: CGPointMake(35.17, 19.74)]; + [bezier8Path addCurveToPoint: CGPointMake(35.98, 20.29) controlPoint1: CGPointMake(35.47, 19.84) controlPoint2: CGPointMake(35.69, 19.93)]; + [bezier8Path addCurveToPoint: CGPointMake(34.82, 16.76) controlPoint1: CGPointMake(36.13, 18.5) controlPoint2: CGPointMake(35.89, 17.45)]; + [bezier8Path addCurveToPoint: CGPointMake(30.22, 15) controlPoint1: CGPointMake(34.16, 15.45) controlPoint2: CGPointMake(32.53, 15)]; + [bezier8Path addLineToPoint: CGPointMake(24.46, 15)]; + [bezier8Path addCurveToPoint: CGPointMake(23.3, 15.59) controlPoint1: CGPointMake(23.96, 15) controlPoint2: CGPointMake(23.6, 15.32)]; + [bezier8Path addLineToPoint: CGPointMake(21, 32.06)]; + [bezier8Path addCurveToPoint: CGPointMake(21.58, 32.65) controlPoint1: CGPointMake(20.96, 32.36) controlPoint2: CGPointMake(21.2, 32.65)]; + [bezier8Path addLineToPoint: CGPointMake(25.03, 32.65)]; + [bezier8Path addLineToPoint: CGPointMake(26.18, 26.76)]; + [bezier8Path addLineToPoint: CGPointMake(27.34, 20.29)]; + [bezier8Path closePath]; + bezier8Path.miterLimit = 4; + + bezier8Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier8Path fill]; + + + //// Bezier 9 Drawing + UIBezierPath* bezier9Path = [UIBezierPath bezierPath]; + [bezier9Path moveToPoint: CGPointMake(35.4, 19.71)]; + [bezier9Path addCurveToPoint: CGPointMake(34.82, 19.12) controlPoint1: CGPointMake(35.01, 19.38) controlPoint2: CGPointMake(34.88, 19.35)]; + [bezier9Path addCurveToPoint: CGPointMake(34.25, 19.12) controlPoint1: CGPointMake(34.62, 19.29) controlPoint2: CGPointMake(34.49, 19.26)]; + [bezier9Path addCurveToPoint: CGPointMake(32.52, 19.12) controlPoint1: CGPointMake(33.87, 19.16) controlPoint2: CGPointMake(33.34, 19.12)]; + [bezier9Path addLineToPoint: CGPointMake(27.91, 19.12)]; + [bezier9Path addCurveToPoint: CGPointMake(27.91, 19.12) controlPoint1: CGPointMake(27.87, 19.12) controlPoint2: CGPointMake(27.76, 19.15)]; + [bezier9Path addCurveToPoint: CGPointMake(27.34, 19.71) controlPoint1: CGPointMake(27.43, 19.31) controlPoint2: CGPointMake(27.27, 19.53)]; + [bezier9Path addLineToPoint: CGPointMake(26.18, 26.76)]; + [bezier9Path addLineToPoint: CGPointMake(26.18, 26.76)]; + [bezier9Path addCurveToPoint: CGPointMake(26.76, 26.18) controlPoint1: CGPointMake(26.25, 26.32) controlPoint2: CGPointMake(26.61, 25.99)]; + [bezier9Path addLineToPoint: CGPointMake(29.06, 26.18)]; + [bezier9Path addCurveToPoint: CGPointMake(35.98, 20.29) controlPoint1: CGPointMake(32.35, 25.99) controlPoint2: CGPointMake(35.11, 24.49)]; + [bezier9Path addCurveToPoint: CGPointMake(35.98, 19.71) controlPoint1: CGPointMake(35.94, 20.02) controlPoint2: CGPointMake(35.96, 19.9)]; + [bezier9Path addCurveToPoint: CGPointMake(35.4, 19.71) controlPoint1: CGPointMake(35.77, 19.66) controlPoint2: CGPointMake(35.55, 19.56)]; + [bezier9Path addCurveToPoint: CGPointMake(35.4, 19.71) controlPoint1: CGPointMake(35.25, 19.46) controlPoint2: CGPointMake(35.19, 19.44)]; + [bezier9Path closePath]; + bezier9Path.miterLimit = 4; + + bezier9Path.usesEvenOddFillRule = YES; + + [color3 setFill]; + [bezier9Path fill]; + } + } + + + //// Rectangle Drawing + CGRect rectangleRect = CGRectMake(106, 15, 79, 32); + NSMutableParagraphStyle* rectangleStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy]; + [rectangleStyle setAlignment: NSTextAlignmentLeft]; + + NSDictionary* rectangleFontAttributes = @{NSFontAttributeName: [UIFont fontWithName: @"HelveticaNeue-Bold" size: 16], NSForegroundColorAttributeName: color1, NSParagraphStyleAttributeName: rectangleStyle}; + + [@"Check out" drawInRect: rectangleRect withAttributes: rectangleFontAttributes]; + } + } + } + + + +} + +- (void)updateConstraints { + NSLayoutConstraint *aspectRatioConstraint = [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeWidth + relatedBy:NSLayoutRelationEqual + toItem:self + attribute:NSLayoutAttributeHeight + multiplier:(self.artDimensions.width / self.artDimensions.height) + constant:0.0f]; + aspectRatioConstraint.priority = UILayoutPriorityRequired; + + [self addConstraint:aspectRatioConstraint]; + + [super updateConstraints]; +} + +- (UILayoutPriority)contentCompressionResistancePriorityForAxis:(__unused UILayoutConstraintAxis)axis { + return UILayoutPriorityRequired; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIUnionPayVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIUnionPayVectorArtView.h new file mode 100644 index 0000000..f1e80cc --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIUnionPayVectorArtView.h @@ -0,0 +1,5 @@ +#import "BTUICardVectorArtView.h" + +@interface BTUIUnionPayVectorArtView : BTUICardVectorArtView + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIUnionPayVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIUnionPayVectorArtView.m new file mode 100644 index 0000000..f2bfce4 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIUnionPayVectorArtView.m @@ -0,0 +1,481 @@ +#import "BTUIUnionPayVectorArtView.h" + +@implementation BTUIUnionPayVectorArtView + +- (void)drawArt { + //// Color Declarations + UIColor* color = [UIColor colorWithRed: 1 green: 1 blue: 1 alpha: 1]; + UIColor* color2 = [UIColor colorWithRed: 0 green: 0.616 blue: 0.647 alpha: 1]; + UIColor* color3 = [UIColor colorWithRed: 0 green: 0.447 blue: 0.737 alpha: 1]; + UIColor* color4 = [UIColor colorWithRed: 0.929 green: 0.11 blue: 0.141 alpha: 1]; + + //// Group + { + //// Bezier 4 Drawing + UIBezierPath* bezier4Path = [UIBezierPath bezierPath]; + [bezier4Path moveToPoint: CGPointMake(27.72, 43.3)]; + [bezier4Path addLineToPoint: CGPointMake(34.69, 12.7)]; + [bezier4Path addCurveToPoint: CGPointMake(39.74, 9.03) controlPoint1: CGPointMake(35.15, 10.69) controlPoint2: CGPointMake(37.71, 9.07)]; + [bezier4Path addLineToPoint: CGPointMake(26.2, 9.03)]; + [bezier4Path addCurveToPoint: CGPointMake(21.08, 12.7) controlPoint1: CGPointMake(24.15, 9.03) controlPoint2: CGPointMake(21.53, 10.66)]; + [bezier4Path addLineToPoint: CGPointMake(14.11, 43.3)]; + [bezier4Path addCurveToPoint: CGPointMake(14.03, 43.86) controlPoint1: CGPointMake(14.06, 43.48) controlPoint2: CGPointMake(14.03, 43.68)]; + [bezier4Path addLineToPoint: CGPointMake(14.03, 44.44)]; + [bezier4Path addCurveToPoint: CGPointMake(16.92, 47) controlPoint1: CGPointMake(14.16, 45.89) controlPoint2: CGPointMake(15.3, 46.97)]; + [bezier4Path addLineToPoint: CGPointMake(30.53, 47)]; + [bezier4Path addCurveToPoint: CGPointMake(27.72, 43.3) controlPoint1: CGPointMake(28.53, 46.95) controlPoint2: CGPointMake(27.27, 45.31)]; + [bezier4Path closePath]; + bezier4Path.miterLimit = 4; + + [color4 setFill]; + [bezier4Path fill]; + + + //// Bezier 5 Drawing + UIBezierPath* bezier5Path = [UIBezierPath bezierPath]; + [bezier5Path moveToPoint: CGPointMake(50.34, 9.03)]; + [bezier5Path addLineToPoint: CGPointMake(39.84, 9.03)]; + [bezier5Path addCurveToPoint: CGPointMake(39.76, 9.03) controlPoint1: CGPointMake(39.81, 9.03) controlPoint2: CGPointMake(39.79, 9.03)]; + [bezier5Path addLineToPoint: CGPointMake(50.34, 9.03)]; + [bezier5Path closePath]; + bezier5Path.miterLimit = 4; + + [[UIColor blackColor] setFill]; + [bezier5Path fill]; + + + //// Bezier 6 Drawing + UIBezierPath* bezier6Path = [UIBezierPath bezierPath]; + [bezier6Path moveToPoint: CGPointMake(44.2, 43.3)]; + [bezier6Path addLineToPoint: CGPointMake(51.17, 12.7)]; + [bezier6Path addCurveToPoint: CGPointMake(56.19, 9.03) controlPoint1: CGPointMake(51.63, 10.71) controlPoint2: CGPointMake(54.16, 9.1)]; + [bezier6Path addLineToPoint: CGPointMake(50.34, 9.03)]; + [bezier6Path addLineToPoint: CGPointMake(39.76, 9.03)]; + [bezier6Path addCurveToPoint: CGPointMake(34.72, 12.7) controlPoint1: CGPointMake(37.74, 9.07) controlPoint2: CGPointMake(35.18, 10.69)]; + [bezier6Path addLineToPoint: CGPointMake(27.75, 43.3)]; + [bezier6Path addCurveToPoint: CGPointMake(30.56, 46.97) controlPoint1: CGPointMake(27.29, 45.31) controlPoint2: CGPointMake(28.54, 46.95)]; + [bezier6Path addLineToPoint: CGPointMake(47.04, 46.97)]; + [bezier6Path addCurveToPoint: CGPointMake(44.2, 43.3) controlPoint1: CGPointMake(45.01, 46.95) controlPoint2: CGPointMake(43.74, 45.31)]; + [bezier6Path closePath]; + bezier6Path.miterLimit = 4; + + [color3 setFill]; + [bezier6Path fill]; + + + //// Bezier 7 Drawing + UIBezierPath* bezier7Path = [UIBezierPath bezierPath]; + [bezier7Path moveToPoint: CGPointMake(70.99, 9.03)]; + [bezier7Path addLineToPoint: CGPointMake(56.24, 9.03)]; + [bezier7Path addLineToPoint: CGPointMake(56.24, 9.03)]; + [bezier7Path addLineToPoint: CGPointMake(56.21, 9.03)]; + [bezier7Path addCurveToPoint: CGPointMake(51.19, 12.7) controlPoint1: CGPointMake(54.18, 9.07) controlPoint2: CGPointMake(51.65, 10.71)]; + [bezier7Path addLineToPoint: CGPointMake(44.22, 43.3)]; + [bezier7Path addCurveToPoint: CGPointMake(47.03, 46.97) controlPoint1: CGPointMake(43.76, 45.31) controlPoint2: CGPointMake(45.01, 46.95)]; + [bezier7Path addLineToPoint: CGPointMake(49.04, 46.97)]; + [bezier7Path addLineToPoint: CGPointMake(58.19, 46.97)]; + [bezier7Path addLineToPoint: CGPointMake(62.55, 46.97)]; + [bezier7Path addCurveToPoint: CGPointMake(66.91, 43.33) controlPoint1: CGPointMake(64.53, 46.87) controlPoint2: CGPointMake(66.45, 45.29)]; + [bezier7Path addLineToPoint: CGPointMake(73.88, 12.72)]; + [bezier7Path addCurveToPoint: CGPointMake(70.99, 9.03) controlPoint1: CGPointMake(74.31, 10.69) controlPoint2: CGPointMake(73.05, 9.03)]; + [bezier7Path closePath]; + bezier7Path.miterLimit = 4; + + [color2 setFill]; + [bezier7Path fill]; + + + //// Bezier 8 Drawing + UIBezierPath* bezier8Path = [UIBezierPath bezierPath]; + [bezier8Path moveToPoint: CGPointMake(40.04, 31.34)]; + [bezier8Path addLineToPoint: CGPointMake(40.3, 31.34)]; + [bezier8Path addCurveToPoint: CGPointMake(40.75, 31.12) controlPoint1: CGPointMake(40.53, 31.34) controlPoint2: CGPointMake(40.7, 31.27)]; + [bezier8Path addLineToPoint: CGPointMake(41.41, 30.14)]; + [bezier8Path addLineToPoint: CGPointMake(43.19, 30.14)]; + [bezier8Path addLineToPoint: CGPointMake(42.81, 30.79)]; + [bezier8Path addLineToPoint: CGPointMake(44.93, 30.79)]; + [bezier8Path addLineToPoint: CGPointMake(44.66, 31.8)]; + [bezier8Path addLineToPoint: CGPointMake(42.12, 31.8)]; + [bezier8Path addCurveToPoint: CGPointMake(41.03, 32.42) controlPoint1: CGPointMake(41.81, 32.22) controlPoint2: CGPointMake(41.46, 32.45)]; + [bezier8Path addLineToPoint: CGPointMake(39.71, 32.42)]; + [bezier8Path addLineToPoint: CGPointMake(40.04, 31.34)]; + [bezier8Path closePath]; + [bezier8Path moveToPoint: CGPointMake(39.76, 32.78)]; + [bezier8Path addLineToPoint: CGPointMake(44.45, 32.78)]; + [bezier8Path addLineToPoint: CGPointMake(44.15, 33.86)]; + [bezier8Path addLineToPoint: CGPointMake(42.27, 33.86)]; + [bezier8Path addLineToPoint: CGPointMake(41.99, 34.91)]; + [bezier8Path addLineToPoint: CGPointMake(43.82, 34.91)]; + [bezier8Path addLineToPoint: CGPointMake(43.51, 35.99)]; + [bezier8Path addLineToPoint: CGPointMake(41.69, 35.99)]; + [bezier8Path addLineToPoint: CGPointMake(41.26, 37.52)]; + [bezier8Path addCurveToPoint: CGPointMake(41.66, 37.87) controlPoint1: CGPointMake(41.15, 37.77) controlPoint2: CGPointMake(41.28, 37.9)]; + [bezier8Path addLineToPoint: CGPointMake(43.16, 37.87)]; + [bezier8Path addLineToPoint: CGPointMake(42.88, 38.88)]; + [bezier8Path addLineToPoint: CGPointMake(40.02, 38.88)]; + [bezier8Path addCurveToPoint: CGPointMake(39.46, 37.95) controlPoint1: CGPointMake(39.48, 38.88) controlPoint2: CGPointMake(39.28, 38.57)]; + [bezier8Path addLineToPoint: CGPointMake(39.99, 35.98)]; + [bezier8Path addLineToPoint: CGPointMake(38.83, 35.98)]; + [bezier8Path addLineToPoint: CGPointMake(39.13, 34.91)]; + [bezier8Path addLineToPoint: CGPointMake(40.3, 34.91)]; + [bezier8Path addLineToPoint: CGPointMake(40.57, 33.85)]; + [bezier8Path addLineToPoint: CGPointMake(39.46, 33.85)]; + [bezier8Path addLineToPoint: CGPointMake(39.76, 32.78)]; + [bezier8Path closePath]; + [bezier8Path moveToPoint: CGPointMake(47.24, 30.11)]; + [bezier8Path addLineToPoint: CGPointMake(47.17, 30.74)]; + [bezier8Path addCurveToPoint: CGPointMake(48.87, 30.08) controlPoint1: CGPointMake(47.17, 30.74) controlPoint2: CGPointMake(48.05, 30.08)]; + [bezier8Path addLineToPoint: CGPointMake(51.83, 30.08)]; + [bezier8Path addLineToPoint: CGPointMake(50.69, 34.16)]; + [bezier8Path addCurveToPoint: CGPointMake(49.47, 34.86) controlPoint1: CGPointMake(50.59, 34.64) controlPoint2: CGPointMake(50.18, 34.86)]; + [bezier8Path addLineToPoint: CGPointMake(46.1, 34.86)]; + [bezier8Path addLineToPoint: CGPointMake(45.31, 37.73)]; + [bezier8Path addCurveToPoint: CGPointMake(45.49, 37.95) controlPoint1: CGPointMake(45.26, 37.88) controlPoint2: CGPointMake(45.34, 37.95)]; + [bezier8Path addLineToPoint: CGPointMake(46.15, 37.95)]; + [bezier8Path addLineToPoint: CGPointMake(45.9, 38.83)]; + [bezier8Path addLineToPoint: CGPointMake(44.25, 38.83)]; + [bezier8Path addCurveToPoint: CGPointMake(43.44, 38.25) controlPoint1: CGPointMake(43.62, 38.83) controlPoint2: CGPointMake(43.34, 38.63)]; + [bezier8Path addLineToPoint: CGPointMake(45.67, 30.11)]; + [bezier8Path addLineToPoint: CGPointMake(47.24, 30.11)]; + [bezier8Path closePath]; + [bezier8Path moveToPoint: CGPointMake(49.75, 31.27)]; + [bezier8Path addLineToPoint: CGPointMake(47.11, 31.27)]; + [bezier8Path addLineToPoint: CGPointMake(46.81, 32.38)]; + [bezier8Path addCurveToPoint: CGPointMake(47.97, 32.05) controlPoint1: CGPointMake(46.81, 32.38) controlPoint2: CGPointMake(47.24, 32.05)]; + [bezier8Path addCurveToPoint: CGPointMake(49.54, 32.05) controlPoint1: CGPointMake(48.71, 32.05) controlPoint2: CGPointMake(49.54, 32.05)]; + [bezier8Path addLineToPoint: CGPointMake(49.75, 31.27)]; + [bezier8Path closePath]; + [bezier8Path moveToPoint: CGPointMake(48.79, 33.81)]; + [bezier8Path addCurveToPoint: CGPointMake(49.11, 33.58) controlPoint1: CGPointMake(48.99, 33.83) controlPoint2: CGPointMake(49.09, 33.76)]; + [bezier8Path addLineToPoint: CGPointMake(49.27, 33)]; + [bezier8Path addLineToPoint: CGPointMake(46.6, 33)]; + [bezier8Path addLineToPoint: CGPointMake(46.37, 33.8)]; + [bezier8Path addLineToPoint: CGPointMake(48.79, 33.81)]; + [bezier8Path addLineToPoint: CGPointMake(48.79, 33.81)]; + [bezier8Path closePath]; + [bezier8Path moveToPoint: CGPointMake(46.99, 35.11)]; + [bezier8Path addLineToPoint: CGPointMake(48.51, 35.11)]; + [bezier8Path addLineToPoint: CGPointMake(48.48, 35.77)]; + [bezier8Path addLineToPoint: CGPointMake(48.89, 35.77)]; + [bezier8Path addCurveToPoint: CGPointMake(49.2, 35.57) controlPoint1: CGPointMake(49.1, 35.77) controlPoint2: CGPointMake(49.2, 35.69)]; + [bezier8Path addLineToPoint: CGPointMake(49.33, 35.14)]; + [bezier8Path addLineToPoint: CGPointMake(50.59, 35.14)]; + [bezier8Path addLineToPoint: CGPointMake(50.41, 35.77)]; + [bezier8Path addCurveToPoint: CGPointMake(49.27, 36.57) controlPoint1: CGPointMake(50.26, 36.29) controlPoint2: CGPointMake(49.88, 36.55)]; + [bezier8Path addLineToPoint: CGPointMake(48.46, 36.57)]; + [bezier8Path addLineToPoint: CGPointMake(48.46, 37.7)]; + [bezier8Path addCurveToPoint: CGPointMake(48.94, 37.98) controlPoint1: CGPointMake(48.44, 37.88) controlPoint2: CGPointMake(48.61, 37.98)]; + [bezier8Path addLineToPoint: CGPointMake(49.71, 37.98)]; + [bezier8Path addLineToPoint: CGPointMake(49.45, 38.86)]; + [bezier8Path addLineToPoint: CGPointMake(47.63, 38.86)]; + [bezier8Path addCurveToPoint: CGPointMake(46.87, 38.13) controlPoint1: CGPointMake(47.12, 38.88) controlPoint2: CGPointMake(46.87, 38.63)]; + [bezier8Path addLineToPoint: CGPointMake(46.99, 35.11)]; + [bezier8Path closePath]; + bezier8Path.miterLimit = 4; + + [color setFill]; + [bezier8Path fill]; + + + //// Bezier 9 Drawing + UIBezierPath* bezier9Path = [UIBezierPath bezierPath]; + [bezier9Path moveToPoint: CGPointMake(53.5, 31.39)]; + [bezier9Path addLineToPoint: CGPointMake(53.86, 30.16)]; + [bezier9Path addLineToPoint: CGPointMake(55.66, 30.16)]; + [bezier9Path addLineToPoint: CGPointMake(55.58, 30.61)]; + [bezier9Path addCurveToPoint: CGPointMake(57.15, 30.16) controlPoint1: CGPointMake(55.58, 30.61) controlPoint2: CGPointMake(56.49, 30.16)]; + [bezier9Path addCurveToPoint: CGPointMake(59.36, 30.16) controlPoint1: CGPointMake(57.81, 30.16) controlPoint2: CGPointMake(59.36, 30.16)]; + [bezier9Path addLineToPoint: CGPointMake(59, 31.39)]; + [bezier9Path addLineToPoint: CGPointMake(58.65, 31.39)]; + [bezier9Path addLineToPoint: CGPointMake(56.98, 37.22)]; + [bezier9Path addLineToPoint: CGPointMake(57.33, 37.22)]; + [bezier9Path addLineToPoint: CGPointMake(57, 38.38)]; + [bezier9Path addLineToPoint: CGPointMake(56.65, 38.38)]; + [bezier9Path addLineToPoint: CGPointMake(56.5, 38.88)]; + [bezier9Path addLineToPoint: CGPointMake(54.78, 38.88)]; + [bezier9Path addLineToPoint: CGPointMake(54.93, 38.38)]; + [bezier9Path addLineToPoint: CGPointMake(51.5, 38.38)]; + [bezier9Path addLineToPoint: CGPointMake(51.83, 37.22)]; + [bezier9Path addLineToPoint: CGPointMake(52.18, 37.22)]; + [bezier9Path addLineToPoint: CGPointMake(53.86, 31.39)]; + [bezier9Path addLineToPoint: CGPointMake(53.5, 31.39)]; + [bezier9Path closePath]; + [bezier9Path moveToPoint: CGPointMake(55.43, 31.39)]; + [bezier9Path addLineToPoint: CGPointMake(54.97, 32.98)]; + [bezier9Path addCurveToPoint: CGPointMake(56.42, 32.6) controlPoint1: CGPointMake(54.97, 32.98) controlPoint2: CGPointMake(55.76, 32.67)]; + [bezier9Path addCurveToPoint: CGPointMake(56.77, 31.39) controlPoint1: CGPointMake(56.57, 32.05) controlPoint2: CGPointMake(56.77, 31.39)]; + [bezier9Path addLineToPoint: CGPointMake(55.43, 31.39)]; + [bezier9Path closePath]; + [bezier9Path moveToPoint: CGPointMake(54.74, 33.71)]; + [bezier9Path addLineToPoint: CGPointMake(54.29, 35.36)]; + [bezier9Path addCurveToPoint: CGPointMake(55.76, 34.91) controlPoint1: CGPointMake(54.29, 35.36) controlPoint2: CGPointMake(55.15, 34.94)]; + [bezier9Path addCurveToPoint: CGPointMake(56.11, 33.71) controlPoint1: CGPointMake(55.94, 34.28) controlPoint2: CGPointMake(56.11, 33.71)]; + [bezier9Path addLineToPoint: CGPointMake(54.74, 33.71)]; + [bezier9Path addLineToPoint: CGPointMake(54.74, 33.71)]; + [bezier9Path closePath]; + [bezier9Path moveToPoint: CGPointMake(55.1, 37.23)]; + [bezier9Path addLineToPoint: CGPointMake(55.45, 36.02)]; + [bezier9Path addLineToPoint: CGPointMake(54.11, 36.02)]; + [bezier9Path addLineToPoint: CGPointMake(53.76, 37.23)]; + [bezier9Path addLineToPoint: CGPointMake(55.1, 37.23)]; + [bezier9Path closePath]; + [bezier9Path moveToPoint: CGPointMake(59.43, 30.06)]; + [bezier9Path addLineToPoint: CGPointMake(61.11, 30.06)]; + [bezier9Path addLineToPoint: CGPointMake(61.18, 30.69)]; + [bezier9Path addCurveToPoint: CGPointMake(61.46, 30.92) controlPoint1: CGPointMake(61.18, 30.84) controlPoint2: CGPointMake(61.26, 30.92)]; + [bezier9Path addLineToPoint: CGPointMake(61.77, 30.92)]; + [bezier9Path addLineToPoint: CGPointMake(61.46, 31.97)]; + [bezier9Path addLineToPoint: CGPointMake(60.22, 31.97)]; + [bezier9Path addCurveToPoint: CGPointMake(59.48, 31.42) controlPoint1: CGPointMake(59.73, 32) controlPoint2: CGPointMake(59.51, 31.82)]; + [bezier9Path addLineToPoint: CGPointMake(59.43, 30.06)]; + [bezier9Path closePath]; + [bezier9Path moveToPoint: CGPointMake(58.93, 32.3)]; + [bezier9Path addLineToPoint: CGPointMake(64.38, 32.3)]; + [bezier9Path addLineToPoint: CGPointMake(64.05, 33.43)]; + [bezier9Path addLineToPoint: CGPointMake(62.3, 33.43)]; + [bezier9Path addLineToPoint: CGPointMake(62, 34.46)]; + [bezier9Path addLineToPoint: CGPointMake(63.72, 34.46)]; + [bezier9Path addLineToPoint: CGPointMake(63.39, 35.59)]; + [bezier9Path addLineToPoint: CGPointMake(61.46, 35.59)]; + [bezier9Path addLineToPoint: CGPointMake(61.04, 36.25)]; + [bezier9Path addLineToPoint: CGPointMake(61.97, 36.25)]; + [bezier9Path addLineToPoint: CGPointMake(62.2, 37.55)]; + [bezier9Path addCurveToPoint: CGPointMake(62.56, 37.76) controlPoint1: CGPointMake(62.23, 37.68) controlPoint2: CGPointMake(62.35, 37.76)]; + [bezier9Path addLineToPoint: CGPointMake(62.86, 37.76)]; + [bezier9Path addLineToPoint: CGPointMake(62.56, 38.84)]; + [bezier9Path addLineToPoint: CGPointMake(61.52, 38.84)]; + [bezier9Path addCurveToPoint: CGPointMake(60.68, 38.31) controlPoint1: CGPointMake(60.99, 38.86) controlPoint2: CGPointMake(60.71, 38.69)]; + [bezier9Path addLineToPoint: CGPointMake(60.43, 37.1)]; + [bezier9Path addLineToPoint: CGPointMake(59.57, 38.38)]; + [bezier9Path addCurveToPoint: CGPointMake(58.63, 38.89) controlPoint1: CGPointMake(59.36, 38.73) controlPoint2: CGPointMake(59.06, 38.91)]; + [bezier9Path addLineToPoint: CGPointMake(57.03, 38.89)]; + [bezier9Path addLineToPoint: CGPointMake(57.33, 37.81)]; + [bezier9Path addLineToPoint: CGPointMake(57.84, 37.81)]; + [bezier9Path addCurveToPoint: CGPointMake(58.37, 37.53) controlPoint1: CGPointMake(58.05, 37.81) controlPoint2: CGPointMake(58.22, 37.71)]; + [bezier9Path addLineToPoint: CGPointMake(59.72, 35.6)]; + [bezier9Path addLineToPoint: CGPointMake(57.97, 35.6)]; + [bezier9Path addLineToPoint: CGPointMake(58.3, 34.46)]; + [bezier9Path addLineToPoint: CGPointMake(60.17, 34.46)]; + [bezier9Path addLineToPoint: CGPointMake(60.48, 33.43)]; + [bezier9Path addLineToPoint: CGPointMake(58.6, 33.43)]; + [bezier9Path addLineToPoint: CGPointMake(58.93, 32.3)]; + [bezier9Path closePath]; + bezier9Path.miterLimit = 4; + + [color setFill]; + [bezier9Path fill]; + + + //// Bezier 10 Drawing + UIBezierPath* bezier10Path = [UIBezierPath bezierPath]; + [bezier10Path moveToPoint: CGPointMake(28.48, 24.68)]; + [bezier10Path addCurveToPoint: CGPointMake(27.04, 27.02) controlPoint1: CGPointMake(28.28, 25.69) controlPoint2: CGPointMake(27.8, 26.47)]; + [bezier10Path addCurveToPoint: CGPointMake(24.18, 27.82) controlPoint1: CGPointMake(26.31, 27.55) controlPoint2: CGPointMake(25.34, 27.82)]; + [bezier10Path addCurveToPoint: CGPointMake(21.77, 26.99) controlPoint1: CGPointMake(23.09, 27.82) controlPoint2: CGPointMake(22.28, 27.55)]; + [bezier10Path addCurveToPoint: CGPointMake(21.24, 25.49) controlPoint1: CGPointMake(21.41, 26.59) controlPoint2: CGPointMake(21.24, 26.09)]; + [bezier10Path addCurveToPoint: CGPointMake(21.34, 24.68) controlPoint1: CGPointMake(21.24, 25.24) controlPoint2: CGPointMake(21.26, 24.96)]; + [bezier10Path addLineToPoint: CGPointMake(22.58, 18.75)]; + [bezier10Path addLineToPoint: CGPointMake(24.46, 18.75)]; + [bezier10Path addLineToPoint: CGPointMake(23.24, 24.63)]; + [bezier10Path addCurveToPoint: CGPointMake(23.19, 25.09) controlPoint1: CGPointMake(23.21, 24.78) controlPoint2: CGPointMake(23.19, 24.94)]; + [bezier10Path addCurveToPoint: CGPointMake(23.42, 25.81) controlPoint1: CGPointMake(23.19, 25.39) controlPoint2: CGPointMake(23.27, 25.64)]; + [bezier10Path addCurveToPoint: CGPointMake(24.51, 26.24) controlPoint1: CGPointMake(23.65, 26.09) controlPoint2: CGPointMake(24.01, 26.24)]; + [bezier10Path addCurveToPoint: CGPointMake(25.93, 25.81) controlPoint1: CGPointMake(25.1, 26.24) controlPoint2: CGPointMake(25.57, 26.09)]; + [bezier10Path addCurveToPoint: CGPointMake(26.64, 24.61) controlPoint1: CGPointMake(26.31, 25.54) controlPoint2: CGPointMake(26.54, 25.13)]; + [bezier10Path addLineToPoint: CGPointMake(27.88, 18.73)]; + [bezier10Path addLineToPoint: CGPointMake(29.76, 18.73)]; + [bezier10Path addLineToPoint: CGPointMake(28.48, 24.68)]; + [bezier10Path closePath]; + bezier10Path.miterLimit = 4; + + [color setFill]; + [bezier10Path fill]; + + + //// Bezier 11 Drawing + UIBezierPath* bezier11Path = [UIBezierPath bezierPath]; + [bezier11Path moveToPoint: CGPointMake(30.21, 22.35)]; + [bezier11Path addLineToPoint: CGPointMake(31.53, 22.35)]; + [bezier11Path addLineToPoint: CGPointMake(31.37, 23.1)]; + [bezier11Path addLineToPoint: CGPointMake(31.58, 22.87)]; + [bezier11Path addCurveToPoint: CGPointMake(33.15, 22.19) controlPoint1: CGPointMake(32.01, 22.42) controlPoint2: CGPointMake(32.54, 22.19)]; + [bezier11Path addCurveToPoint: CGPointMake(34.37, 22.67) controlPoint1: CGPointMake(33.71, 22.19) controlPoint2: CGPointMake(34.11, 22.34)]; + [bezier11Path addCurveToPoint: CGPointMake(34.57, 24) controlPoint1: CGPointMake(34.62, 23) controlPoint2: CGPointMake(34.67, 23.45)]; + [bezier11Path addLineToPoint: CGPointMake(33.84, 27.62)]; + [bezier11Path addLineToPoint: CGPointMake(32.47, 27.62)]; + [bezier11Path addLineToPoint: CGPointMake(33.13, 24.36)]; + [bezier11Path addCurveToPoint: CGPointMake(33.08, 23.6) controlPoint1: CGPointMake(33.2, 24.03) controlPoint2: CGPointMake(33.18, 23.78)]; + [bezier11Path addCurveToPoint: CGPointMake(32.49, 23.35) controlPoint1: CGPointMake(32.98, 23.45) controlPoint2: CGPointMake(32.77, 23.35)]; + [bezier11Path addCurveToPoint: CGPointMake(31.61, 23.68) controlPoint1: CGPointMake(32.14, 23.35) controlPoint2: CGPointMake(31.86, 23.45)]; + [bezier11Path addCurveToPoint: CGPointMake(31.13, 24.58) controlPoint1: CGPointMake(31.36, 23.9) controlPoint2: CGPointMake(31.2, 24.2)]; + [bezier11Path addLineToPoint: CGPointMake(30.52, 27.62)]; + [bezier11Path addLineToPoint: CGPointMake(29.15, 27.62)]; + [bezier11Path addLineToPoint: CGPointMake(30.21, 22.35)]; + [bezier11Path closePath]; + bezier11Path.miterLimit = 4; + + [color setFill]; + [bezier11Path fill]; + + + //// Bezier 12 Drawing + UIBezierPath* bezier12Path = [UIBezierPath bezierPath]; + [bezier12Path moveToPoint: CGPointMake(45.42, 22.35)]; + [bezier12Path addLineToPoint: CGPointMake(46.74, 22.35)]; + [bezier12Path addLineToPoint: CGPointMake(46.59, 23.1)]; + [bezier12Path addLineToPoint: CGPointMake(46.76, 22.87)]; + [bezier12Path addCurveToPoint: CGPointMake(48.33, 22.19) controlPoint1: CGPointMake(47.19, 22.42) controlPoint2: CGPointMake(47.73, 22.19)]; + [bezier12Path addCurveToPoint: CGPointMake(49.55, 22.67) controlPoint1: CGPointMake(48.89, 22.19) controlPoint2: CGPointMake(49.3, 22.34)]; + [bezier12Path addCurveToPoint: CGPointMake(49.76, 24) controlPoint1: CGPointMake(49.8, 23) controlPoint2: CGPointMake(49.88, 23.45)]; + [bezier12Path addLineToPoint: CGPointMake(49.02, 27.62)]; + [bezier12Path addLineToPoint: CGPointMake(47.65, 27.62)]; + [bezier12Path addLineToPoint: CGPointMake(48.31, 24.36)]; + [bezier12Path addCurveToPoint: CGPointMake(48.26, 23.6) controlPoint1: CGPointMake(48.39, 24.03) controlPoint2: CGPointMake(48.36, 23.78)]; + [bezier12Path addCurveToPoint: CGPointMake(47.68, 23.35) controlPoint1: CGPointMake(48.16, 23.45) controlPoint2: CGPointMake(47.96, 23.35)]; + [bezier12Path addCurveToPoint: CGPointMake(46.79, 23.68) controlPoint1: CGPointMake(47.32, 23.35) controlPoint2: CGPointMake(47.05, 23.45)]; + [bezier12Path addCurveToPoint: CGPointMake(46.31, 24.58) controlPoint1: CGPointMake(46.54, 23.9) controlPoint2: CGPointMake(46.39, 24.2)]; + [bezier12Path addLineToPoint: CGPointMake(45.7, 27.62)]; + [bezier12Path addLineToPoint: CGPointMake(44.34, 27.62)]; + [bezier12Path addLineToPoint: CGPointMake(45.42, 22.35)]; + [bezier12Path closePath]; + bezier12Path.miterLimit = 4; + + [color setFill]; + [bezier12Path fill]; + + + //// Bezier 13 Drawing + UIBezierPath* bezier13Path = [UIBezierPath bezierPath]; + [bezier13Path moveToPoint: CGPointMake(36.37, 22.35)]; + [bezier13Path addLineToPoint: CGPointMake(37.84, 22.35)]; + [bezier13Path addLineToPoint: CGPointMake(36.7, 27.65)]; + [bezier13Path addLineToPoint: CGPointMake(35.23, 27.65)]; + [bezier13Path addLineToPoint: CGPointMake(36.37, 22.35)]; + [bezier13Path closePath]; + [bezier13Path moveToPoint: CGPointMake(36.82, 20.41)]; + [bezier13Path addLineToPoint: CGPointMake(38.29, 20.41)]; + [bezier13Path addLineToPoint: CGPointMake(38.02, 21.69)]; + [bezier13Path addLineToPoint: CGPointMake(36.55, 21.69)]; + [bezier13Path addLineToPoint: CGPointMake(36.82, 20.41)]; + [bezier13Path closePath]; + bezier13Path.miterLimit = 4; + + [color setFill]; + [bezier13Path fill]; + + + //// Bezier 14 Drawing + UIBezierPath* bezier14Path = [UIBezierPath bezierPath]; + [bezier14Path moveToPoint: CGPointMake(39.13, 27.25)]; + [bezier14Path addCurveToPoint: CGPointMake(38.55, 25.76) controlPoint1: CGPointMake(38.75, 26.89) controlPoint2: CGPointMake(38.55, 26.39)]; + [bezier14Path addCurveToPoint: CGPointMake(38.57, 25.41) controlPoint1: CGPointMake(38.55, 25.66) controlPoint2: CGPointMake(38.55, 25.53)]; + [bezier14Path addCurveToPoint: CGPointMake(38.62, 25.03) controlPoint1: CGPointMake(38.6, 25.28) controlPoint2: CGPointMake(38.6, 25.13)]; + [bezier14Path addCurveToPoint: CGPointMake(39.74, 22.97) controlPoint1: CGPointMake(38.8, 24.18) controlPoint2: CGPointMake(39.18, 23.5)]; + [bezier14Path addCurveToPoint: CGPointMake(41.79, 22.22) controlPoint1: CGPointMake(40.32, 22.47) controlPoint2: CGPointMake(41, 22.22)]; + [bezier14Path addCurveToPoint: CGPointMake(43.36, 22.77) controlPoint1: CGPointMake(42.45, 22.22) controlPoint2: CGPointMake(42.98, 22.39)]; + [bezier14Path addCurveToPoint: CGPointMake(43.95, 24.28) controlPoint1: CGPointMake(43.74, 23.15) controlPoint2: CGPointMake(43.95, 23.62)]; + [bezier14Path addCurveToPoint: CGPointMake(43.92, 24.66) controlPoint1: CGPointMake(43.95, 24.38) controlPoint2: CGPointMake(43.95, 24.51)]; + [bezier14Path addCurveToPoint: CGPointMake(43.87, 25.06) controlPoint1: CGPointMake(43.89, 24.78) controlPoint2: CGPointMake(43.89, 24.93)]; + [bezier14Path addCurveToPoint: CGPointMake(42.76, 27.07) controlPoint1: CGPointMake(43.69, 25.92) controlPoint2: CGPointMake(43.34, 26.59)]; + [bezier14Path addCurveToPoint: CGPointMake(40.7, 27.82) controlPoint1: CGPointMake(42.17, 27.57) controlPoint2: CGPointMake(41.49, 27.82)]; + [bezier14Path addCurveToPoint: CGPointMake(39.13, 27.25) controlPoint1: CGPointMake(40.04, 27.78) controlPoint2: CGPointMake(39.51, 27.6)]; + [bezier14Path closePath]; + [bezier14Path moveToPoint: CGPointMake(41.94, 26.19)]; + [bezier14Path addCurveToPoint: CGPointMake(42.5, 24.94) controlPoint1: CGPointMake(42.19, 25.92) controlPoint2: CGPointMake(42.4, 25.49)]; + [bezier14Path addCurveToPoint: CGPointMake(42.55, 24.66) controlPoint1: CGPointMake(42.53, 24.86) controlPoint2: CGPointMake(42.53, 24.76)]; + [bezier14Path addCurveToPoint: CGPointMake(42.58, 24.41) controlPoint1: CGPointMake(42.55, 24.56) controlPoint2: CGPointMake(42.58, 24.48)]; + [bezier14Path addCurveToPoint: CGPointMake(42.32, 23.65) controlPoint1: CGPointMake(42.58, 24.08) controlPoint2: CGPointMake(42.5, 23.83)]; + [bezier14Path addCurveToPoint: CGPointMake(41.61, 23.38) controlPoint1: CGPointMake(42.15, 23.48) controlPoint2: CGPointMake(41.92, 23.38)]; + [bezier14Path addCurveToPoint: CGPointMake(40.63, 23.8) controlPoint1: CGPointMake(41.21, 23.38) controlPoint2: CGPointMake(40.88, 23.53)]; + [bezier14Path addCurveToPoint: CGPointMake(40.07, 25.09) controlPoint1: CGPointMake(40.37, 24.08) controlPoint2: CGPointMake(40.17, 24.51)]; + [bezier14Path addCurveToPoint: CGPointMake(40.02, 25.34) controlPoint1: CGPointMake(40.04, 25.16) controlPoint2: CGPointMake(40.04, 25.26)]; + [bezier14Path addCurveToPoint: CGPointMake(40.02, 25.59) controlPoint1: CGPointMake(40.02, 25.41) controlPoint2: CGPointMake(40.02, 25.51)]; + [bezier14Path addCurveToPoint: CGPointMake(40.27, 26.34) controlPoint1: CGPointMake(40.02, 25.91) controlPoint2: CGPointMake(40.1, 26.17)]; + [bezier14Path addCurveToPoint: CGPointMake(40.98, 26.62) controlPoint1: CGPointMake(40.45, 26.52) controlPoint2: CGPointMake(40.68, 26.62)]; + [bezier14Path addCurveToPoint: CGPointMake(41.94, 26.19) controlPoint1: CGPointMake(41.34, 26.62) controlPoint2: CGPointMake(41.66, 26.47)]; + [bezier14Path closePath]; + bezier14Path.miterLimit = 4; + + [color setFill]; + [bezier14Path fill]; + + + //// Bezier 15 Drawing + UIBezierPath* bezier15Path = [UIBezierPath bezierPath]; + [bezier15Path moveToPoint: CGPointMake(51.96, 19.05)]; + [bezier15Path addLineToPoint: CGPointMake(55.81, 19.05)]; + [bezier15Path addCurveToPoint: CGPointMake(57.51, 19.56) controlPoint1: CGPointMake(56.54, 19.05) controlPoint2: CGPointMake(57.13, 19.23)]; + [bezier15Path addCurveToPoint: CGPointMake(58.09, 20.99) controlPoint1: CGPointMake(57.89, 19.89) controlPoint2: CGPointMake(58.09, 20.36)]; + [bezier15Path addLineToPoint: CGPointMake(58.09, 21.02)]; + [bezier15Path addCurveToPoint: CGPointMake(58.07, 21.42) controlPoint1: CGPointMake(58.09, 21.14) controlPoint2: CGPointMake(58.09, 21.27)]; + [bezier15Path addCurveToPoint: CGPointMake(57.99, 21.85) controlPoint1: CGPointMake(58.04, 21.57) controlPoint2: CGPointMake(58.02, 21.7)]; + [bezier15Path addCurveToPoint: CGPointMake(56.83, 23.83) controlPoint1: CGPointMake(57.81, 22.68) controlPoint2: CGPointMake(57.43, 23.33)]; + [bezier15Path addCurveToPoint: CGPointMake(54.67, 24.58) controlPoint1: CGPointMake(56.22, 24.33) controlPoint2: CGPointMake(55.48, 24.58)]; + [bezier15Path addLineToPoint: CGPointMake(52.62, 24.58)]; + [bezier15Path addLineToPoint: CGPointMake(51.98, 27.7)]; + [bezier15Path addLineToPoint: CGPointMake(50.18, 27.7)]; + [bezier15Path addLineToPoint: CGPointMake(51.96, 19.05)]; + [bezier15Path closePath]; + [bezier15Path moveToPoint: CGPointMake(52.92, 23.05)]; + [bezier15Path addLineToPoint: CGPointMake(54.64, 23.05)]; + [bezier15Path addCurveToPoint: CGPointMake(55.71, 22.75) controlPoint1: CGPointMake(55.1, 23.05) controlPoint2: CGPointMake(55.45, 22.95)]; + [bezier15Path addCurveToPoint: CGPointMake(56.24, 21.79) controlPoint1: CGPointMake(55.96, 22.54) controlPoint2: CGPointMake(56.14, 22.22)]; + [bezier15Path addCurveToPoint: CGPointMake(56.26, 21.56) controlPoint1: CGPointMake(56.26, 21.72) controlPoint2: CGPointMake(56.26, 21.64)]; + [bezier15Path addCurveToPoint: CGPointMake(56.29, 21.39) controlPoint1: CGPointMake(56.26, 21.51) controlPoint2: CGPointMake(56.29, 21.44)]; + [bezier15Path addCurveToPoint: CGPointMake(55.96, 20.73) controlPoint1: CGPointMake(56.29, 21.08) controlPoint2: CGPointMake(56.19, 20.86)]; + [bezier15Path addCurveToPoint: CGPointMake(54.92, 20.53) controlPoint1: CGPointMake(55.73, 20.58) controlPoint2: CGPointMake(55.4, 20.53)]; + [bezier15Path addLineToPoint: CGPointMake(53.48, 20.53)]; + [bezier15Path addLineToPoint: CGPointMake(52.92, 23.05)]; + [bezier15Path closePath]; + bezier15Path.miterLimit = 4; + + [color setFill]; + [bezier15Path fill]; + + + //// Bezier 16 Drawing + UIBezierPath* bezier16Path = [UIBezierPath bezierPath]; + [bezier16Path moveToPoint: CGPointMake(66.13, 28.68)]; + [bezier16Path addCurveToPoint: CGPointMake(64.71, 30.89) controlPoint1: CGPointMake(65.57, 29.86) controlPoint2: CGPointMake(65.01, 30.56)]; + [bezier16Path addCurveToPoint: CGPointMake(62.25, 31.9) controlPoint1: CGPointMake(64.4, 31.22) controlPoint2: CGPointMake(63.77, 31.95)]; + [bezier16Path addLineToPoint: CGPointMake(62.38, 30.99)]; + [bezier16Path addCurveToPoint: CGPointMake(64.74, 28.08) controlPoint1: CGPointMake(63.64, 30.62) controlPoint2: CGPointMake(64.33, 28.86)]; + [bezier16Path addLineToPoint: CGPointMake(64.28, 22.37)]; + [bezier16Path addLineToPoint: CGPointMake(65.27, 22.35)]; + [bezier16Path addLineToPoint: CGPointMake(66.1, 22.35)]; + [bezier16Path addLineToPoint: CGPointMake(66.18, 25.92)]; + [bezier16Path addLineToPoint: CGPointMake(67.72, 22.35)]; + [bezier16Path addLineToPoint: CGPointMake(69.3, 22.35)]; + [bezier16Path addLineToPoint: CGPointMake(66.13, 28.68)]; + [bezier16Path closePath]; + bezier16Path.miterLimit = 4; + + [color setFill]; + [bezier16Path fill]; + + + //// Bezier 17 Drawing + UIBezierPath* bezier17Path = [UIBezierPath bezierPath]; + [bezier17Path moveToPoint: CGPointMake(61.74, 22.77)]; + [bezier17Path addLineToPoint: CGPointMake(61.11, 23.2)]; + [bezier17Path addCurveToPoint: CGPointMake(58.72, 22.9) controlPoint1: CGPointMake(60.45, 22.69) controlPoint2: CGPointMake(59.86, 22.4)]; + [bezier17Path addCurveToPoint: CGPointMake(60.15, 27.29) controlPoint1: CGPointMake(57.15, 23.62) controlPoint2: CGPointMake(55.86, 29.1)]; + [bezier17Path addLineToPoint: CGPointMake(60.4, 27.57)]; + [bezier17Path addLineToPoint: CGPointMake(62.1, 27.62)]; + [bezier17Path addLineToPoint: CGPointMake(63.21, 22.62)]; + [bezier17Path addLineToPoint: CGPointMake(61.74, 22.77)]; + [bezier17Path closePath]; + [bezier17Path moveToPoint: CGPointMake(60.78, 25.51)]; + [bezier17Path addCurveToPoint: CGPointMake(59.44, 26.69) controlPoint1: CGPointMake(60.5, 26.31) controlPoint2: CGPointMake(59.89, 26.82)]; + [bezier17Path addCurveToPoint: CGPointMake(59.06, 24.98) controlPoint1: CGPointMake(58.95, 26.54) controlPoint2: CGPointMake(58.8, 25.79)]; + [bezier17Path addCurveToPoint: CGPointMake(60.4, 23.8) controlPoint1: CGPointMake(59.34, 24.18) controlPoint2: CGPointMake(59.94, 23.68)]; + [bezier17Path addCurveToPoint: CGPointMake(60.78, 25.51) controlPoint1: CGPointMake(60.88, 23.95) controlPoint2: CGPointMake(61.06, 24.71)]; + [bezier17Path closePath]; + bezier17Path.miterLimit = 4; + + [color setFill]; + [bezier17Path fill]; + } +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIUnknownCardVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIUnknownCardVectorArtView.h new file mode 100644 index 0000000..fff4f3b --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIUnknownCardVectorArtView.h @@ -0,0 +1,5 @@ +#import "BTUICardVectorArtView.h" + +@interface BTUIUnknownCardVectorArtView : BTUICardVectorArtView + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIUnknownCardVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIUnknownCardVectorArtView.m new file mode 100644 index 0000000..45d5bad --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIUnknownCardVectorArtView.m @@ -0,0 +1,306 @@ +#import "BTUIUnknownCardVectorArtView.h" +#import "BTUI.h" + +@implementation BTUIUnknownCardVectorArtView + +- (void)drawArt { + + //// Color Declarations + UIColor* color2 = [UIColor colorWithRed: 0 green: 0 blue: 0 alpha: 0.099]; + UIColor* color1 = self.highlightColor ?: color2; + + //// Page-1 + { + //// Unknown + { + //// Card-# + { + //// CC-numbers + { + //// CC-number + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(6, 30)]; + [bezierPath addLineToPoint: CGPointMake(8, 30)]; + [bezierPath addLineToPoint: CGPointMake(8, 36)]; + [bezierPath addLineToPoint: CGPointMake(6, 36)]; + [bezierPath addLineToPoint: CGPointMake(6, 30)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + bezierPath.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezierPath fill]; + + + //// Bezier 2 Drawing + UIBezierPath* bezier2Path = [UIBezierPath bezierPath]; + [bezier2Path moveToPoint: CGPointMake(10, 30)]; + [bezier2Path addLineToPoint: CGPointMake(12, 30)]; + [bezier2Path addLineToPoint: CGPointMake(12, 36)]; + [bezier2Path addLineToPoint: CGPointMake(10, 36)]; + [bezier2Path addLineToPoint: CGPointMake(10, 30)]; + [bezier2Path closePath]; + bezier2Path.miterLimit = 4; + + bezier2Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier2Path fill]; + + + //// Bezier 3 Drawing + UIBezierPath* bezier3Path = [UIBezierPath bezierPath]; + [bezier3Path moveToPoint: CGPointMake(14, 30)]; + [bezier3Path addLineToPoint: CGPointMake(16, 30)]; + [bezier3Path addLineToPoint: CGPointMake(16, 36)]; + [bezier3Path addLineToPoint: CGPointMake(14, 36)]; + [bezier3Path addLineToPoint: CGPointMake(14, 30)]; + [bezier3Path closePath]; + bezier3Path.miterLimit = 4; + + bezier3Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier3Path fill]; + + + //// Bezier 4 Drawing + UIBezierPath* bezier4Path = [UIBezierPath bezierPath]; + [bezier4Path moveToPoint: CGPointMake(18, 30)]; + [bezier4Path addLineToPoint: CGPointMake(20, 30)]; + [bezier4Path addLineToPoint: CGPointMake(20, 36)]; + [bezier4Path addLineToPoint: CGPointMake(18, 36)]; + [bezier4Path addLineToPoint: CGPointMake(18, 30)]; + [bezier4Path closePath]; + bezier4Path.miterLimit = 4; + + bezier4Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier4Path fill]; + + + //// Bezier 5 Drawing + UIBezierPath* bezier5Path = [UIBezierPath bezierPath]; + [bezier5Path moveToPoint: CGPointMake(26, 30)]; + [bezier5Path addLineToPoint: CGPointMake(28, 30)]; + [bezier5Path addLineToPoint: CGPointMake(28, 36)]; + [bezier5Path addLineToPoint: CGPointMake(26, 36)]; + [bezier5Path addLineToPoint: CGPointMake(26, 30)]; + [bezier5Path closePath]; + bezier5Path.miterLimit = 4; + + bezier5Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier5Path fill]; + + + //// Bezier 6 Drawing + UIBezierPath* bezier6Path = [UIBezierPath bezierPath]; + [bezier6Path moveToPoint: CGPointMake(30, 30)]; + [bezier6Path addLineToPoint: CGPointMake(32, 30)]; + [bezier6Path addLineToPoint: CGPointMake(32, 36)]; + [bezier6Path addLineToPoint: CGPointMake(30, 36)]; + [bezier6Path addLineToPoint: CGPointMake(30, 30)]; + [bezier6Path closePath]; + bezier6Path.miterLimit = 4; + + bezier6Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier6Path fill]; + + + //// Bezier 7 Drawing + UIBezierPath* bezier7Path = [UIBezierPath bezierPath]; + [bezier7Path moveToPoint: CGPointMake(34, 30)]; + [bezier7Path addLineToPoint: CGPointMake(36, 30)]; + [bezier7Path addLineToPoint: CGPointMake(36, 36)]; + [bezier7Path addLineToPoint: CGPointMake(34, 36)]; + [bezier7Path addLineToPoint: CGPointMake(34, 30)]; + [bezier7Path closePath]; + bezier7Path.miterLimit = 4; + + bezier7Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier7Path fill]; + + + //// Bezier 8 Drawing + UIBezierPath* bezier8Path = [UIBezierPath bezierPath]; + [bezier8Path moveToPoint: CGPointMake(38, 30)]; + [bezier8Path addLineToPoint: CGPointMake(40, 30)]; + [bezier8Path addLineToPoint: CGPointMake(40, 36)]; + [bezier8Path addLineToPoint: CGPointMake(38, 36)]; + [bezier8Path addLineToPoint: CGPointMake(38, 30)]; + [bezier8Path closePath]; + bezier8Path.miterLimit = 4; + + bezier8Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier8Path fill]; + + + //// Bezier 9 Drawing + UIBezierPath* bezier9Path = [UIBezierPath bezierPath]; + [bezier9Path moveToPoint: CGPointMake(46, 30)]; + [bezier9Path addLineToPoint: CGPointMake(48, 30)]; + [bezier9Path addLineToPoint: CGPointMake(48, 36)]; + [bezier9Path addLineToPoint: CGPointMake(46, 36)]; + [bezier9Path addLineToPoint: CGPointMake(46, 30)]; + [bezier9Path closePath]; + bezier9Path.miterLimit = 4; + + bezier9Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier9Path fill]; + + + //// Bezier 10 Drawing + UIBezierPath* bezier10Path = [UIBezierPath bezierPath]; + [bezier10Path moveToPoint: CGPointMake(50, 30)]; + [bezier10Path addLineToPoint: CGPointMake(52, 30)]; + [bezier10Path addLineToPoint: CGPointMake(52, 36)]; + [bezier10Path addLineToPoint: CGPointMake(50, 36)]; + [bezier10Path addLineToPoint: CGPointMake(50, 30)]; + [bezier10Path closePath]; + bezier10Path.miterLimit = 4; + + bezier10Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier10Path fill]; + + + //// Bezier 11 Drawing + UIBezierPath* bezier11Path = [UIBezierPath bezierPath]; + [bezier11Path moveToPoint: CGPointMake(54, 30)]; + [bezier11Path addLineToPoint: CGPointMake(56, 30)]; + [bezier11Path addLineToPoint: CGPointMake(56, 36)]; + [bezier11Path addLineToPoint: CGPointMake(54, 36)]; + [bezier11Path addLineToPoint: CGPointMake(54, 30)]; + [bezier11Path closePath]; + bezier11Path.miterLimit = 4; + + bezier11Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier11Path fill]; + + + //// Bezier 12 Drawing + UIBezierPath* bezier12Path = [UIBezierPath bezierPath]; + [bezier12Path moveToPoint: CGPointMake(58, 30)]; + [bezier12Path addLineToPoint: CGPointMake(60, 30)]; + [bezier12Path addLineToPoint: CGPointMake(60, 36)]; + [bezier12Path addLineToPoint: CGPointMake(58, 36)]; + [bezier12Path addLineToPoint: CGPointMake(58, 30)]; + [bezier12Path closePath]; + bezier12Path.miterLimit = 4; + + bezier12Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier12Path fill]; + + + //// Bezier 13 Drawing + UIBezierPath* bezier13Path = [UIBezierPath bezierPath]; + [bezier13Path moveToPoint: CGPointMake(66, 30)]; + [bezier13Path addLineToPoint: CGPointMake(68, 30)]; + [bezier13Path addLineToPoint: CGPointMake(68, 36)]; + [bezier13Path addLineToPoint: CGPointMake(66, 36)]; + [bezier13Path addLineToPoint: CGPointMake(66, 30)]; + [bezier13Path closePath]; + bezier13Path.miterLimit = 4; + + bezier13Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier13Path fill]; + + + //// Bezier 14 Drawing + UIBezierPath* bezier14Path = [UIBezierPath bezierPath]; + [bezier14Path moveToPoint: CGPointMake(70, 30)]; + [bezier14Path addLineToPoint: CGPointMake(72, 30)]; + [bezier14Path addLineToPoint: CGPointMake(72, 36)]; + [bezier14Path addLineToPoint: CGPointMake(70, 36)]; + [bezier14Path addLineToPoint: CGPointMake(70, 30)]; + [bezier14Path closePath]; + bezier14Path.miterLimit = 4; + + bezier14Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier14Path fill]; + + + //// Bezier 15 Drawing + UIBezierPath* bezier15Path = [UIBezierPath bezierPath]; + [bezier15Path moveToPoint: CGPointMake(74, 30)]; + [bezier15Path addLineToPoint: CGPointMake(76, 30)]; + [bezier15Path addLineToPoint: CGPointMake(76, 36)]; + [bezier15Path addLineToPoint: CGPointMake(74, 36)]; + [bezier15Path addLineToPoint: CGPointMake(74, 30)]; + [bezier15Path closePath]; + bezier15Path.miterLimit = 4; + + bezier15Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier15Path fill]; + + + //// Bezier 16 Drawing + UIBezierPath* bezier16Path = [UIBezierPath bezierPath]; + [bezier16Path moveToPoint: CGPointMake(78, 30)]; + [bezier16Path addLineToPoint: CGPointMake(80, 30)]; + [bezier16Path addLineToPoint: CGPointMake(80, 36)]; + [bezier16Path addLineToPoint: CGPointMake(78, 36)]; + [bezier16Path addLineToPoint: CGPointMake(78, 30)]; + [bezier16Path closePath]; + bezier16Path.miterLimit = 4; + + bezier16Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier16Path fill]; + } + + + //// Rectangle Drawing + UIBezierPath* rectanglePath = [UIBezierPath bezierPathWithRect: CGRectMake(26, 42, 14, 2)]; + [color2 setFill]; + [rectanglePath fill]; + + + //// Rectangle 2 Drawing + UIBezierPath* rectangle2Path = [UIBezierPath bezierPathWithRect: CGRectMake(6, 46, 34, 2)]; + [color2 setFill]; + [rectangle2Path fill]; + } + + + //// Rounded Rectangle Drawing + UIBezierPath* roundedRectanglePath = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(6, 6, 14, 14) cornerRadius: 0.75]; + [color2 setFill]; + [roundedRectanglePath fill]; + + + //// Rounded Rectangle 2 Drawing + UIBezierPath* roundedRectangle2Path = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(72, 40, 8, 8) cornerRadius: 0.75]; + [color2 setFill]; + [roundedRectangle2Path fill]; + } + } + } +} +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVenmoMonogramCardView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVenmoMonogramCardView.h new file mode 100644 index 0000000..5e23216 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVenmoMonogramCardView.h @@ -0,0 +1,5 @@ +#import "BTUICardVectorArtView.h" + +@interface BTUIVenmoMonogramCardView : BTUICardVectorArtView + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVenmoMonogramCardView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVenmoMonogramCardView.m new file mode 100644 index 0000000..18b8692 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVenmoMonogramCardView.m @@ -0,0 +1,36 @@ +#import "BTUIVenmoMonogramCardView.h" + +@implementation BTUIVenmoMonogramCardView + +- (void)drawArt { + //// Color Declarations + UIColor* fillColor = [UIColor colorWithRed: 0.201 green: 0.463 blue: 0.682 alpha: 1]; + + //// Page-1 + { + //// Artboard-1 + { + //// Fill-1 Drawing + UIBezierPath* fill1Path = [UIBezierPath bezierPath]; + [fill1Path moveToPoint: CGPointMake(59.25, 9)]; + [fill1Path addCurveToPoint: CGPointMake(61.25, 16.65) controlPoint1: CGPointMake(60.63, 11.3) controlPoint2: CGPointMake(61.25, 13.66)]; + [fill1Path addCurveToPoint: CGPointMake(46.66, 47.26) controlPoint1: CGPointMake(61.25, 26.18) controlPoint2: CGPointMake(53.2, 38.57)]; + [fill1Path addLineToPoint: CGPointMake(31.74, 47.26)]; + [fill1Path addLineToPoint: CGPointMake(25.75, 11.09)]; + [fill1Path addLineToPoint: CGPointMake(38.82, 9.83)]; + [fill1Path addLineToPoint: CGPointMake(41.98, 35.57)]; + [fill1Path addCurveToPoint: CGPointMake(48.59, 17.84) controlPoint1: CGPointMake(44.94, 30.7) controlPoint2: CGPointMake(48.59, 23.05)]; + [fill1Path addCurveToPoint: CGPointMake(47.35, 11.43) controlPoint1: CGPointMake(48.59, 14.98) controlPoint2: CGPointMake(48.11, 13.04)]; + [fill1Path addLineToPoint: CGPointMake(59.25, 9)]; + [fill1Path closePath]; + fill1Path.miterLimit = 4; + + fill1Path.usesEvenOddFillRule = YES; + + [fillColor setFill]; + [fill1Path fill]; + } + } +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVenmoWordmarkVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVenmoWordmarkVectorArtView.h new file mode 100644 index 0000000..37c8059 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVenmoWordmarkVectorArtView.h @@ -0,0 +1,7 @@ +#import "BTUIVectorArtView.h" + +@interface BTUIVenmoWordmarkVectorArtView : BTUIVectorArtView + +@property (nonatomic, strong) UIColor *color; + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVenmoWordmarkVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVenmoWordmarkVectorArtView.m new file mode 100644 index 0000000..9deb4c3 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVenmoWordmarkVectorArtView.m @@ -0,0 +1,189 @@ +#import "BTUIVenmoWordmarkVectorArtView.h" + +@implementation BTUIVenmoWordmarkVectorArtView + +- (id)init { + self = [super init]; + if (self) { + self.artDimensions = CGSizeMake(132, 88); + self.opaque = NO; + } + return self; +} + +- (void)setColor:(UIColor *)color { + _color = color; + [self setNeedsDisplay]; +} + +- (void)drawArt { + //// Color Declarations + UIColor* color = self.color; //[UIColor colorWithRed: 0.194 green: 0.507 blue: 0.764 alpha: 1]; + + //// Assets + { + //// button-venmo + { + //// Rectangle Drawing + + + //// logo/venmo + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(70.02, 53.98)]; + [bezierPath addCurveToPoint: CGPointMake(70.02, 52.78) controlPoint1: CGPointMake(70.02, 53.43) controlPoint2: CGPointMake(69.97, 53.09)]; + [bezierPath addCurveToPoint: CGPointMake(72.56, 36.46) controlPoint1: CGPointMake(70.87, 47.34) controlPoint2: CGPointMake(71.77, 41.9)]; + [bezierPath addCurveToPoint: CGPointMake(74.94, 34.44) controlPoint1: CGPointMake(72.87, 34.33) controlPoint2: CGPointMake(72.83, 34.43)]; + [bezierPath addCurveToPoint: CGPointMake(76.91, 34.43) controlPoint1: CGPointMake(75.59, 34.44) controlPoint2: CGPointMake(76.25, 34.48)]; + [bezierPath addCurveToPoint: CGPointMake(78.78, 35.72) controlPoint1: CGPointMake(77.84, 34.35) controlPoint2: CGPointMake(78.63, 34.46)]; + [bezierPath addCurveToPoint: CGPointMake(79.63, 35.35) controlPoint1: CGPointMake(79.13, 35.57) controlPoint2: CGPointMake(79.39, 35.49)]; + [bezierPath addCurveToPoint: CGPointMake(83.08, 34.11) controlPoint1: CGPointMake(80.7, 34.71) controlPoint2: CGPointMake(81.84, 34.3)]; + [bezierPath addCurveToPoint: CGPointMake(87.94, 35.56) controlPoint1: CGPointMake(84.94, 33.83) controlPoint2: CGPointMake(86.59, 34.13)]; + [bezierPath addCurveToPoint: CGPointMake(88.47, 35.99) controlPoint1: CGPointMake(88.08, 35.71) controlPoint2: CGPointMake(88.26, 35.82)]; + [bezierPath addCurveToPoint: CGPointMake(90.53, 34.9) controlPoint1: CGPointMake(89.16, 35.62) controlPoint2: CGPointMake(89.83, 35.22)]; + [bezierPath addCurveToPoint: CGPointMake(96.29, 34.23) controlPoint1: CGPointMake(92.38, 34.05) controlPoint2: CGPointMake(94.29, 33.75)]; + [bezierPath addCurveToPoint: CGPointMake(99, 37.48) controlPoint1: CGPointMake(97.97, 34.63) controlPoint2: CGPointMake(98.97, 35.72)]; + [bezierPath addCurveToPoint: CGPointMake(98.7, 41.97) controlPoint1: CGPointMake(99.02, 38.98) controlPoint2: CGPointMake(98.91, 40.49)]; + [bezierPath addCurveToPoint: CGPointMake(97.05, 52.6) controlPoint1: CGPointMake(98.2, 45.52) controlPoint2: CGPointMake(97.6, 49.06)]; + [bezierPath addCurveToPoint: CGPointMake(95.52, 53.99) controlPoint1: CGPointMake(96.84, 53.93) controlPoint2: CGPointMake(96.8, 53.99)]; + [bezierPath addCurveToPoint: CGPointMake(91.7, 53.99) controlPoint1: CGPointMake(94.24, 54) controlPoint2: CGPointMake(92.97, 54)]; + [bezierPath addCurveToPoint: CGPointMake(90.47, 53.9) controlPoint1: CGPointMake(91.34, 53.99) controlPoint2: CGPointMake(90.98, 53.94)]; + [bezierPath addCurveToPoint: CGPointMake(90.55, 52.4) controlPoint1: CGPointMake(90.5, 53.35) controlPoint2: CGPointMake(90.48, 52.87)]; + [bezierPath addCurveToPoint: CGPointMake(92.22, 41.39) controlPoint1: CGPointMake(91.1, 48.73) controlPoint2: CGPointMake(91.66, 45.06)]; + [bezierPath addCurveToPoint: CGPointMake(92.28, 40.52) controlPoint1: CGPointMake(92.26, 41.1) controlPoint2: CGPointMake(92.32, 40.8)]; + [bezierPath addCurveToPoint: CGPointMake(91.24, 39.51) controlPoint1: CGPointMake(92.21, 39.89) controlPoint2: CGPointMake(91.84, 39.46)]; + [bezierPath addCurveToPoint: CGPointMake(89.13, 40.07) controlPoint1: CGPointMake(90.52, 39.58) controlPoint2: CGPointMake(89.78, 39.77)]; + [bezierPath addCurveToPoint: CGPointMake(88.65, 41.13) controlPoint1: CGPointMake(88.86, 40.2) controlPoint2: CGPointMake(88.71, 40.75)]; + [bezierPath addCurveToPoint: CGPointMake(87.43, 48.92) controlPoint1: CGPointMake(88.22, 43.72) controlPoint2: CGPointMake(87.83, 46.32)]; + [bezierPath addCurveToPoint: CGPointMake(86.63, 53.9) controlPoint1: CGPointMake(87.17, 50.56) controlPoint2: CGPointMake(86.91, 52.2)]; + [bezierPath addLineToPoint: CGPointMake(80.17, 53.9)]; + [bezierPath addCurveToPoint: CGPointMake(80.62, 50.53) controlPoint1: CGPointMake(80.33, 52.73) controlPoint2: CGPointMake(80.45, 51.62)]; + [bezierPath addCurveToPoint: CGPointMake(81.96, 42.12) controlPoint1: CGPointMake(81.06, 47.72) controlPoint2: CGPointMake(81.52, 44.93)]; + [bezierPath addCurveToPoint: CGPointMake(82.02, 40.63) controlPoint1: CGPointMake(82.03, 41.63) controlPoint2: CGPointMake(82.08, 41.12)]; + [bezierPath addCurveToPoint: CGPointMake(81.53, 39.69) controlPoint1: CGPointMake(81.97, 40.29) controlPoint2: CGPointMake(81.79, 39.88)]; + [bezierPath addCurveToPoint: CGPointMake(78.43, 40.93) controlPoint1: CGPointMake(80.64, 39.03) controlPoint2: CGPointMake(78.64, 39.84)]; + [bezierPath addCurveToPoint: CGPointMake(77.86, 44.51) controlPoint1: CGPointMake(78.2, 42.12) controlPoint2: CGPointMake(78.04, 43.32)]; + [bezierPath addCurveToPoint: CGPointMake(76.58, 53.05) controlPoint1: CGPointMake(77.43, 47.36) controlPoint2: CGPointMake(77, 50.2)]; + [bezierPath addCurveToPoint: CGPointMake(75.81, 53.98) controlPoint1: CGPointMake(76.51, 53.55) controlPoint2: CGPointMake(76.4, 53.97)]; + [bezierPath addCurveToPoint: CGPointMake(70.02, 53.98) controlPoint1: CGPointMake(73.93, 53.98) controlPoint2: CGPointMake(72.05, 53.98)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(65.64, 53.85)]; + [bezierPath addCurveToPoint: CGPointMake(59.25, 53.73) controlPoint1: CGPointMake(64, 54.09) controlPoint2: CGPointMake(60.19, 54.03)]; + [bezierPath addCurveToPoint: CGPointMake(59.71, 50.43) controlPoint1: CGPointMake(59.4, 52.64) controlPoint2: CGPointMake(59.54, 51.53)]; + [bezierPath addCurveToPoint: CGPointMake(61.06, 41.78) controlPoint1: CGPointMake(60.16, 47.55) controlPoint2: CGPointMake(60.61, 44.67)]; + [bezierPath addCurveToPoint: CGPointMake(58.66, 39.69) controlPoint1: CGPointMake(61.39, 39.72) controlPoint2: CGPointMake(60.6, 39.04)]; + [bezierPath addCurveToPoint: CGPointMake(57.43, 41.2) controlPoint1: CGPointMake(57.9, 39.94) controlPoint2: CGPointMake(57.55, 40.4)]; + [bezierPath addCurveToPoint: CGPointMake(55.71, 52.57) controlPoint1: CGPointMake(56.88, 45) controlPoint2: CGPointMake(56.29, 48.78)]; + [bezierPath addCurveToPoint: CGPointMake(54.19, 53.98) controlPoint1: CGPointMake(55.51, 53.92) controlPoint2: CGPointMake(55.46, 53.97)]; + [bezierPath addCurveToPoint: CGPointMake(49, 53.98) controlPoint1: CGPointMake(52.51, 53.99) controlPoint2: CGPointMake(50.84, 53.98)]; + [bezierPath addCurveToPoint: CGPointMake(49.38, 50.94) controlPoint1: CGPointMake(49.13, 52.89) controlPoint2: CGPointMake(49.22, 51.91)]; + [bezierPath addCurveToPoint: CGPointMake(51.46, 37.73) controlPoint1: CGPointMake(50.06, 46.54) controlPoint2: CGPointMake(50.76, 42.14)]; + [bezierPath addCurveToPoint: CGPointMake(51.8, 35.38) controlPoint1: CGPointMake(51.58, 36.95) controlPoint2: CGPointMake(51.71, 36.17)]; + [bezierPath addCurveToPoint: CGPointMake(52.73, 34.45) controlPoint1: CGPointMake(51.86, 34.79) controlPoint2: CGPointMake(52.12, 34.45)]; + [bezierPath addCurveToPoint: CGPointMake(56.91, 34.44) controlPoint1: CGPointMake(54.12, 34.45) controlPoint2: CGPointMake(55.52, 34.47)]; + [bezierPath addCurveToPoint: CGPointMake(57.91, 35.69) controlPoint1: CGPointMake(57.69, 34.43) controlPoint2: CGPointMake(57.61, 35.12)]; + [bezierPath addCurveToPoint: CGPointMake(59.21, 35.06) controlPoint1: CGPointMake(58.36, 35.47) controlPoint2: CGPointMake(58.79, 35.27)]; + [bezierPath addCurveToPoint: CGPointMake(65.29, 34.26) controlPoint1: CGPointMake(61.15, 34.1) controlPoint2: CGPointMake(63.16, 33.69)]; + [bezierPath addCurveToPoint: CGPointMake(67.84, 37) controlPoint1: CGPointMake(66.7, 34.64) controlPoint2: CGPointMake(67.49, 35.55)]; + [bezierPath addCurveToPoint: CGPointMake(67.73, 40.97) controlPoint1: CGPointMake(68.17, 38.36) controlPoint2: CGPointMake(67.92, 39.67)]; + [bezierPath addCurveToPoint: CGPointMake(65.8, 53.33) controlPoint1: CGPointMake(67.14, 45.1) controlPoint2: CGPointMake(66.45, 49.21)]; + [bezierPath addCurveToPoint: CGPointMake(65.64, 53.85) controlPoint1: CGPointMake(65.77, 53.49) controlPoint2: CGPointMake(65.71, 53.64)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(118.98, 42.12)]; + [bezierPath addCurveToPoint: CGPointMake(117.38, 48.99) controlPoint1: CGPointMake(119.11, 44.56) controlPoint2: CGPointMake(118.6, 46.87)]; + [bezierPath addCurveToPoint: CGPointMake(108.97, 54) controlPoint1: CGPointMake(115.52, 52.2) controlPoint2: CGPointMake(112.75, 53.97)]; + [bezierPath addCurveToPoint: CGPointMake(105.76, 53.8) controlPoint1: CGPointMake(107.9, 54) controlPoint2: CGPointMake(106.8, 54.02)]; + [bezierPath addCurveToPoint: CGPointMake(101.19, 49.25) controlPoint1: CGPointMake(103.3, 53.26) controlPoint2: CGPointMake(101.73, 51.62)]; + [bezierPath addCurveToPoint: CGPointMake(102.47, 38.85) controlPoint1: CGPointMake(100.37, 45.67) controlPoint2: CGPointMake(100.59, 42.13)]; + [bezierPath addCurveToPoint: CGPointMake(109.3, 34.21) controlPoint1: CGPointMake(103.99, 36.22) controlPoint2: CGPointMake(106.29, 34.71)]; + [bezierPath addCurveToPoint: CGPointMake(113.49, 34.2) controlPoint1: CGPointMake(110.7, 33.97) controlPoint2: CGPointMake(112.08, 33.96)]; + [bezierPath addCurveToPoint: CGPointMake(118.97, 40.15) controlPoint1: CGPointMake(116.67, 34.74) controlPoint2: CGPointMake(118.72, 36.92)]; + [bezierPath addCurveToPoint: CGPointMake(118.98, 42.12) controlPoint1: CGPointMake(119.02, 40.8) controlPoint2: CGPointMake(118.98, 41.46)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(107.37, 45.48)]; + [bezierPath addCurveToPoint: CGPointMake(107.54, 45.5) controlPoint1: CGPointMake(107.43, 45.48) controlPoint2: CGPointMake(107.48, 45.49)]; + [bezierPath addCurveToPoint: CGPointMake(107.55, 47.1) controlPoint1: CGPointMake(107.54, 46.04) controlPoint2: CGPointMake(107.5, 46.57)]; + [bezierPath addCurveToPoint: CGPointMake(108.89, 48.99) controlPoint1: CGPointMake(107.64, 48.09) controlPoint2: CGPointMake(108.18, 48.82)]; + [bezierPath addCurveToPoint: CGPointMake(110.96, 47.92) controlPoint1: CGPointMake(109.58, 49.16) controlPoint2: CGPointMake(110.4, 48.74)]; + [bezierPath addCurveToPoint: CGPointMake(111.09, 47.71) controlPoint1: CGPointMake(111, 47.85) controlPoint2: CGPointMake(111.05, 47.79)]; + [bezierPath addCurveToPoint: CGPointMake(112.18, 40.52) controlPoint1: CGPointMake(112.23, 45.43) controlPoint2: CGPointMake(112.51, 43.02)]; + [bezierPath addCurveToPoint: CGPointMake(111.11, 39.14) controlPoint1: CGPointMake(112.1, 39.9) controlPoint2: CGPointMake(111.81, 39.33)]; + [bezierPath addCurveToPoint: CGPointMake(109.2, 39.73) controlPoint1: CGPointMake(110.36, 38.95) controlPoint2: CGPointMake(109.66, 39.14)]; + [bezierPath addCurveToPoint: CGPointMake(108.08, 41.75) controlPoint1: CGPointMake(108.73, 40.33) controlPoint2: CGPointMake(108.29, 41.03)]; + [bezierPath addCurveToPoint: CGPointMake(107.37, 45.48) controlPoint1: CGPointMake(107.74, 42.96) controlPoint2: CGPointMake(107.6, 44.23)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(12, 35.08)]; + [bezierPath addCurveToPoint: CGPointMake(13.83, 34.83) controlPoint1: CGPointMake(12.73, 34.98) controlPoint2: CGPointMake(13.28, 34.89)]; + [bezierPath addCurveToPoint: CGPointMake(17.44, 34.46) controlPoint1: CGPointMake(15.03, 34.69) controlPoint2: CGPointMake(16.24, 34.55)]; + [bezierPath addCurveToPoint: CGPointMake(18.72, 35.54) controlPoint1: CGPointMake(18.39, 34.39) controlPoint2: CGPointMake(18.6, 34.58)]; + [bezierPath addCurveToPoint: CGPointMake(19.75, 44.26) controlPoint1: CGPointMake(19.08, 38.45) controlPoint2: CGPointMake(19.4, 41.36)]; + [bezierPath addCurveToPoint: CGPointMake(20.28, 47.47) controlPoint1: CGPointMake(19.87, 45.33) controlPoint2: CGPointMake(20.02, 46.39)]; + [bezierPath addCurveToPoint: CGPointMake(23.06, 41.7) controlPoint1: CGPointMake(21.55, 45.7) controlPoint2: CGPointMake(22.38, 43.74)]; + [bezierPath addCurveToPoint: CGPointMake(23.16, 35.38) controlPoint1: CGPointMake(23.75, 39.62) controlPoint2: CGPointMake(23.88, 37.53)]; + [bezierPath addCurveToPoint: CGPointMake(23.98, 34.99) controlPoint1: CGPointMake(23.49, 35.22) controlPoint2: CGPointMake(23.72, 35.05)]; + [bezierPath addCurveToPoint: CGPointMake(28.25, 34.07) controlPoint1: CGPointMake(25.4, 34.67) controlPoint2: CGPointMake(26.82, 34.36)]; + [bezierPath addCurveToPoint: CGPointMake(29.46, 34.73) controlPoint1: CGPointMake(29.01, 33.91) controlPoint2: CGPointMake(29.17, 33.97)]; + [bezierPath addCurveToPoint: CGPointMake(29.93, 36.66) controlPoint1: CGPointMake(29.69, 35.35) controlPoint2: CGPointMake(29.86, 36.01)]; + [bezierPath addCurveToPoint: CGPointMake(28.75, 43.64) controlPoint1: CGPointMake(30.19, 39.1) controlPoint2: CGPointMake(29.68, 41.41)]; + [bezierPath addCurveToPoint: CGPointMake(23.03, 53.4) controlPoint1: CGPointMake(27.27, 47.16) controlPoint2: CGPointMake(25.23, 50.33)]; + [bezierPath addCurveToPoint: CGPointMake(22.17, 53.97) controlPoint1: CGPointMake(22.84, 53.67) controlPoint2: CGPointMake(22.46, 53.96)]; + [bezierPath addCurveToPoint: CGPointMake(15.03, 54) controlPoint1: CGPointMake(19.83, 54.02) controlPoint2: CGPointMake(17.49, 54)]; + [bezierPath addCurveToPoint: CGPointMake(13.49, 44.53) controlPoint1: CGPointMake(14.51, 50.78) controlPoint2: CGPointMake(13.99, 47.65)]; + [bezierPath addCurveToPoint: CGPointMake(12, 35.08) controlPoint1: CGPointMake(12.99, 41.41) controlPoint2: CGPointMake(12.4, 38.31)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(38.37, 45.72)]; + [bezierPath addCurveToPoint: CGPointMake(41.21, 48.8) controlPoint1: CGPointMake(38.38, 47.8) controlPoint2: CGPointMake(39.3, 48.75)]; + [bezierPath addCurveToPoint: CGPointMake(45.43, 47.88) controlPoint1: CGPointMake(42.69, 48.84) controlPoint2: CGPointMake(44.07, 48.4)]; + [bezierPath addCurveToPoint: CGPointMake(46.75, 47.34) controlPoint1: CGPointMake(45.8, 47.73) controlPoint2: CGPointMake(46.18, 47.57)]; + [bezierPath addCurveToPoint: CGPointMake(45.97, 52.45) controlPoint1: CGPointMake(46.49, 49.15) controlPoint2: CGPointMake(46.28, 50.81)]; + [bezierPath addCurveToPoint: CGPointMake(45.18, 53.12) controlPoint1: CGPointMake(45.92, 52.72) controlPoint2: CGPointMake(45.5, 53.03)]; + [bezierPath addCurveToPoint: CGPointMake(42.05, 53.85) controlPoint1: CGPointMake(44.15, 53.42) controlPoint2: CGPointMake(43.11, 53.75)]; + [bezierPath addCurveToPoint: CGPointMake(37.72, 53.88) controlPoint1: CGPointMake(40.62, 53.98) controlPoint2: CGPointMake(39.14, 54.06)]; + [bezierPath addCurveToPoint: CGPointMake(31.74, 47.78) controlPoint1: CGPointMake(34.3, 53.45) controlPoint2: CGPointMake(32.15, 51.27)]; + [bezierPath addCurveToPoint: CGPointMake(34.04, 38.05) controlPoint1: CGPointMake(31.32, 44.29) controlPoint2: CGPointMake(31.95, 40.99)]; + [bezierPath addCurveToPoint: CGPointMake(44.6, 34.35) controlPoint1: CGPointMake(36.45, 34.65) controlPoint2: CGPointMake(40.9, 33.31)]; + [bezierPath addCurveToPoint: CGPointMake(46.79, 42.8) controlPoint1: CGPointMake(48.43, 35.42) controlPoint2: CGPointMake(49.6, 39.99)]; + [bezierPath addCurveToPoint: CGPointMake(41.48, 45.3) controlPoint1: CGPointMake(45.32, 44.27) controlPoint2: CGPointMake(43.45, 44.9)]; + [bezierPath addCurveToPoint: CGPointMake(38.37, 45.72) controlPoint1: CGPointMake(40.48, 45.5) controlPoint2: CGPointMake(39.45, 45.58)]; + [bezierPath closePath]; + [bezierPath moveToPoint: CGPointMake(38.49, 42.08)]; + [bezierPath addCurveToPoint: CGPointMake(42.3, 40.96) controlPoint1: CGPointMake(40.01, 42.18) controlPoint2: CGPointMake(41.22, 41.79)]; + [bezierPath addCurveToPoint: CGPointMake(42.73, 40.36) controlPoint1: CGPointMake(42.49, 40.82) controlPoint2: CGPointMake(42.63, 40.58)]; + [bezierPath addCurveToPoint: CGPointMake(42.52, 38.87) controlPoint1: CGPointMake(42.96, 39.83) controlPoint2: CGPointMake(42.92, 39.31)]; + [bezierPath addCurveToPoint: CGPointMake(41.16, 38.52) controlPoint1: CGPointMake(42.16, 38.46) controlPoint2: CGPointMake(41.68, 38.36)]; + [bezierPath addCurveToPoint: CGPointMake(40.36, 38.85) controlPoint1: CGPointMake(40.88, 38.6) controlPoint2: CGPointMake(40.59, 38.69)]; + [bezierPath addCurveToPoint: CGPointMake(38.49, 42.08) controlPoint1: CGPointMake(39.31, 39.6) controlPoint2: CGPointMake(38.62, 40.57)]; + [bezierPath addLineToPoint: CGPointMake(38.49, 42.08)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + bezierPath.usesEvenOddFillRule = YES; + + [color setFill]; + [bezierPath fill]; + } + } + } +} + +- (void)updateConstraints { + NSLayoutConstraint *aspectRatioConstraint = [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeWidth + relatedBy:NSLayoutRelationEqual + toItem:self + attribute:NSLayoutAttributeHeight + multiplier:(self.artDimensions.width / self.artDimensions.height) + constant:0.0f]; + aspectRatioConstraint.priority = UILayoutPriorityRequired; + + [self addConstraint:aspectRatioConstraint]; + + [super updateConstraints]; +} + +- (UILayoutPriority)contentCompressionResistancePriorityForAxis:(__unused UILayoutConstraintAxis)axis { + return UILayoutPriorityRequired; +} + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVisaVectorArtView.h b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVisaVectorArtView.h new file mode 100644 index 0000000..8516593 --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVisaVectorArtView.h @@ -0,0 +1,5 @@ +#import "BTUICardVectorArtView.h" + +@interface BTUIVisaVectorArtView : BTUICardVectorArtView + +@end diff --git a/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVisaVectorArtView.m b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVisaVectorArtView.m new file mode 100644 index 0000000..4ff958a --- /dev/null +++ b/Pods/Braintree/BraintreeUI/Views/Vector Art/BTUIVisaVectorArtView.m @@ -0,0 +1,128 @@ +#import "BTUIVisaVectorArtView.h" + +@implementation BTUIVisaVectorArtView + +- (void)drawArt { + //// Color Declarations + UIColor* color2 = [UIColor colorWithRed: 0.914 green: 0.555 blue: 0.193 alpha: 1]; + UIColor* color1 = [UIColor colorWithRed: 0.033 green: 0.277 blue: 0.542 alpha: 1]; + + //// Page-1 + { + //// Visa + { + //// Group 3 + { + //// Bezier Drawing + UIBezierPath* bezierPath = [UIBezierPath bezierPath]; + [bezierPath moveToPoint: CGPointMake(37.45, 38.09)]; + [bezierPath addLineToPoint: CGPointMake(32.1, 38.09)]; + [bezierPath addLineToPoint: CGPointMake(35.45, 17)]; + [bezierPath addLineToPoint: CGPointMake(40.8, 17)]; + [bezierPath addLineToPoint: CGPointMake(37.45, 38.09)]; + [bezierPath closePath]; + bezierPath.miterLimit = 4; + + bezierPath.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezierPath fill]; + + + //// Bezier 2 Drawing + UIBezierPath* bezier2Path = [UIBezierPath bezierPath]; + [bezier2Path moveToPoint: CGPointMake(27.58, 17)]; + [bezier2Path addLineToPoint: CGPointMake(22.48, 31.5)]; + [bezier2Path addLineToPoint: CGPointMake(21.88, 28.38)]; + [bezier2Path addLineToPoint: CGPointMake(21.88, 28.38)]; + [bezier2Path addLineToPoint: CGPointMake(20.07, 18.9)]; + [bezier2Path addCurveToPoint: CGPointMake(17.53, 17) controlPoint1: CGPointMake(20.07, 18.9) controlPoint2: CGPointMake(19.86, 17)]; + [bezier2Path addLineToPoint: CGPointMake(9.1, 17)]; + [bezier2Path addLineToPoint: CGPointMake(9, 17.36)]; + [bezier2Path addCurveToPoint: CGPointMake(14.6, 19.77) controlPoint1: CGPointMake(9, 17.36) controlPoint2: CGPointMake(11.58, 17.91)]; + [bezier2Path addLineToPoint: CGPointMake(19.25, 38.09)]; + [bezier2Path addLineToPoint: CGPointMake(24.83, 38.09)]; + [bezier2Path addLineToPoint: CGPointMake(33.34, 17)]; + [bezier2Path addLineToPoint: CGPointMake(27.58, 17)]; + [bezier2Path closePath]; + bezier2Path.miterLimit = 4; + + bezier2Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier2Path fill]; + + + //// Bezier 3 Drawing + UIBezierPath* bezier3Path = [UIBezierPath bezierPath]; + [bezier3Path moveToPoint: CGPointMake(63.99, 30.63)]; + [bezier3Path addLineToPoint: CGPointMake(66.8, 22.74)]; + [bezier3Path addLineToPoint: CGPointMake(68.38, 30.63)]; + [bezier3Path addLineToPoint: CGPointMake(63.99, 30.63)]; + [bezier3Path addLineToPoint: CGPointMake(63.99, 30.63)]; + [bezier3Path addLineToPoint: CGPointMake(63.99, 30.63)]; + [bezier3Path addLineToPoint: CGPointMake(63.99, 30.63)]; + [bezier3Path closePath]; + [bezier3Path moveToPoint: CGPointMake(69.88, 38.09)]; + [bezier3Path addLineToPoint: CGPointMake(74.79, 38.09)]; + [bezier3Path addLineToPoint: CGPointMake(70.51, 17)]; + [bezier3Path addLineToPoint: CGPointMake(66.2, 17)]; + [bezier3Path addCurveToPoint: CGPointMake(63.73, 18.57) controlPoint1: CGPointMake(64.22, 17) controlPoint2: CGPointMake(63.73, 18.57)]; + [bezier3Path addLineToPoint: CGPointMake(55.75, 38.09)]; + [bezier3Path addLineToPoint: CGPointMake(61.33, 38.09)]; + [bezier3Path addLineToPoint: CGPointMake(62.45, 34.96)]; + [bezier3Path addLineToPoint: CGPointMake(69.25, 34.96)]; + [bezier3Path addLineToPoint: CGPointMake(69.88, 38.09)]; + [bezier3Path addLineToPoint: CGPointMake(69.88, 38.09)]; + [bezier3Path closePath]; + bezier3Path.miterLimit = 4; + + bezier3Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier3Path fill]; + + + //// Bezier 4 Drawing + UIBezierPath* bezier4Path = [UIBezierPath bezierPath]; + [bezier4Path moveToPoint: CGPointMake(56.14, 22.45)]; + [bezier4Path addLineToPoint: CGPointMake(56.9, 17.92)]; + [bezier4Path addCurveToPoint: CGPointMake(52.09, 17) controlPoint1: CGPointMake(56.9, 17.92) controlPoint2: CGPointMake(54.55, 17)]; + [bezier4Path addCurveToPoint: CGPointMake(43.12, 23.98) controlPoint1: CGPointMake(49.43, 17) controlPoint2: CGPointMake(43.12, 18.19)]; + [bezier4Path addCurveToPoint: CGPointMake(50.53, 32.36) controlPoint1: CGPointMake(43.12, 29.43) controlPoint2: CGPointMake(50.53, 29.5)]; + [bezier4Path addCurveToPoint: CGPointMake(41.7, 32.9) controlPoint1: CGPointMake(50.53, 35.22) controlPoint2: CGPointMake(43.89, 34.71)]; + [bezier4Path addLineToPoint: CGPointMake(40.9, 37.64)]; + [bezier4Path addCurveToPoint: CGPointMake(46.94, 38.83) controlPoint1: CGPointMake(40.9, 37.64) controlPoint2: CGPointMake(43.29, 38.83)]; + [bezier4Path addCurveToPoint: CGPointMake(56.11, 31.61) controlPoint1: CGPointMake(50.6, 38.83) controlPoint2: CGPointMake(56.11, 36.89)]; + [bezier4Path addCurveToPoint: CGPointMake(48.64, 23.23) controlPoint1: CGPointMake(56.11, 26.13) controlPoint2: CGPointMake(48.64, 25.62)]; + [bezier4Path addCurveToPoint: CGPointMake(56.14, 22.45) controlPoint1: CGPointMake(48.64, 20.85) controlPoint2: CGPointMake(53.85, 21.15)]; + [bezier4Path closePath]; + bezier4Path.miterLimit = 4; + + bezier4Path.usesEvenOddFillRule = YES; + + [color1 setFill]; + [bezier4Path fill]; + + + //// Bezier 5 Drawing + UIBezierPath* bezier5Path = [UIBezierPath bezierPath]; + [bezier5Path moveToPoint: CGPointMake(21.88, 28.38)]; + [bezier5Path addLineToPoint: CGPointMake(20.07, 18.9)]; + [bezier5Path addCurveToPoint: CGPointMake(17.53, 17) controlPoint1: CGPointMake(20.07, 18.9) controlPoint2: CGPointMake(19.86, 17)]; + [bezier5Path addLineToPoint: CGPointMake(9.1, 17)]; + [bezier5Path addLineToPoint: CGPointMake(9, 17.36)]; + [bezier5Path addCurveToPoint: CGPointMake(16.95, 21.45) controlPoint1: CGPointMake(9, 17.36) controlPoint2: CGPointMake(13.06, 18.22)]; + [bezier5Path addCurveToPoint: CGPointMake(21.88, 28.38) controlPoint1: CGPointMake(20.66, 24.53) controlPoint2: CGPointMake(21.88, 28.38)]; + [bezier5Path closePath]; + bezier5Path.miterLimit = 4; + + bezier5Path.usesEvenOddFillRule = YES; + + [color2 setFill]; + [bezier5Path fill]; + } + } + } +} +@end diff --git a/e-shop.xcworkspace/xcuserdata/surendrakumar.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/e-shop.xcworkspace/xcuserdata/surendrakumar.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index eb4b260..ed9a9b4 100644 --- a/e-shop.xcworkspace/xcuserdata/surendrakumar.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/e-shop.xcworkspace/xcuserdata/surendrakumar.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -2,22 +2,4 @@ - - - - - -