text:
#if  !__has_feature(objc_arc)
#error FIRMessagingLib should be compiled with ARC.
#endif

#import "FIRMessaging.h"
#import "FIRMessaging_Private.h"

#import <UIKit/UIKit.h>

#import "FIRMessagingAnalytics.h"
#import "FIRMessagingClient.h"
#import "FIRMessagingConstants.h"
#import "FIRMessagingContextManagerService.h"
#import "FIRMessagingDataMessageManager.h"
#import "FIRMessagingDefines.h"
#import "FIRMessagingLogger.h"
#import "FIRMessagingPubSub.h"
#import "FIRMessagingReceiver.h"
#import "FIRMessagingRemoteNotificationsProxy.h"
#import "FIRMessagingRmqManager.h"
#import "FIRMessagingSyncMessageManager.h"
#import "FIRMessagingUtilities.h"
#import "FIRMessagingVersionUtilities.h"
#import "FIRMessaging_Private.h"

#import <FirebaseAnalyticsInterop/FIRAnalyticsInterop.h>
#import <FirebaseCore/FIRAppInternal.h>
#import <FirebaseCore/FIRComponent.h>
#import <FirebaseCore/FIRComponentContainer.h>
#import <FirebaseCore/FIRComponentRegistrant.h>
#import <FirebaseCore/FIRCoreConfigurable.h>
#import <FirebaseCore/FIRDependency.h>
#import <FirebaseInstanceID/FirebaseInstanceID.h>
#import <GoogleUtilities/GULReachabilityChecker.h>

#import "NSError+FIRMessaging.h"

static NSString *const kFIRMessagingMessageViaAPNSRootKey = @"aps";
static NSString *const kFIRMessagingReachabilityHostname = @"www.google.com";
static NSString *const kFIRMessagingDefaultTokenScope = @"*";
static NSString *const kFIRMessagingFCMTokenFetchAPNSOption = @"apns_token";

#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
const NSNotificationName FIRMessagingSendSuccessNotification =
    @"com.firebase.messaging.notif.send-success";
const NSNotificationName FIRMessagingSendErrorNotification =
    @"com.firebase.messaging.notif.send-error";
const NSNotificationName FIRMessagingMessagesDeletedNotification =
    @"com.firebase.messaging.notif.messages-deleted";
const NSNotificationName FIRMessagingConnectionStateChangedNotification =
    @"com.firebase.messaging.notif.connection-state-changed";
const NSNotificationName FIRMessagingRegistrationTokenRefreshedNotification =
    @"com.firebase.messaging.notif.fcm-token-refreshed";
#else
NSString *const FIRMessagingSendSuccessNotification =
    @"com.firebase.messaging.notif.send-success";
NSString *const FIRMessagingSendErrorNotification =
    @"com.firebase.messaging.notif.send-error";
NSString * const FIRMessagingMessagesDeletedNotification =
    @"com.firebase.messaging.notif.messages-deleted";
NSString * const FIRMessagingConnectionStateChangedNotification =
    @"com.firebase.messaging.notif.connection-state-changed";
NSString * const FIRMessagingRegistrationTokenRefreshedNotification =
    @"com.firebase.messaging.notif.fcm-token-refreshed";
#endif  // defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0

NSString *const kFIRMessagingUserDefaultsKeyAutoInitEnabled =
    @"com.firebase.messaging.auto-init.enabled";  // Auto Init Enabled key stored in NSUserDefaults

NSString *const kFIRMessagingAPNSTokenType = @"APNSTokenType"; // APNS Token type key stored in user info.

NSString *const kFIRMessagingPlistAutoInitEnabled =
    @"FirebaseMessagingAutoInitEnabled";  // Auto Init Enabled key stored in Info.plist

@interface FIRMessagingMessageInfo ()

@property(nonatomic, readwrite, assign) FIRMessagingMessageStatus status;

@end

@implementation FIRMessagingMessageInfo

- (instancetype)init {
  FIRMessagingInvalidateInitializer();
}

- (instancetype)initWithStatus:(FIRMessagingMessageStatus)status {
  self = [super init];
  if (self) {
    _status = status;
  }
  return self;
}

@end

#pragma mark - for iOS 10 compatibility
@implementation FIRMessagingRemoteMessage

- (instancetype)init {
  self = [super init];
  if (self) {
    _appData = [[NSMutableDictionary alloc] init];
  }

  return self;
}

@end

@interface FIRMessaging ()<FIRMessagingClientDelegate, FIRMessagingReceiverDelegate,
                           GULReachabilityDelegate>

// FIRApp properties
@property(nonatomic, readwrite, strong) NSData *apnsTokenData;
@property(nonatomic, readwrite, strong) NSString *defaultFcmToken;

@property(nonatomic, readwrite, strong) FIRInstanceID *instanceID;

@property(nonatomic, readwrite, assign) BOOL isClientSetup;

@property(nonatomic, readwrite, strong) FIRMessagingClient *client;
@property(nonatomic, readwrite, strong) GULReachabilityChecker *reachability;
@property(nonatomic, readwrite, strong) FIRMessagingDataMessageManager *dataMessageManager;
@property(nonatomic, readwrite, strong) FIRMessagingPubSub *pubsub;
@property(nonatomic, readwrite, strong) FIRMessagingRmqManager *rmq2Manager;
@property(nonatomic, readwrite, strong) FIRMessagingReceiver *receiver;
@property(nonatomic, readwrite, strong) FIRMessagingSyncMessageManager *syncMessageManager;
@property(nonatomic, readwrite, strong) NSUserDefaults *messagingUserDefaults;

/// Message ID's logged for analytics. This prevents us from logging the same message twice
/// which can happen if the user inadvertently calls `appDidReceiveMessage` along with us
/// calling it implicitly during swizzling.
@property(nonatomic, readwrite, strong) NSMutableSet *loggedMessageIDs;
@property(nonatomic, readwrite, strong) id<FIRAnalyticsInterop> _Nullable analytics;

@end

// Messaging doesn't provide any functionality to other components,
// so it provides a private, empty protocol that it conforms to and use it for registration.

@protocol FIRMessagingInstanceProvider
@end

@interface FIRMessaging () <FIRMessagingInstanceProvider,
                            FIRCoreConfigurable,
                            FIRComponentRegistrant>
@end

@implementation FIRMessaging

// File static to support InstanceID tests that call [FIRMessaging messaging] after
// [FIRMessaging messagingForTests].
static FIRMessaging *sMessaging;

+ (FIRMessaging *)messaging {
  if (sMessaging != nil) {
    return sMessaging;
  }
  FIRApp *defaultApp = [FIRApp defaultApp];  // Missing configure will be logged here.
  id<FIRMessagingInstanceProvider> messaging =
      FIR_COMPONENT(FIRMessagingInstanceProvider, defaultApp.container);

  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
    [(FIRMessaging *)messaging start];
  });
  sMessaging = (FIRMessaging *)messaging;
  return sMessaging;
}

+ (FIRMessaging *)messagingForTests {
  sMessaging = [[FIRMessaging alloc] initWithAnalytics:nil
                                        withInstanceID:[FIRInstanceID instanceID]
                                      withUserDefaults:[NSUserDefaults standardUserDefaults]];
  [sMessaging start];
  return sMessaging;
}

- (instancetype)initWithAnalytics:(nullable id<FIRAnalyticsInterop>)analytics
                   withInstanceID:(FIRInstanceID *)instanceID
                 withUserDefaults:(NSUserDefaults *)defaults {
  self = [super init];
  if (self != nil) {
    _loggedMessageIDs = [NSMutableSet set];
    _instanceID = instanceID;
    _messagingUserDefaults = defaults;
    _analytics = analytics;
  }
  return self;
}

- (void)dealloc {
  [self.reachability stop];
  [[NSNotificationCenter defaultCenter] removeObserver:self];
  [self teardown];
}

#pragma mark - Config

+ (void)load {
  [FIRApp registerAsConfigurable:self];
  [FIRComponentContainer registerAsComponentRegistrant:self];
}

+ (nonnull NSArray<FIRComponent *> *)componentsToRegister {
  FIRDependency *analyticsDep =
      [FIRDependency dependencyWithProtocol:@protocol(FIRAnalyticsInterop) isRequired:NO];
  FIRComponentCreationBlock creationBlock =
      ^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) {
    // Ensure it's cached so it returns the same instance every time messaging is called.
    *isCacheable = YES;
    id<FIRAnalyticsInterop> analytics = FIR_COMPONENT(FIRAnalyticsInterop, container);
        return [[FIRMessaging alloc] initWithAnalytics:analytics
                                        withInstanceID:[FIRInstanceID instanceID]
                                      withUserDefaults:[NSUserDefaults standardUserDefaults]];
  };
  FIRComponent *messagingProvider =
      [FIRComponent componentWithProtocol:@protocol(FIRMessagingInstanceProvider)
                      instantiationTiming:FIRInstantiationTimingLazy
                             dependencies:@[ analyticsDep ]
                           creationBlock:creationBlock];

  return @[ messagingProvider ];
}

+ (void)configureWithApp:(FIRApp *)app {
  if (!app.isDefaultApp) {
    // Only configure for the default FIRApp.
    FIRMessagingLoggerDebug(kFIRMessagingMessageCodeFIRApp001,
                            @"Firebase Messaging only works with the default app.");
    return;
  }
  [[FIRMessaging messaging] configureMessaging:app];
}

- (void)configureMessaging:(FIRApp *)app {
  // Swizzle remote-notification-related methods (app delegate and UNUserNotificationCenter)
  if ([FIRMessagingRemoteNotificationsProxy canSwizzleMethods]) {
    NSString *docsURLString = @"https://firebase.google.com/docs/cloud-messaging/ios/client"
                              @"#method_swizzling_in_firebase_messaging";
    FIRMessagingLoggerNotice(kFIRMessagingMessageCodeFIRApp000,
                             @"FIRMessaging Remote Notifications proxy enabled, will swizzle "
                             @"remote notification receiver handlers. If you'd prefer to manually "
                             @"integrate Firebase Messaging, add \"%@\" to your Info.plist, "
                             @"and set it to NO. Follow the instructions at:\n%@\nto ensure "
                             @"proper integration.",
                             kFIRMessagingRemoteNotificationsProxyEnabledInfoPlistKey,
                             docsURLString);
    [FIRMessagingRemoteNotificationsProxy swizzleMethods];
  }
}

- (void)start {
  // Print the library version for logging.
  NSString *currentLibraryVersion = FIRMessagingCurrentLibraryVersion();
  FIRMessagingLoggerInfo(kFIRMessagingMessageCodeMessagingPrintLibraryVersion,
                         @"FIRMessaging library version %@",
                         currentLibraryVersion);

  [self setupReceiver];

  NSString *hostname = kFIRMessagingReachabilityHostname;
  self.reachability = [[GULReachabilityChecker alloc] initWithReachabilityDelegate:self
                                                                          withHost:hostname];
  [self.reachability start];

  [self setupApplicationSupportSubDirectory];
  // setup FIRMessaging objects
  [self setupRmqManager];
  [self setupClient];
  [self setupSyncMessageManager];
  [self setupDataMessageManager];
  [self setupTopics];

  self.isClientSetup = YES;
  [self setupNotificationListeners];
}

- (void)setupApplicationSupportSubDirectory {
  NSString *messagingSubDirectory = kFIRMessagingApplicationSupportSubDirectory;
  if (![[self class] hasApplicationSupportSubDirectory:messagingSubDirectory]) {
    [[self class] createApplicationSupportSubDirectory:messagingSubDirectory];
  }
}

- (void)setupNotificationListeners {
  // To prevent multiple notifications remove self as observer for all events.
  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  [center removeObserver:self];

  [center addObserver:self
             selector:@selector(didReceiveDefaultInstanceIDToken:)
                 name:kFIRMessagingFCMTokenNotification
               object:nil];
  [center addObserver:self
             selector:@selector(defaultInstanceIDTokenWasRefreshed:)
                 name:kFIRMessagingRegistrationTokenRefreshNotification
               object:nil];
  [center addObserver:self
             selector:@selector(applicationStateChanged)
                 name:UIApplicationDidBecomeActiveNotification
               object:nil];
  [center addObserver:self
             selector:@selector(applicationStateChanged)
                 name:UIApplicationDidEnterBackgroundNotification
               object:nil];
}

- (void)setupReceiver {
  self.receiver = [[FIRMessagingReceiver alloc] init];
  self.receiver.delegate = self;
}

- (void)setupClient {
  self.client = [[FIRMessagingClient alloc] initWithDelegate:self
                                                reachability:self.reachability
                                                 rmq2Manager:self.rmq2Manager];
}

- (void)setupDataMessageManager {
  self.dataMessageManager =
      [[FIRMessagingDataMessageManager alloc] initWithDelegate:self.receiver
                                                        client:self.client
                                                   rmq2Manager:self.rmq2Manager
                                            syncMessageManager:self.syncMessageManager];

  [self.dataMessageManager refreshDelayedMessages];
  [self.client setDataMessageManager:self.dataMessageManager];
}

- (void)setupRmqManager {
  self.rmq2Manager = [[FIRMessagingRmqManager alloc] initWithDatabaseName:@"rmq2"];
  [self.rmq2Manager loadRmqId];
}

- (void)setupTopics {
  _FIRMessagingDevAssert(self.client, @"Invalid nil client before init pubsub.");
  self.pubsub = [[FIRMessagingPubSub alloc] initWithClient:self.client];
}

- (void)setupSyncMessageManager {
  self.syncMessageManager =
      [[FIRMessagingSyncMessageManager alloc] initWithRmqManager:self.rmq2Manager];

  // Delete the expired messages with a delay. We don't want to block startup with a somewhat
  // expensive db call.
  FIRMessaging_WEAKIFY(self);
  dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC));
  dispatch_after(time, dispatch_get_main_queue(), ^{
    FIRMessaging_STRONGIFY(self);
    [self.syncMessageManager removeExpiredSyncMessages];
  });
}

- (void)teardown {
  _FIRMessagingDevAssert([NSThread isMainThread],
                         @"FIRMessaging should be called from main thread only.");
  [self.client teardown];
  self.pubsub = nil;
  self.syncMessageManager = nil;
  self.rmq2Manager = nil;
  self.dataMessageManager = nil;
  self.client = nil;
  self.isClientSetup = NO;
  FIRMessagingLoggerDebug(kFIRMessagingMessageCodeMessaging001, @"Did successfully teardown");
}

#pragma mark - Messages

- (FIRMessagingMessageInfo *)appDidReceiveMessage:(NSDictionary *)message {
  if (!message.count) {
    return [[FIRMessagingMessageInfo alloc] initWithStatus:FIRMessagingMessageStatusUnknown];
  }

  // For downstream messages that go via MCS we should strip out this key before sending
  // the message to the device.
  BOOL isOldMessage = NO;
  NSString *messageID = message[kFIRMessagingMessageIDKey];
  if ([messageID length]) {
    [self.rmq2Manager saveS2dMessageWithRmqId:messageID];

    BOOL isSyncMessage = [[self class] isAPNSSyncMessage:message];
    if (isSyncMessage) {
      isOldMessage = [self.syncMessageManager didReceiveAPNSSyncMessage:message];
    }
  }
  // Prevent duplicates by keeping a cache of all the logged messages during each session.
  // The duplicates only happen when the 3P app calls `appDidReceiveMessage:` along with
  // us swizzling their implementation to call the same method implicitly.
  if (!isOldMessage && messageID.length) {
    isOldMessage = [self.loggedMessageIDs containsObject:messageID];
    if (!isOldMessage) {
      [self.loggedMessageIDs addObject:messageID];
    }
  }

  if (!isOldMessage) {
    [FIRMessagingAnalytics logMessage:message toAnalytics:_analytics];
    [self handleContextManagerMessage:message];
    [self handleIncomingLinkIfNeededFromMessage:message];
  }
  return [[FIRMessagingMessageInfo alloc] initWithStatus:FIRMessagingMessageStatusNew];
}

- (BOOL)handleContextManagerMessage:(NSDictionary *)message {
  if ([FIRMessagingContextManagerService isContextManagerMessage:message]) {
    return [FIRMessagingContextManagerService handleContextManagerMessage:message];
  }
  return NO;
}

+ (BOOL)isAPNSSyncMessage:(NSDictionary *)message {
  if ([message[kFIRMessagingMessageViaAPNSRootKey] isKindOfClass:[NSDictionary class]]) {
    NSDictionary *aps = message[kFIRMessagingMessageViaAPNSRootKey];
    return [aps[kFIRMessagingMessageAPNSContentAvailableKey] boolValue];
  }
  return NO;
}

- (void)handleIncomingLinkIfNeededFromMessage:(NSDictionary *)message {
  NSURL *url = [self linkURLFromMessage:message];
  if (url == nil) {
    return;
  }
  if (![NSThread isMainThread]) {
    dispatch_async(dispatch_get_main_queue(), ^{
      [self handleIncomingLinkIfNeededFromMessage:message];

    });
    return;
  }
  UIApplication *application = FIRMessagingUIApplication();
  if (!application) {
    return;
  }
  id<UIApplicationDelegate> appDelegate = application.delegate;
  SEL continueUserActivitySelector =
      @selector(application:continueUserActivity:restorationHandler:);
  SEL openURLWithOptionsSelector = @selector(application:openURL:options:);
  SEL openURLWithSourceApplicationSelector =
      @selector(application:openURL:sourceApplication:annotation:);
  SEL handleOpenURLSelector = @selector(application:handleOpenURL:);
  // Due to FIRAAppDelegateProxy swizzling, this selector will most likely get chosen, whether or
  // not the actual application has implemented
  // |application:continueUserActivity:restorationHandler:|. A warning will be displayed to the user
  // if they haven't implemented it.
  if ([NSUserActivity class] != nil &&
      [appDelegate respondsToSelector:continueUserActivitySelector]) {
    NSUserActivity *userActivity =
        [[NSUserActivity alloc] initWithActivityType:NSUserActivityTypeBrowsingWeb];
    userActivity.webpageURL = url;
    [appDelegate application:application
        continueUserActivity:userActivity
          restorationHandler:^(NSArray * _Nullable restorableObjects) {
      // Do nothing, as we don't support the app calling this block
    }];

  } else if ([appDelegate respondsToSelector:openURLWithOptionsSelector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
    [appDelegate application:application openURL:url options:@{}];
#pragma clang diagnostic pop

  // Similarly, |application:openURL:sourceApplication:annotation:| will also always be called, due
  // to the default swizzling done by FIRAAppDelegateProxy in Firebase Analytics
  } else if ([appDelegate respondsToSelector:openURLWithSourceApplicationSelector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    [appDelegate application:application
                     openURL:url
           sourceApplication:FIRMessagingAppIdentifier()
                  annotation:@{}];
  } else if ([appDelegate respondsToSelector:handleOpenURLSelector]) {
    [appDelegate application:application handleOpenURL:url];
#pragma clang diagnostic pop
  }
}

- (NSURL *)linkURLFromMessage:(NSDictionary *)message {
  NSString *urlString = message[kFIRMessagingMessageLinkKey];
  if (urlString == nil || ![urlString isKindOfClass:[NSString class]] || urlString.length == 0) {
    return nil;
  }
  NSURL *url = [NSURL URLWithString:urlString];
  return url;
}

#pragma mark - APNS

- (NSData *)APNSToken {
  return self.apnsTokenData;
}

- (void)setAPNSToken:(NSData *)APNSToken {
  [self setAPNSToken:APNSToken type:FIRMessagingAPNSTokenTypeUnknown];
}

- (void)setAPNSToken:(NSData *)apnsToken type:(FIRMessagingAPNSTokenType)type {
  if ([apnsToken isEqual:self.apnsTokenData]) {
    return;
  }
  self.apnsTokenData = apnsToken;

  // Notify InstanceID that APNS Token has been set.
  NSDictionary *userInfo = @{kFIRMessagingAPNSTokenType : @(type)};
  NSNotification *notification =
      [NSNotification notificationWithName:kFIRMessagingAPNSTokenNotification
                                    object:[apnsToken copy]
                                  userInfo:userInfo];
  [[NSNotificationQueue defaultQueue] enqueueNotification:notification postingStyle:NSPostASAP];
}

#pragma mark - FCM

- (BOOL)isAutoInitEnabled {
  // Check storage
  id isAutoInitEnabledObject =
      [_messagingUserDefaults objectForKey:kFIRMessagingUserDefaultsKeyAutoInitEnabled];
  if (isAutoInitEnabledObject) {
    return [isAutoInitEnabledObject boolValue];
  }

  // Check Info.plist
  isAutoInitEnabledObject =
      [[NSBundle mainBundle] objectForInfoDictionaryKey:kFIRMessagingPlistAutoInitEnabled];
  if (isAutoInitEnabledObject) {
    return [isAutoInitEnabledObject boolValue];
  }

  // If none of above exists, we default to the global switch that comes from FIRApp.
  return [[FIRApp defaultApp] isDataCollectionDefaultEnabled];
}

- (void)setAutoInitEnabled:(BOOL)autoInitEnabled {
  BOOL isFCMAutoInitEnabled = [self isAutoInitEnabled];
  [_messagingUserDefaults setBool:autoInitEnabled
                           forKey:kFIRMessagingUserDefaultsKeyAutoInitEnabled];
  [_messagingUserDefaults synchronize];
  if (!isFCMAutoInitEnabled && autoInitEnabled) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    self.defaultFcmToken = self.instanceID.token;
#pragma clang diagnostic pop
  }
}

- (NSString *)FCMToken {
  NSString *token = self.defaultFcmToken;
  if (!token) {
    // We may not have received it from Instance ID yet (via NSNotification), so extract it directly
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
    token = self.instanceID.token;
#pragma clang diagnostic pop
  }
  return token;
}

- (void)retrieveFCMTokenForSenderID:(nonnull NSString *)senderID
                         completion:(nonnull FIRMessagingFCMTokenFetchCompletion)completion {
  if (!senderID.length) {
    FIRMessagingLoggerError(kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenFetch,
                            @"Sender ID not supplied. It is required for a token fetch, "
                            @"to identify the sender.");
    if (completion) {
      NSString *description = @"Couldn't fetch token because a Sender ID was not supplied. A valid "
                              @"Sender ID is required to fetch an FCM token";
      NSError *error = [NSError fcm_errorWithCode:FIRMessagingErrorInvalidRequest
                                         userInfo:@{NSLocalizedDescriptionKey : description}];
      completion(nil, error);
    }
    return;
  }
  NSDictionary *options = nil;
  if (self.APNSToken) {
    options = @{kFIRMessagingFCMTokenFetchAPNSOption : self.APNSToken};
  } else {
    FIRMessagingLoggerWarn(kFIRMessagingMessageCodeAPNSTokenNotAvailableDuringTokenFetch,
                           @"APNS device token not set before retrieving FCM Token for Sender ID "
                           @"'%@'. Notifications to this FCM Token will not be delivered over APNS."
                           @"Be sure to re-retrieve the FCM token once the APNS device token is "
                           @"set.", senderID);
  }
  [self.instanceID tokenWithAuthorizedEntity:senderID
                                       scope:kFIRMessagingDefaultTokenScope
                                     options:options
                                     handler:completion];
}

- (void)deleteFCMTokenForSenderID:(nonnull NSString *)senderID
                       completion:(nonnull FIRMessagingDeleteFCMTokenCompletion)completion {
  if (!senderID.length) {
    FIRMessagingLoggerError(kFIRMessagingMessageCodeSenderIDNotSuppliedForTokenDelete,
                            @"Sender ID not supplied. It is required to delete an FCM token.");
    if (completion) {
      NSString *description = @"Couldn't delete token because a Sender ID was not supplied. A "
                              @"valid Sender ID is required to delete an FCM token";
      NSError *error = [NSError fcm_errorWithCode:FIRMessagingErrorInvalidRequest
                                         userInfo:@{NSLocalizedDescriptionKey : description}];
      completion(error);
    }
    return;
  }
  [self.instanceID deleteTokenWithAuthorizedEntity:senderID
                                             scope:kFIRMessagingDefaultTokenScope
                                           handler:completion];
}

#pragma mark - FIRMessagingDelegate helper methods
- (void)setDelegate:(id<FIRMessagingDelegate>)delegate {
  _delegate = delegate;
  [self validateDelegateConformsToTokenAvailabilityMethods];
}

// Check if the delegate conforms to |didReceiveRegistrationToken:|
// and display a warning to the developer if not.
// NOTE: Once |didReceiveRegistrationToken:| can be made a required method, this
// check can be removed.
- (void)validateDelegateConformsToTokenAvailabilityMethods {
  if (self.delegate &&
      ![self.delegate respondsToSelector:@selector(messaging:didReceiveRegistrationToken:)]) {
    FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTokenDelegateMethodsNotImplemented,
                           @"The object %@ does not respond to "
                           @"-messaging:didReceiveRegistrationToken:. Please implement "
                           @"-messaging:didReceiveRegistrationToken: to be provided with an FCM "
                           @"token.", self.delegate.description);
  }
}

- (void)notifyDelegateOfFCMTokenAvailability {
  __weak FIRMessaging *weakSelf = self;
  if (![NSThread isMainThread]) {
    dispatch_async(dispatch_get_main_queue(), ^{
      [weakSelf notifyDelegateOfFCMTokenAvailability];
    });
    return;
  }
  if ([self.delegate respondsToSelector:@selector(messaging:didReceiveRegistrationToken:)]) {
    [self.delegate messaging:self didReceiveRegistrationToken:self.defaultFcmToken];
  }
}

- (void)setUseMessagingDelegateForDirectChannel:(BOOL)useMessagingDelegateForDirectChannel {
  self.receiver.useDirectChannel = useMessagingDelegateForDirectChannel;
}

- (BOOL)useMessagingDelegateForDirectChannel {
  return self.receiver.useDirectChannel;
}

#pragma mark - Application State Changes

- (void)applicationStateChanged {
  if (self.shouldEstablishDirectChannel) {
    [self updateAutomaticClientConnection];
  }
}

#pragma mark - Direct Channel

- (void)setShouldEstablishDirectChannel:(BOOL)shouldEstablishDirectChannel {
  if (_shouldEstablishDirectChannel == shouldEstablishDirectChannel) {
    return;
  }
  _shouldEstablishDirectChannel = shouldEstablishDirectChannel;
  [self updateAutomaticClientConnection];
}

- (BOOL)isDirectChannelEstablished {
  return self.client.isConnectionActive;
}

- (BOOL)shouldBeConnectedAutomatically {
  // We require a token from Instance ID
  NSString *token = self.defaultFcmToken;
  // Only on foreground connections
  UIApplication *application = FIRMessagingUIApplication();
  if (!application) {
    return NO;
  }
  UIApplicationState applicationState = application.applicationState;
  BOOL shouldBeConnected = _shouldEstablishDirectChannel &&
                           (token.length > 0) &&
                           applicationState == UIApplicationStateActive;
  return shouldBeConnected;
}

- (void)updateAutomaticClientConnection {
  if (![NSThread isMainThread]) {
    // Call this method from the main thread
    dispatch_async(dispatch_get_main_queue(), ^{
      [self updateAutomaticClientConnection];
    });
    return;
  }
  BOOL shouldBeConnected = [self shouldBeConnectedAutomatically];
  if (shouldBeConnected && !self.client.isConnected) {
    [self.client connectWithHandler:^(NSError *error) {
      if (!error) {
        // It means we connected. Fire connection change notification
        [self notifyOfDirectChannelConnectionChange];
      }
    }];
  } else if (!shouldBeConnected && self.client.isConnected) {
    [self.client disconnect];
    [self notifyOfDirectChannelConnectionChange];
  }
}

- (void)notifyOfDirectChannelConnectionChange {
  NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  [center postNotificationName:FIRMessagingConnectionStateChangedNotification object:self];
}

#pragma mark - Connect

- (void)connectWithCompletion:(FIRMessagingConnectCompletion)handler {
  _FIRMessagingDevAssert([NSThread isMainThread],
                         @"FIRMessaging connect should be called from main thread only.");
  _FIRMessagingDevAssert(self.isClientSetup, @"FIRMessaging client not setup.");
  [self.client connectWithHandler:^(NSError *error) {
    if (handler) {
      handler(error);
    }
    if (!error) {
      // It means we connected. Fire connection change notification
      [self notifyOfDirectChannelConnectionChange];
    }
  }];

}

- (void)disconnect {
  _FIRMessagingDevAssert([NSThread isMainThread],
                         @"FIRMessaging should be called from main thread only.");
  if ([self.client isConnected]) {
    [self.client disconnect];
    [self notifyOfDirectChannelConnectionChange];
  }
}

#pragma mark - Topics

+ (NSString *)normalizeTopic:(NSString *)topic {
  if (!topic.length) {
    return nil;
  }
  if (![FIRMessagingPubSub hasTopicsPrefix:topic]) {
    topic = [FIRMessagingPubSub addPrefixToTopic:topic];
  }
  if ([FIRMessagingPubSub isValidTopicWithPrefix:topic]) {
    return [topic copy];
  }
  return nil;
}

- (void)subscribeToTopic:(NSString *)topic {
  [self subscribeToTopic:topic completion:nil];
}

- (void)subscribeToTopic:(NSString *)topic
              completion:(nullable FIRMessagingTopicOperationCompletion)completion {
  if ([FIRMessagingPubSub hasTopicsPrefix:topic]) {
    FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTopicFormatIsDeprecated,
                           @"Format '%@' is deprecated. Only '%@' should be used in "
                           @"subscribeToTopic.",
                           topic, [FIRMessagingPubSub removePrefixFromTopic:topic]);
  }
  if (!self.defaultFcmToken.length) {
    FIRMessagingLoggerWarn(kFIRMessagingMessageCodeMessaging010,
                           @"The subscription operation is suspended because you don't have a "
                           @"token. The operation will resume once you get an FCM token.");
  }
  NSString *normalizeTopic = [[self class] normalizeTopic:topic];
  if (normalizeTopic.length) {
    [self.pubsub subscribeToTopic:normalizeTopic handler:completion];
    return;
  }
  FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging009,
                          @"Cannot parse topic name %@. Will not subscribe.", topic);
  if (completion) {
    completion([NSError fcm_errorWithCode:FIRMessagingErrorInvalidTopicName userInfo:nil]);
  }
}

- (void)unsubscribeFromTopic:(NSString *)topic {
  [self unsubscribeFromTopic:topic completion:nil];
}

- (void)unsubscribeFromTopic:(NSString *)topic
                  completion:(nullable FIRMessagingTopicOperationCompletion)completion {
  if ([FIRMessagingPubSub hasTopicsPrefix:topic]) {
    FIRMessagingLoggerWarn(kFIRMessagingMessageCodeTopicFormatIsDeprecated,
                           @"Format '%@' is deprecated. Only '%@' should be used in "
                           @"unsubscribeFromTopic.",
                           topic, [FIRMessagingPubSub removePrefixFromTopic:topic]);
  }
  if (!self.defaultFcmToken.length) {
    FIRMessagingLoggerWarn(kFIRMessagingMessageCodeMessaging012,
                           @"The unsubscription operation is suspended because you don't have a "
                           @"token. The operation will resume once you get an FCM token.");
  }
  NSString *normalizeTopic = [[self class] normalizeTopic:topic];
  if (normalizeTopic.length) {
    [self.pubsub unsubscribeFromTopic:normalizeTopic handler:completion];
    return;
  }
  FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging011,
                          @"Cannot parse topic name %@. Will not unsubscribe.", topic);
  if (completion) {
    completion([NSError fcm_errorWithCode:FIRMessagingErrorInvalidTopicName userInfo:nil]);
  }
}

#pragma mark - Send

- (void)sendMessage:(NSDictionary *)message
                 to:(NSString *)to
      withMessageID:(NSString *)messageID
         timeToLive:(int64_t)ttl {
  _FIRMessagingDevAssert([to length] != 0, @"Invalid receiver id for FIRMessaging-message");

  NSMutableDictionary *fcmMessage = [[self class] createFIRMessagingMessageWithMessage:message
                                                                           to:to
                                                                       withID:messageID
                                                                   timeToLive:ttl
                                                                        delay:0];
  FIRMessagingLoggerInfo(kFIRMessagingMessageCodeMessaging013, @"Sending message: %@ with id: %@",
                         message, messageID);
  [self.dataMessageManager sendDataMessageStanza:fcmMessage];
}

+ (NSMutableDictionary *)createFIRMessagingMessageWithMessage:(NSDictionary *)message
                                                  to:(NSString *)to
                                              withID:(NSString *)msgID
                                          timeToLive:(int64_t)ttl
                                               delay:(int)delay {
  NSMutableDictionary *fcmMessage = [NSMutableDictionary dictionary];
  fcmMessage[kFIRMessagingSendTo] = [to copy];
  fcmMessage[kFIRMessagingSendMessageID] = msgID ? [msgID copy] : @"";
  fcmMessage[kFIRMessagingSendTTL] = @(ttl);
  fcmMessage[kFIRMessagingSendDelay] = @(delay);
  fcmMessage[KFIRMessagingSendMessageAppData] =
      [NSMutableDictionary dictionaryWithDictionary:message];
  return fcmMessage;
}

#pragma mark - IID dependencies

+ (NSString *)FIRMessagingSDKVersion {
  return FIRMessagingCurrentLibraryVersion();
}

+ (NSString *)FIRMessagingSDKCurrentLocale {
  return [self currentLocale];
}

#pragma mark - FIRMessagingReceiverDelegate

- (void)receiver:(FIRMessagingReceiver *)receiver
      receivedRemoteMessage:(FIRMessagingRemoteMessage *)remoteMessage {
  if ([self.delegate respondsToSelector:@selector(messaging:didReceiveMessage:)]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
    [self.delegate messaging:self didReceiveMessage:remoteMessage];
#pragma pop
  } else {
    // Delegate methods weren't implemented, so messages are being dropped, log a warning
    FIRMessagingLoggerWarn(kFIRMessagingMessageCodeRemoteMessageDelegateMethodNotImplemented,
                           @"FIRMessaging received data-message, but FIRMessagingDelegate's"
                           @"-messaging:didReceiveMessage: not implemented");
  }
}

#pragma mark - GULReachabilityDelegate

- (void)reachability:(GULReachabilityChecker *)reachability
       statusChanged:(GULReachabilityStatus)status {
  [self onNetworkStatusChanged];
}

#pragma mark - Network

- (void)onNetworkStatusChanged {
  if (![self.client isConnected] && [self isNetworkAvailable]) {
    if (self.client.shouldStayConnected) {
      FIRMessagingLoggerDebug(kFIRMessagingMessageCodeMessaging014,
                              @"Attempting to establish direct channel.");
      [self.client retryConnectionImmediately:YES];
    }
    [self.pubsub scheduleSync:YES];
  }
}

- (BOOL)isNetworkAvailable {
  GULReachabilityStatus status = self.reachability.reachabilityStatus;
  return (status == kGULReachabilityViaCellular || status == kGULReachabilityViaWifi);
}

- (FIRMessagingNetworkStatus)networkType {
  GULReachabilityStatus status = self.reachability.reachabilityStatus;
  if (![self isNetworkAvailable]) {
    return kFIRMessagingReachabilityNotReachable;
  } else if (status == kGULReachabilityViaCellular) {
    return kFIRMessagingReachabilityReachableViaWWAN;
  } else {
    return kFIRMessagingReachabilityReachableViaWiFi;
  }
}

#pragma mark - Notifications

- (void)didReceiveDefaultInstanceIDToken:(NSNotification *)notification {
  if (notification.object && ![notification.object isKindOfClass:[NSString class]]) {
    FIRMessagingLoggerDebug(kFIRMessagingMessageCodeMessaging015,
                            @"Invalid default FCM token type %@",
                            NSStringFromClass([notification.object class]));
    return;
  }
  NSString *oldToken = self.defaultFcmToken;
  self.defaultFcmToken = [(NSString *)notification.object copy];
  if (self.defaultFcmToken && ![self.defaultFcmToken isEqualToString:oldToken]) {
    [self notifyDelegateOfFCMTokenAvailability];
  }
  [self.pubsub scheduleSync:YES];
  if (self.shouldEstablishDirectChannel) {
    [self updateAutomaticClientConnection];
  }
}

- (void)defaultInstanceIDTokenWasRefreshed:(NSNotification *)notification {
  // Retrieve the Instance ID default token, and if it is non-nil, post it
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
  NSString *token = self.instanceID.token;
#pragma clang diagnostic pop
  // Sometimes Instance ID doesn't yet have a token, so wait until the default
  // token is fetched, and then notify. This ensures that this token should not
  // be nil when the developer accesses it.
  if (token != nil) {
    NSString *oldToken = self.defaultFcmToken;
    self.defaultFcmToken = [token copy];
    if (self.defaultFcmToken && ![self.defaultFcmToken isEqualToString:oldToken]) {
      [self notifyDelegateOfFCMTokenAvailability];
    }
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    [center postNotificationName:FIRMessagingRegistrationTokenRefreshedNotification object:nil];
  }
}

#pragma mark - Application Support Directory

+ (BOOL)hasApplicationSupportSubDirectory:(NSString *)subDirectoryName {
  NSString *subDirectoryPath = [self pathForApplicationSupportSubDirectory:subDirectoryName];
  BOOL isDirectory;
  if (![[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath
                                            isDirectory:&isDirectory]) {
    return NO;
  } else if (!isDirectory) {
    return NO;
  }
  return YES;
}

+ (NSString *)pathForApplicationSupportSubDirectory:(NSString *)subDirectoryName {
  NSArray *directoryPaths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory,
                                                                NSUserDomainMask, YES);
  NSString *applicationSupportDirPath = directoryPaths.lastObject;
  NSArray *components = @[applicationSupportDirPath, subDirectoryName];
  return [NSString pathWithComponents:components];
}

+ (BOOL)createApplicationSupportSubDirectory:(NSString *)subDirectoryName {
  NSString *subDirectoryPath = [self pathForApplicationSupportSubDirectory:subDirectoryName];
  BOOL hasSubDirectory;

  if (![[NSFileManager defaultManager] fileExistsAtPath:subDirectoryPath
                                            isDirectory:&hasSubDirectory]) {
    NSError *error;
    [[NSFileManager defaultManager] createDirectoryAtPath:subDirectoryPath
                              withIntermediateDirectories:YES
                                               attributes:nil
                                                    error:&error];
    if (error) {
      FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging017,
                              @"Cannot create directory %@, error: %@", subDirectoryPath, error);
      return NO;
    }
  } else {
    if (!hasSubDirectory) {
      FIRMessagingLoggerError(kFIRMessagingMessageCodeMessaging018,
                              @"Found file instead of directory at %@", subDirectoryPath);
      return NO;
    }
  }
  return YES;
}

#pragma mark - Locales

+ (NSString *)currentLocale {
  NSArray *locales = [self firebaseLocales];
  NSArray *preferredLocalizations =
    [NSBundle preferredLocalizationsFromArray:locales
                               forPreferences:[NSLocale preferredLanguages]];
  NSString *legalDocsLanguage = [preferredLocalizations firstObject];
  // Use en as the default language
  return legalDocsLanguage ? legalDocsLanguage : @"en";
}

+ (NSArray *)firebaseLocales {
  NSMutableArray *locales = [NSMutableArray array];
  NSDictionary *localesMap = [self firebaselocalesMap];
  for (NSString *key in localesMap) {
    [locales addObjectsFromArray:localesMap[key]];
  }
  return locales;
}

+ (NSDictionary *)firebaselocalesMap {
  return @{
    // Albanian
    @"sq" : @[ @"sq_AL" ],
    // Belarusian
    @"be" : @[ @"be_BY" ],
    // Bulgarian
    @"bg" : @[ @"bg_BG" ],
    // Catalan
    @"ca" : @[ @"ca", @"ca_ES" ],
    // Croatian
    @"hr" : @[ @"hr", @"hr_HR" ],
    // Czech
    @"cs" : @[ @"cs", @"cs_CZ" ],
    // Danish
    @"da" : @[ @"da", @"da_DK" ],
    // Estonian
    @"et" : @[ @"et_EE" ],
    // Finnish
    @"fi" : @[ @"fi", @"fi_FI" ],
    // Hebrew
    @"he" : @[ @"he", @"iw_IL" ],
    // Hindi
    @"hi" : @[ @"hi_IN" ],
    // Hungarian
    @"hu" : @[ @"hu", @"hu_HU" ],
    // Icelandic
    @"is" : @[ @"is_IS" ],
    // Indonesian
    @"id" : @[ @"id", @"in_ID", @"id_ID" ],
    // Irish
    @"ga" : @[ @"ga_IE" ],
    // Korean
    @"ko" : @[ @"ko", @"ko_KR", @"ko-KR" ],
    // Latvian
    @"lv" : @[ @"lv_LV" ],
    // Lithuanian
    @"lt" : @[ @"lt_LT" ],
    // Macedonian
    @"mk" : @[ @"mk_MK" ],
    // Malay
    @"ms" : @[ @"ms_MY" ],
    // Maltese
    @"ms" : @[ @"mt_MT" ],
    // Polish
    @"pl" : @[ @"pl", @"pl_PL", @"pl-PL" ],
    // Romanian
    @"ro" : @[ @"ro", @"ro_RO" ],
    // Russian
    @"ru" : @[ @"ru_RU", @"ru", @"ru_BY", @"ru_KZ", @"ru-RU" ],
    // Slovak
    @"sk" : @[ @"sk", @"sk_SK" ],
    // Slovenian
    @"sl" : @[ @"sl_SI" ],
    // Swedish
    @"sv" : @[ @"sv", @"sv_SE", @"sv-SE" ],
    // Turkish
    @"tr" : @[ @"tr", @"tr-TR", @"tr_TR" ],
    // Ukrainian
    @"uk" : @[ @"uk", @"uk_UA" ],
    // Vietnamese
    @"vi" : @[ @"vi", @"vi_VN" ],
    // The following are groups of locales or locales that sub-divide a
    // language).
    // Arabic
    @"ar" : @[
      @"ar",
      @"ar_DZ",
      @"ar_BH",
      @"ar_EG",
      @"ar_IQ",
      @"ar_JO",
      @"ar_KW",
      @"ar_LB",
      @"ar_LY",
      @"ar_MA",
      @"ar_OM",
      @"ar_QA",
      @"ar_SA",
      @"ar_SD",
      @"ar_SY",
      @"ar_TN",
      @"ar_AE",
      @"ar_YE",
      @"ar_GB",
      @"ar-IQ",
      @"ar_US"
    ],
    // Simplified Chinese
    @"zh_Hans" : @[ @"zh_CN", @"zh_SG", @"zh-Hans" ],
    // Traditional Chinese
    @"zh_Hant" : @[ @"zh_HK", @"zh_TW", @"zh-Hant", @"zh-HK", @"zh-TW" ],
    // Dutch
    @"nl" : @[ @"nl", @"nl_BE", @"nl_NL", @"nl-NL" ],
    // English
    @"en" : @[
      @"en",
      @"en_AU",
      @"en_CA",
      @"en_IN",
      @"en_IE",
      @"en_MT",
      @"en_NZ",
      @"en_PH",
      @"en_SG",
      @"en_ZA",
      @"en_GB",
      @"en_US",
      @"en_AE",
      @"en-AE",
      @"en_AS",
      @"en-AU",
      @"en_BD",
      @"en-CA",
      @"en_EG",
      @"en_ES",
      @"en_GB",
      @"en-GB",
      @"en_HK",
      @"en_ID",
      @"en-IN",
      @"en_NG",
      @"en-PH",
      @"en_PK",
      @"en-SG",
      @"en-US"
    ],
    // French

    @"fr" : @[
      @"fr",
      @"fr_BE",
      @"fr_CA",
      @"fr_FR",
      @"fr_LU",
      @"fr_CH",
      @"fr-CA",
      @"fr-FR",
      @"fr_MA"
    ],
    // German
    @"de" : @[ @"de", @"de_AT", @"de_DE", @"de_LU", @"de_CH", @"de-DE" ],
    // Greek
    @"el" : @[ @"el", @"el_CY", @"el_GR" ],
    // Italian
    @"it" : @[ @"it", @"it_IT", @"it_CH", @"it-IT" ],
    // Japanese
    @"ja" : @[ @"ja", @"ja_JP", @"ja_JP_JP", @"ja-JP" ],
    // Norwegian
    @"no" : @[ @"nb", @"no_NO", @"no_NO_NY", @"nb_NO" ],
    // Brazilian Portuguese
    @"pt_BR" : @[ @"pt_BR", @"pt-BR" ],
    // European Portuguese
    @"pt_PT" : @[ @"pt", @"pt_PT", @"pt-PT" ],
    // Serbian
    @"sr" : @[
      @"sr_BA",
      @"sr_ME",
      @"sr_RS",
      @"sr_Latn_BA",
      @"sr_Latn_ME",
      @"sr_Latn_RS"
    ],
    // European Spanish
    @"es_ES" : @[ @"es", @"es_ES", @"es-ES" ],
    // Mexican Spanish
    @"es_MX" : @[ @"es-MX", @"es_MX", @"es_US", @"es-US" ],
    // Latin American Spanish
    @"es_419" : @[
      @"es_AR",
      @"es_BO",
      @"es_CL",
      @"es_CO",
      @"es_CR",
      @"es_DO",
      @"es_EC",
      @"es_SV",
      @"es_GT",
      @"es_HN",
      @"es_NI",
      @"es_PA",
      @"es_PY",
      @"es_PE",
      @"es_PR",
      @"es_UY",
      @"es_VE",
      @"es-AR",
      @"es-CL",
      @"es-CO"
    ],
    // Thai
    @"th" : @[ @"th", @"th_TH", @"th_TH_TH" ],
  };
}

@end


text:
import os
import random
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from django.conf import settings as base_set
from django.db.models import Q
from django.utils import timezone
from buysell.models import *
from buysell.helper import url_coder, image_process, paginator
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from PIL import Image
from datetime import datetime, timedelta
from django.db.models import Count, Max
from parser import missy_parser
from django.contrib import messages
from urllib.request import urlopen
from io import BytesIO
from pyzipcode import Pyzipcode as pz

def index(request):
    if request.user.is_authenticated():
        zipcode = request.user.customer.zipcode.number
        area = Zipcode.objects.get(number=zipcode).city.state.area.slug
        states = Area.objects.get(slug=area).states.all()
        cities = City.objects.filter(state__in=states)
    else:
        cities = City.objects.all()

    one_day = datetime.now() - timedelta(hours=24)
    items_new = Item.objects.filter(city__in=cities, is_expired=False, is_removed=False).order_by('-pub_date')[:12]
    items_rand = Item.objects.filter(city__in=cities, pub_date__lte=one_day).order_by('?')[:6]
    items_saved = []
    if request.user.is_authenticated():
        faves = Favorite.objects.filter(user=request.user).values('item').order_by('-pk')[:6]
        for fave in faves:
            fave_item = Item.objects.get(pk=fave['item'])
            items_saved.append(fave_item)

    return render(request, 'index.html', {'items_new': items_new, 'items_rand': items_rand, 'items_saved': items_saved})

def join(request):
    if request.user.is_authenticated():
        return redirect('/')
    else:
        if request.method == 'GET':
            next = request.GET.get('next')
        return render(request, 'join.html', {'next': next})

def sign_up(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        email = request.POST.get('email')
        password = request.POST.get('password')
        zipcode = request.POST.get('zipcode')

        zip_object = pz.get(zipcode, "US")
        city = zip_object['city']
        state = zip_object['state']

        if User.objects.filter(username=username).exists():
            messages.error(request, 'Username is taken')
            return render(request, 'join.html')

        if User.objects.filter(email=email).exists():
            messages.error(request, 'Email in use')
            return render(request, 'join.html')

        if not State.objects.filter(name=state).exists():
            messages.error(request, 'This area is not supported yet. Here is a list: click here')
            return render(request, 'join.html')

        if Zipcode.objects.filter(number=zipcode).exists():
            zipcode = Zipcode.objects.get(number=zipcode)
        else:
            if City.objects.filter(name=city).exists():
                city = City.objects.get(name=city)
            else:
                state = State.objects.get(name=state)
                city = City(name=city, state=state, slug='yes')
                city.save()
                zipcode = Zipcode(number=zipcode, city=city)
                zipcode.save()

        user = User.objects.create_user(username, email, password)
        add_user = Customer(user=user, zipcode=zipcode)
        add_user.save()
        messages.success(request, 'Account created! Please sign in!')
        return render(request, 'join.html')
    else:
        return redirect('/')

def log_in(request):
    next = request.GET.get('next')

    if request.method == 'POST':
        email = request.POST.get('email')
        password = request.POST.get('password')

        username = User.objects.get(email=email).username
        user = authenticate(username=username, password=password)

        if user is not None:
            if user.is_active:
                login(request, user)
                request.session['zip'] = request.user.customer.zipcode.number
                if not next:
                    return redirect('/')
                else:
                    return redirect(next)
            else:
                return HttpResponse('activate your account')
        else:
            messages.error(request, 'Wrong username/password')
            return redirect('/join')
    else:
        # not a POST method
        return redirect('/')

@login_required
def log_out(request):
    logout(request)
    return redirect('/')

@login_required
def settings(request):
    if request.method == 'POST':
        if request.POST.get('profile'):
            email = request.POST.get('email')
            number = request.POST.get('zipcode')

            try:
                zipcode = Zipcode.objects.get(number=number)
            except Zipcode.DoesNotExist:
                return HttpResponse('Your area is not supported')
            else:
                user = User.objects.get(username=request.user.username)
                user.email = email
                user.customer.zipcode = zipcode

                user.save()
                user.customer.save()

                messages.success(request, 'Successfully updated your profile!')
                return render(request, 'settings.html')
        elif request.POST.get('password'):
            pass_cur = request.POST.get('pass_cur')
            pass_new = request.POST.get('pass_new')
            pass_conf = request.POST.get('pass_conf')

            if pass_new == pass_conf:
                auth = authenticate(username=request.user.username, password=pass_cur)
                if auth is not None:
                    user = User.objects.get(username=request.user.username)
                    user.set_password(pass_new)
                    user.save()
                    return redirect('/join')
                else:
                    messages.error(request, 'Wrong password!')
                    return render(request, 'settings.html')
            else:
                messages.error(request, 'Passwords do not match!')
                return render(request, 'settings.html')
        else:
            return redirect('/')
    else:
        return render(request, 'settings.html')

@login_required
def post_create(request):
    categories = Category.objects.order_by('kor_name')
    zipcode = request.user.customer.zipcode.number
    area = Zipcode.objects.get(number=zipcode).city.state.area.slug
    states = Area.objects.get(slug=area).states.all()
    cities = City.objects.filter(state__in=states).order_by('name')
    return render(request, 'post_create.html', {'categories': categories, 'cities': cities})

@login_required
def post_edit(request, url_code):
    if Item.objects.get(url_code=url_code).user == request.user:
        categories = Category.objects.order_by('kor_name')
        zipcode = request.user.customer.zipcode.number
        area = Zipcode.objects.get(number=zipcode).city.state.area.slug
        states = Area.objects.get(slug=area).states.all()
        cities = City.objects.filter(state__in=states).order_by('name')
        item = Item.objects.get(url_code=url_code)
        repost = False
        return render(request, 'post_create.html', {'categories': categories, 'cities': cities, 'item': item, 'repost': repost})
    else:
        return redirect('/')

@login_required
def post_repost(request, url_code):
    try:
        Item.objects.get(url_code=url_code, is_removed=True).user == request.user
    except Item.DoesNotExist:
        return redirect('/')
    else:
        categories = Category.objects.order_by('kor_name')
        zipcode = request.user.customer.zipcode.number
        area = Zipcode.objects.get(number=zipcode).city.state.area.slug
        states = Area.objects.get(slug=area).states.all()
        cities = City.objects.filter(state__in=states).order_by('name')
        item = Item.objects.get(url_code=url_code)
        repost = True
        return render(request, 'post_create.html', {'categories': categories, 'cities': cities, 'item': item, 'repost': repost})

@login_required
def post_remove(request):
    if request.method == 'POST':
        item_code = request.POST.get('item_code')
        item = Item.objects.get(url_code=item_code)
        item.is_removed=True
        item.save()

        return redirect('/store/manage')

@login_required
def post_process(request):
    if request.method == 'POST':

        if request.POST.get('edit'):
            title = request.POST.get('title')
            details = request.POST.get('details')
            url_code = request.POST.get('item_code')
            category = request.POST.get('category')
            category = Category.objects.get(eng_name=category)
            city = request.POST.get('city')
            city = City.objects.get(slug=city)

            item = Item.objects.get(url_code=url_code)
            item.title = title
            item.details = details
            item.category = category
            item.city = city
            if request.POST.get('repost'):
                exp_date = item.pub_date + timedelta(days=item.category.days_til_expire)
                if timezone.now() >= exp_date:
                    #price = request.POST.get('price')
                    #item.price = price
                    item.pub_date = timezone.now()
                item.is_removed = False

            item.save()

            messages.success(request, 'You have successfully edited the item')
            return redirect('/')

        elif request.POST.get('create'):
            title = request.POST.get('title')
            details = request.POST.get('details')
            price = request.POST.get('price')
            url_code = url_coder()
            user = request.user
            category = request.POST.get('category')
            category = Category.objects.get(eng_name=category)
            city = request.POST.get('city')
            city = City.objects.get(slug=city)
            pub_date = timezone.now()

            item = Item(title=title, details=details, price=price, url_code=url_code, user=user, category=category, city=city, pub_date=pub_date)
            item.save()

            if 'image' in request.FILES:
                images = request.FILES.getlist('image')
                number  = len(images)

                # image count limit is 8
                if number <= 8:
                    for image in images:
                        img_filename = image.name
                        img_type = image.content_type
                        img_size = len(image)

                        # image types are jpg, png, gif
                        if img_type == 'image/jpeg' or img_type == 'image/png' or img_type == 'image/gif':
                            # image size limited to 5MB
                            if img_size <= 50000000:
                                img_name = url_coder(size=11)
                                img_ext = os.path.splitext(img_filename)[1].lower()
                                img_filename = img_name + img_ext
                                img_path = os.path.join(img_filename)
                                default_storage.save(img_path, ContentFile(image.read()))

                                img_db = ItemImage(name = img_filename, location = img_filename, item=item)
                                img_db.save()

                                thumb = Image.open(image)
                                W = thumb.size[0] / 2
                                H = thumb.size[1] / 2

                                if W > H:
                                    thumb = thumb.crop((W-H, H-H, W+H, H+H))
                                    thumb = thumb.resize((350,350))
                                elif W < H:
                                    thumb = thumb.crop((W-W, H-W, W+W, H+W))
                                    thumb = thumb.resize((350,350))

                                thumb_path = 'thumb_' + img_filename
                                f_thumb = default_storage.open(thumb_path, 'w')
                                thumb.save(f_thumb, 'png')
                                f_thumb.close()

                            else:
                                messages.error(request, 'The image is too big')
                                return render(request, 'post_create.html')
                        else:
                            messages.error(request, 'Appropriate filetypes are jpg, png, and gif')
                            return render(request, 'post_create.html')

                    return redirect('/post/' + url_code)
                else:
                    messages.error(request, 'You may only upload up to 8 images')
                    return render(request, 'post_create.html')
            else:
                    messages.error(request, 'You need to add at least one image')
                    return render(request, 'post_create.html')
        else:
            # not a POST method
            return redirect('/')

def post(request, url_code):
    item = Item.objects.get(url_code=url_code)
    if not item.is_removed:
        images = ItemImage.objects.filter(item=item)
        user = request.user
        more = Item.objects.filter(user=item.user).all().count()
        if more > 6:
            more_items = Item.objects.filter(user=item.user).exclude(url_code=url_code).order_by('?')[:6]
        else:
            more_items = None

        if request.user.is_authenticated():
            try:
                find = PostView.objects.get(item=item, user=user)
            except PostView.DoesNotExist:
                view = PostView(item=item, user=user)
                view.save()
            else:
                view = PostView(item=item, user=user)
                view.save()
                find.delete()
        try:
            fave = Favorite.objects.get(item=item)
        except Favorite.DoesNotExist:
            favorited = False
        else:
            favorited = True

        return render(request, 'post.html', {'item': item, 'images': images, 'more_items': more_items, 'favorited': favorited})
    else:
        messages.error(request, 'This item has been removed')
        return redirect('/')

def list(request, category=None, page=1):
    if request.user.is_authenticated():
        zipcode = request.user.customer.zipcode.number
        area = Zipcode.objects.get(number=zipcode).city.state.area.slug
        states = Area.objects.get(slug=area).states.all()
        cities = City.objects.filter(state__in=states)
    else:
        cities = City.objects.all()

    cat = 'new'
    if not category:
        return redirect('/list/new')
    elif category == 'new':
        item_list = Item.objects.filter(city__in=cities, is_expired=False, is_removed=False).order_by('-pub_date').exclude(is_removed=True)
        img_title = 'new'
    elif category == 'free':
        item_list = Item.objects.filter(city__in=cities, price='0', is_expired=False, is_removed=False).order_by('-pub_date').exclude(is_removed=True)
        img_title = 'free'
    else:
        try:
            category = Category.objects.get(slug=category)
            cat = category.slug
            item_list = Item.objects.filter(category=category, city__in=cities, is_expired=False, is_removed=False).order_by('-pub_date').exclude(is_removed=True)
            img_title = category.slug
        except Category.DoesNotExist:
            return redirect('/')

    items = paginator(item_list, page)
    if not items:
        return redirect('/')
    else:
        return render(request, 'list.html', {'items': items, 'title': category, 'view': 'list', 'img_title': img_title})

@login_required
def change_zip(request):
    if request.method == 'POST':
        zipcode = request.POST.get('zipcode')
        try:
            zipcode = Zipcode.objects.get(number=zipcode)
        except:
            messages.error(request, 'That area is not yet supported')
            return redirect('/')
        else:
            if request.user.is_authenticated():
                user = User.objects.get(username=request.user.username)
                change = Customer.objects.get(user=user)
                change.zipcode = zipcode
                change.save()
                messages.success(request, 'You successfully changed your zipcode')
                return redirect('/')
            else:
                return redirect('/')
    else:
        return redirect('/')

def search(request, query='', page=1):
    items = ''
    if request.method == 'POST':
        query = request.POST.get('query')
        return redirect('/search/' + query)
    else:
        if not query:
            title = 'None'
            return HttpResponse('No results')
        else:
            title = query
            i = Item.objects
            item_list = i.filter(
                    Q(title__icontains=query) |
                    Q(details__icontains=query) |
                    Q(category__eng_name__icontains=query) |
                    Q(category__kor_name__icontains=query) |
                    Q(user__username__icontains=query) |
                    Q(city__name__icontains=query)).order_by('-pub_date')
            item_list = item_list.exclude(is_removed=True)

            items = paginator(item_list, page)
            return render(request, 'list.html', {'items': items, 'search': title, 'view': 'search', 'img_title': 'search'})

@login_required
def message(request):
    if request.method == 'POST':
        content = request.POST.get('message')
        sender = request.user
        sender = User.objects.get(username = sender)
        recipient = request.POST.get('recipient')
        recipient = User.objects.get(username = recipient)
        item_code = request.POST.get('item')
        item = Item.objects.get(url_code = item_code)
        url_code = request.POST.get('url_code')

        m= Message.objects

        if m.filter(item=item, sender=recipient):
            msg_code = url_code
        elif m.filter(item=item, recipient=recipient):
            msg_code = url_code
        else:
            msg_code = url_coder(size=9)

        msg = Message(sender = sender, recipient = recipient, content = content, item = item, url_code=msg_code)
        msg.save()

        if request.POST.get('url_code'):
            return redirect('/inbox/' + msg_code)
        else:
            messages.success(request, 'Message sent!')
            return redirect('/post/' + item_code)
    else:
        return redirect('/')

@login_required
def inbox(request, url_code=None):
    if request.user.is_authenticated:
        user = request.user
        if Message.objects.filter(url_code=url_code):
            msgs = Message.objects.filter(url_code=url_code)
            user = User.objects.get(username=request.user.username)
            if not msgs.exclude(sender=user).exclude(recipient=user):
                try:
                    recipient = Message.objects.filter(url_code=url_code, sender=user).first().recipient
                except:
                    recipient = Message.objects.filter(url_code=url_code, recipient=user).first().sender
                item_pk = msgs.values('item').distinct()[0]['item']
                item = Item.objects.get(pk=item_pk)

                unread = Message.objects.filter(url_code=url_code, recipient=request.user, is_read=False)
                for msg in unread:
                    msg.is_read = True
                    msg.save()
            else:
                return redirect('/')

            return render(request, 'thread.html', {'msgs':msgs, 'recipient':recipient, 'item':item, 'url_code':url_code})
        else:
            if url_code == None:
                msgs = Message.objects.values('url_code').annotate(date=Max('pub_date')).order_by('-date').filter(Q(sender=user)|Q(recipient=user))
                return render(request, 'inbox.html', {'msgs':msgs})
            elif url_code == 'unread':
                msgs = Message.objects.values('url_code').annotate(date=Max('pub_date')).order_by('-date').filter(recipient=user, is_read=False)
                return render(request, 'inbox.html', {'msgs':msgs})
            elif url_code == 'sent':
                msgs = Message.objects.values('url_code').annotate(date=Max('pub_date')).order_by('-date').filter(sender=user)
                return render(request, 'inbox.html', {'msgs':msgs})
            else:
                return redirect('/inbox')
    else:
        return redirect('/')

@login_required
def bot(request):
    if request.user.is_superuser:
        if request.method == 'POST':
            url = request.POST.get('url')
            cat = request.POST.get('cat')
            city = request.POST.get('city')

            url_code = missy_parser(url, cat, city)

            return redirect('/post/' + url_code)
        else:
            categories = Category.objects.order_by('eng_name')
            zipcode = request.user.customer.zipcode.number
            area = Zipcode.objects.get(number=zipcode).city.state.area.slug
            states = Area.objects.get(slug=area).states.all()
            cities = City.objects.filter(state__in=states).order_by('name')
            return render(request, 'bot.html', {'categories': categories, 'cities': cities})
    else:
        return redirect('/')

@login_required
def botlist(request):
    if request.user.is_superuser:
        bots = []
        custs = Customer.objects.filter(is_bot=True)
        for cust in custs:
            bot = User.objects.get(username=cust.user.username)
            bots.append(bot)

        cities = City.objects.all()

        return render(request, 'botlist.html', {'bots': bots, 'cities': cities})
    else:
        return redirect('/')

@login_required
def store_manage(request):
    items = Item.objects.filter(user=request.user).order_by('-pub_date')
    return render(request, 'store_manage.html', {'items':items})

def store(request, seller, page=1):
    try:
        user = User.objects.get(username=seller)
    except User.DoesNotExist:
        return HttpResponse(user)
    else:
        item_list = Item.objects.filter(user=user).all().order_by('-pub_date').exclude(is_removed=True)
        title = user.username + "'s Store"

        items = paginator(item_list, page)
        if not items:
            return redirect('/')
        else:
            return render(request, 'list.html', {'items':items, 'title':title, 'seller':user.username, 'view':'store'})

@login_required
def history(request, page=1):
    if request.user.is_authenticated():
        title = 'history'
        views = PostView.objects.filter(user=request.user).values('item').order_by('-pk')
        item_list = []
        for view in views:
            view_item = Item.objects.get(pk=view['item'])
            item_list.append(view_item)
        items = paginator(item_list, page)
        if not items:
            return redirect('/')
        else:
            return render(request, 'list.html', {'items':items, 'title':title, 'img_title': 'history'})
    else:
        return redirect('/')

@login_required
def favorites(request, page=1):
    if request.user.is_authenticated():
        # process favorites
        if request.method == 'POST':
            item_code = request.POST.get('item_code')
            item = Item.objects.get(url_code=item_code)
            try:
                find = Favorite.objects.get(item=item)
            except Favorite.DoesNotExist:
                fave = Favorite(user=request.user, item=item, fav_date=timezone.now())
                fave.save()
                messages.success(request, 'Favorited ' + item.title)
            else:
                find.delete()
                messages.success(request, 'Unfavorited ' + item.title)

            return redirect('/post/' + item_code)
        # list favorites
        else:
            title = 'favorites'
            faves = Favorite.objects.filter(user=request.user).values('item').order_by('-pk')
            item_list = []
            for fave in faves:
                fave_item = Item.objects.get(pk=fave['item'])
                item_list.append(fave_item)
            items = paginator(item_list, page)
            if not items:
                return redirect('/')
            else:
                return render(request, 'list.html', {'items':items, 'title':title, 'img_title': 'favorites'})
    else:
        return redirect('/')

redpajama_set_name: RedPajamaGithub


text:
@interface ChessClocksViewController : UIViewController {

}

@property (nonatomic, retain) ChessGame *game;

@property (nonatomic, retain) IBOutlet UILabel *playerOneTimeLabel;
@property (nonatomic, retain) IBOutlet UILabel *playerTwoTimeLabel;
@property (nonatomic, retain) IBOutlet UIImageView *playerOneBackgroundImage;
@property (nonatomic, retain) IBOutlet UIImageView *playerTwoBackgroundImage;

- (IBAction) pauseGame:(id) sender;

@end


text:
    <form class="form-signin">

Please login

        <input type="text" class="input-block-level"
               placeholder="Username"
               name="username" id="username"
               ng-model="user.username" autofocus>
        <input type="password" class="input-block-level"
               placeholder="Password"
               name="password" id="password"
                ng-model="user.password">

        <button class="btn btn-large btn-primary" ng-click="login(user)">Sign in</button>
    </form>


text:
#ifndef FILTER_INTEGRAL_HPP
#define FILTER_INTEGRAL_HPP

#include <filter/filter.hpp>

namespace Aversive {

namespace Filter {

  //! \brief Integral Filter
  /*!

  Basically returns the sum of all inputs

 */
  template<typename ValueType>
  class Integral : public Filter<ValueType, Integral<ValueType>> {
  public:
    using InputType  = ValueType;
    using OutputType = ValueType;

  private:
    InputType _sum;

  public:
    //! \brief Default Constructor
    inline Integral(InputType initial)
      : _sum(initial) {
    }

    //! \brief Computes output in function of input
    inline OutputType operator()(InputType value) {
      _sum += value;
      return _sum;
    }

    inline void reset(InputType initial = 0) {
      _sum = initial;
    }
  };

}

}

#endif//FILTER_INTEGRAL_HPP


text:
require 'rubygems/test_case'
require 'rubygems/simple_gem'

class TestGemPackageOld < Gem::TestCase

  def setup
    super

    open 'old_format.gem', 'wb' do |io|
      io.write SIMPLE_GEM
    end

    @package = Gem::Package::Old.new 'old_format.gem'
    @destination = File.join @tempdir, 'extract'

    FileUtils.mkdir_p @destination
  end

  def test_contents
    assert_equal %w[lib/foo.rb lib/test.rb lib/test/wow.rb], @package.contents
  end

  def test_contents_security_policy
    skip 'openssl is missing' unless defined?(OpenSSL::SSL)

    @package.security_policy = Gem::Security::AlmostNoSecurity

    assert_raises Gem::Security::Exception do
      @package.contents
    end
  end

  def test_extract_files
    @package.extract_files @destination

    extracted = File.join @destination, 'lib/foo.rb'
    assert_path_exists extracted

    mask = 0100644 & (~File.umask)

    assert_equal mask, File.stat(extracted).mode unless win_platform?
  end

  def test_extract_files_security_policy
    skip 'openssl is missing' unless defined?(OpenSSL::SSL)

    @package.security_policy = Gem::Security::AlmostNoSecurity

    assert_raises Gem::Security::Exception do
      @package.extract_files @destination
    end
  end

  def test_spec
    assert_equal 'testing', @package.spec.name
  end

  def test_spec_security_policy
    skip 'openssl is missing' unless defined?(OpenSSL::SSL)

    @package.security_policy = Gem::Security::AlmostNoSecurity

    assert_raises Gem::Security::Exception do
      @package.spec
    end
  end

  def test_verify
    skip 'openssl is missing' unless defined?(OpenSSL::SSL)

    assert @package.verify

    @package.security_policy = Gem::Security::NoSecurity

    assert @package.verify

    @package.security_policy = Gem::Security::AlmostNoSecurity

    e = assert_raises Gem::Security::Exception do
      @package.verify
    end

    assert_equal 'old format gems do not contain signatures ' +
                 'and cannot be verified',
                 e.message
  end

end


text:
**OBSOLETE - 今は使ってない**

シンジョーまちなカレッジ
------

* [Facebookページ](https://www.facebook.com/shinjomachinacollege/)
* [Twitter](https://twitter.com/machina_college)
* email: machina.college@gmail.com

GitHub Pageの作業
----

    GitHub側で「shinjo」リポジトリ作成
    $ git init
    $ git add .
    $ git commit -m "Add a Iinit project"
    $ git branch -m master gh-pages
    $ git remote add origin https://github.com/machina-college/shinjo.git
    $ git push -u origin gh-pages

    DNS設定
      shinjo.machina-college.org
      CNAME
      300
      machina-college.github.io

    $ dig shinjo.machina-college.org +nostats +nocomments +nocmd

参考・関連サイト
----

* [様々なファビコンを一括生成。favicon generator](https://ao-system.net/favicongenerator/)


text:
import { class_create } from '@utils/class';
import { obj_extend } from '@utils/obj';
import { Dom } from '@core/dom/exports';
import { reporter_createErrorNode, error_withNode } from '@core/util/reporters';
import {
    customTag_Compo_getHandler,
    customTag_register,
    customTag_registerResolver,
    customTag_Base
} from '@core/custom/exports';
import { parser_parse } from '@core/parser/exports';
import { Define } from '@core/feature/Define';

import { IModule } from './Module';
import { m_Types } from './ModuleTypes';
import { _file_get } from '../loaders';
import { u_resolvePath } from '../utils';
import { m_registerModule } from './utils';
import { i_createImport } from '../Import/exports';
import { Endpoint } from '../class/Endpoint';
import { mask_nodesToArray } from '../utils/mask-module';

export const ModuleMask = (m_Types['mask'] = class_create(IModule, {
    type: 'mask',
    scope: null,
    source: null,
    modules: null,
    exports: null,
    importItems: null,

    load_: _file_get,
    loadModule() {
        if (this.state === 0) {
            return IModule.prototype.loadModule.call(this);
        }
        if (this.state === 2) {
            this.state = 3;
            var self = this;
            self.preprocess_(this.source, function() {
                self.state = 4;
                self.resolve(self);
            });
        }
        return this;
    },
    preprocessError_(error, next) {
        var msg = 'Load error: ' + this.path;
        if (error && error.status) {
            msg += '; Status: ' + error.status;
        }

        this.source = reporter_createErrorNode(msg);
        next.call(this, error);
    },
    preprocess_(mix, next) {
        var ast = typeof mix === 'string' ? parser_parse(mix, this.path) : mix;

        this.source = ast;
        this.importItems = [];
        this.exports = {
            __nodes__: [],
            __handlers__: {}
        };

        var arr = mask_nodesToArray(ast),
            importNodes = [],
            imax = arr.length,
            i = -1,
            x;
        while (++i < imax) {
            x = arr[i];
            switch (x.tagName) {
                case 'import':
                    importNodes.push(x);
                    this.importItems.push(i_createImport(x, null, null, this));
                    break;
                case 'module':
                    var path = u_resolvePath(x.attr.path, null, null, this),
                        type = x.attr.contentType,
                        endpoint = new Endpoint(path, type);
                    m_registerModule(x.nodes, endpoint);
                    break;
                case 'define':
                case 'let':
                    continue;
                default:
                    this.exports.__nodes__.push(x);
                    break;
            }
        }

        _loadImports(this, importNodes, function() {
            next.call(this, null, _createExports(arr, null, this));
        });
    },

    getHandler(name) {
        return _module_getHandler.call(this, this, name);
    },
    queryHandler(selector) {
        if (this.error) {
            return _createHandlerForNodes(this.source, this);
        }

        var nodes = this.exports.__nodes__;
        if (selector !== '*') {
            nodes = _nodesFilter(nodes, selector);
        }
        return nodes != null && nodes.length !== 0
            ? _createHandlerForNodes(nodes, this)
            : null;
    },
    getExport(misc) {
        return this.getHandler(misc) || this.queryHandler(misc);
    }
}));

function _nodesFilter(nodes, tagName) {
    var arr = [],
        imax = nodes.length,
        i = -1,
        x;
    while (++i < imax) {
        x = nodes[i];
        if (x.tagName === tagName) {
            arr.push(x);
        }
    }
    return arr;
}
function _createExports(nodes, model, module) {
    var exports = module.exports,
        items = module.importItems,
        getHandler = _module_getHandlerDelegate(module);

    var i = -1,
        imax = items.length;
    while (++i < imax) {
        var x = items[i];
        if (x.registerScope) {
            x.registerScope(module);
        }
    }

    var i = -1,
        imax = nodes.length;
    while (++i < imax) {
        var node = nodes[i];
        var name = node.tagName;
        if (name === 'define' || name === 'let') {
            var Base = {
                getHandler: _fn_wrap(customTag_Compo_getHandler, getHandler),
                getModule: _module_getModuleDelegate(module),
                location: module.location
            };
            var Ctor = Define.create(node, model, module, Base);
            var Proto = Ctor.prototype;
            if (Proto.scope != null || module.scope != null) {
                Proto.scope = obj_extend(Proto.scope, module.scope);
            }

            var compoName = node.name;
            if (name === 'define') {
                exports[compoName] = Ctor;
                customTag_register(compoName, Ctor);
            }
            if (name === 'let') {
                customTag_registerResolver(compoName);
            }
            exports.__handlers__[compoName] = Ctor;
        }
    }
    exports['*'] = class_create(customTag_Base, {
        getHandler: getHandler,
        location: module.location,
        nodes: exports.__nodes__,
        scope: module.scope
    });

    return exports;
}
function _createHandlerForNodes(nodes, module) {
    return class_create({
        scope: module.scope,
        location: module.location,
        nodes: nodes,
        getHandler: _module_getHandlerDelegate(module)
    });
}

function _loadImports(module, importNodes, done) {
    var items = module.importItems,
        count = items.length,
        imax = count,
        i = -1;
    if (count === 0) {
        return done.call(module);
    }
    process();
    //= private
    function awaiter() {
        if (--count > 0) {
            return;
        }
        done.call(module);
    }
    function process() {
        if (i > -1) {
            // resume from sync
            awaiter();
        }
        while (++i < imax) {
            var node = importNodes[i];
            var resumer = awaiter;
            if ('async' === node.async) {
                resumer = null;
            }
            if ('sync' === node.async) {
                resumer = process;
            }
            _loadImport(module, items[i], node, resumer);
            if ('async' === node.async) {
                awaiter();
            }
            if ('sync' === node.async) {
                return;
            }
        }
    }
}
function _loadImport(module, import_, node, done) {
    import_.loadImport(function(error) {
        if (error) {
            error_withNode(error, node);
        }
        done && done();
    });
}
function _module_getModuleDelegate(module) {
    return function(name) {
        return module;
    };
}
function _module_getHandlerDelegate(module) {
    return function(name) {
        return _module_getHandler.call(this, module, name);
    };
}
function _module_getHandler(module, name) {
    if (module.error != null) {
        return;
    }
    // check public exports
    var exports = module.exports;
    var Ctor = exports[name];
    if (Ctor != null) {
        return Ctor;
    }
    // check private components store
    var handlers = exports.__handlers__;
    if (handlers != null && (Ctor = handlers[name]) != null) {
        return Ctor;
    }

    var arr = module.importItems,
        i = arr.length,
        x,
        type;
    while (--i > -1) {
        x = arr[i];
        type = x.type;
        if (type === 'mask') {
            if ((Ctor = x.getHandler(name)) != null) {
                return Ctor;
            }
        } else {
            if ((Ctor = x.imports && x.imports[name]) != null) {
                return Ctor;
            }
        }
    }
    return null;
}

function _fn_wrap(baseFn, fn) {
    if (baseFn == null) {
        return fn;
    }
    return function() {
        var x = baseFn.apply(this, arguments);
        if (x != null) {
            return x;
        }
        return fn.apply(this, arguments);
    };
}


text:
int literal_state;
int comment_state;
int current_char;
int next_char;

void init_input_buffer(int input[])
{
    for (int i = 0; i < MAX_INPUT_LENGTH; ++i)
    {
        input[i] = '\0';
    }
}

void read_input(int input[])
{
    int current_char = EOF;
    int index = 0;

    while ((current_char = getchar()) != EOF)
    {
        input[index++] = current_char;
    }
}

void print_error(char message[])
{
    printf("[error] %s\n", message);
}

void print_error_if(char message[], bool condition)
{
    if (condition)
    {
        print_error(message);
    }
}

void print_error_ln(int line, int char_number, char message[])
{
    printf("[error @ line %d, character %d] %s\n", line, char_number, message);
}

void print_error_ln_if(int line, int char_number, char message[], bool condition)
{
    if (condition)
    {
        print_error_ln(line, char_number, message);
    }
}

bool in_code()
{
    return literal_state == NOT_IN_LITERAL && comment_state == NOT_IN_COMMENT;
}

bool in_comment()
{
    return comment_state == NOT_IN_COMMENT;
}

bool in_single_line_comment()
{
    return comment_state == IN_SINGLE_LINE_COMMENT;
}

bool in_multi_line_comment()
{
    return comment_state == IN_MULTI_LINE_COMMENT;
}

bool in_string()
{
    return literal_state == IN_STRING;
}

bool in_character()
{
    return literal_state == IN_CHARACTER;
}

bool start_of_single_line_comment()
{
    return current_char == '/' && next_char == '/';
}

bool start_of_multi_line_comment()
{
    return current_char == '/' && next_char == '*';
}

bool end_of_multi_line_comment()
{
    return current_char == '*' && next_char == '/';
}

int main()
{
    int input[MAX_INPUT_LENGTH];
    init_input_buffer(input);
    read_input(input);

    literal_state = NOT_IN_LITERAL;
    comment_state = NOT_IN_COMMENT;
    current_char = '\0';
    next_char = '\0';

    int line_number = 1;
    int char_number = 0;

    int num_parens = 0;
    int num_brackets = 0;
    int num_braces = 0;

    bool string_escaped = false;
    bool char_escaped = false;

    for (int i = 0; input[i] != '\0' && i < MAX_INPUT_LENGTH; ++i)
    {
        current_char = input[i];
        next_char = ((i == MAX_INPUT_LENGTH - 1) ? '\0' : input[i + 1]);

        ++char_number;

        if (current_char == '\n')
        {
            ++line_number;
            char_number = 0;
            continue;
        }

        if (in_code())
        {
            if (start_of_single_line_comment())
            {
                comment_state = IN_SINGLE_LINE_COMMENT;
            }
            else if (start_of_multi_line_comment())
            {
                comment_state = IN_MULTI_LINE_COMMENT;
            }
            else if (current_char == OPEN_PARENTHESIS)
            {
                ++num_parens;
            }
            else if (current_char == CLOSE_PARENTHESIS)
            {
                --num_parens;
                print_error_ln_if(line_number, char_number, "too many closing parentheses", num_parens < 0);
            }
            else if (current_char == OPEN_BRACE)
            {
                ++num_braces;
            }
            else if (current_char == CLOSE_BRACE)
            {
                --num_braces;
                print_error_ln_if(line_number, char_number, "too many closing braces", num_braces < 0);
            }
            else if (current_char == OPEN_BRACKET)
            {
                ++num_brackets;
            }
            else if (current_char == CLOSE_BRACKET)
            {
                --num_brackets;
                print_error_ln_if(line_number, char_number, "too many closing brackets", num_brackets < 0);
            }
            else if (current_char == '\"')
            {
                literal_state = IN_STRING;
            }
            else if (current_char == '\'')
            {
                literal_state = IN_CHARACTER;
            }
        }
        else if (in_single_line_comment())
        {
            if (current_char == '\n')
            {
                comment_state = NOT_IN_COMMENT;
            }
        }
        else if (in_multi_line_comment())
        {
            if (end_of_multi_line_comment())
            {
                comment_state = NOT_IN_COMMENT;
            }
        }
        else if (in_string())
        {
            if (current_char == '\\')
            {
                string_escaped = !string_escaped;
            }
            else if (current_char == '\"' && !string_escaped)
            {
                literal_state = NOT_IN_LITERAL;
            }
        }
        else if (in_character())
        {
            if (current_char == '\\')
            {
                char_escaped = !char_escaped;
            }
            else if (current_char == '\'' && !char_escaped)
            {
                literal_state = NOT_IN_LITERAL;
            }
        }
    }

    print_error_if("parentheses are not balanced", num_parens != 0);
    print_error_if("braces are not balanced", num_braces != 0);
    print_error_if("brackets are not balanced", num_brackets != 0);

    return 0;
}


text:
package main

import (
	"context"
	"time"

	"gopkg.in/kataras/iris.v6"
	"gopkg.in/kataras/iris.v6/adaptors/httprouter"
)

func main() {
	app := iris.New()
	// output startup banner and error logs on os.Stdout
	app.Adapt(iris.DevLogger())
	// set the router, you can choose gorillamux too
	app.Adapt(httprouter.New())

	app.Get("/hi", func(ctx *iris.Context) {
		ctx.HTML(iris.StatusOK, "
hi, I just exist in order to see if the server is closed
")
	})

	app.Adapt(iris.EventPolicy{
		// Interrupt Event means when control+C pressed on terminal.
		Interrupted: func(*iris.Framework) {
			// shut down gracefully, but wait 5 seconds the maximum before closed
			ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
			app.Shutdown(ctx)
		},
	})

	app.Listen(":8080")
}