2
0

Operational emergency generator.

This commit is contained in:
Maarten Billemont 2014-04-13 13:04:18 -04:00
parent b2624c7572
commit 87b01fcaaf
9 changed files with 394 additions and 220 deletions

View File

@ -111,7 +111,7 @@ const long MPAvatarAdd = 10000;
_newUser = YES; _newUser = YES;
} }
else else
self.avatarImageView.image = [UIImage imageNamed:strf( @"avatar-%ld", avatar )]; self.avatarImageView.image = [UIImage imageNamed:strf( @"avatar-%ld", _avatar )];
} }
- (NSString *)name { - (NSString *)name {

View File

@ -20,18 +20,19 @@
@interface MPEmergencyViewController : UIViewController <UITextFieldDelegate> @interface MPEmergencyViewController : UIViewController <UITextFieldDelegate>
@property(weak, nonatomic) IBOutlet UIView *emergencyGeneratorDialog; @property(weak, nonatomic) IBOutlet UIView *dialogView;
@property(weak, nonatomic) IBOutlet UIView *emergencyGeneratorContainer; @property(weak, nonatomic) IBOutlet UIView *containerView;
@property(weak, nonatomic) IBOutlet UITextField *emergencyName; @property(weak, nonatomic) IBOutlet UITextField *userNameField;
@property(weak, nonatomic) IBOutlet UITextField *emergencyMasterPassword; @property(weak, nonatomic) IBOutlet UITextField *masterPasswordField;
@property(weak, nonatomic) IBOutlet UITextField *emergencySite; @property(weak, nonatomic) IBOutlet UITextField *siteField;
@property(weak, nonatomic) IBOutlet UIStepper *emergencyCounterStepper; @property(weak, nonatomic) IBOutlet UIStepper *counterStepper;
@property(weak, nonatomic) IBOutlet UISegmentedControl *emergencyTypeControl; @property(weak, nonatomic) IBOutlet UISegmentedControl *typeControl;
@property(weak, nonatomic) IBOutlet UILabel *emergencyCounter; @property(weak, nonatomic) IBOutlet UILabel *counterLabel;
@property(weak, nonatomic) IBOutlet UIActivityIndicatorView *emergencyActivity; @property(weak, nonatomic) IBOutlet UIActivityIndicatorView *activity;
@property(weak, nonatomic) IBOutlet UIButton *emergencyPassword; @property(weak, nonatomic) IBOutlet UILabel *passwordLabel;
@property(weak, nonatomic) IBOutlet UIView *emergencyContentTipContainer; @property(weak, nonatomic) IBOutlet UIView *tipContainer;
- (IBAction)emergencyCopy:(id)sender; - (IBAction)controlChanged:(UIControl *)control;
- (IBAction)copyPassword:(UITapGestureRecognizer *)recognizer;
@end @end

View File

@ -18,20 +18,36 @@
#import "MPEmergencyViewController.h" #import "MPEmergencyViewController.h"
#import "MPEntities.h" #import "MPEntities.h"
#import "MPAvatarCell.h"
#import "MPiOSAppDelegate.h"
#import "MPAppDelegate_Store.h"
#import "MPAppDelegate_Key.h"
#import "MPEmergencySegue.h"
@implementation MPEmergencyViewController @implementation MPEmergencyViewController {
MPKey *_key;
NSOperationQueue *_emergencyKeyQueue;
NSOperationQueue *_emergencyPasswordQueue;
}
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
[_emergencyKeyQueue = [NSOperationQueue new] setMaxConcurrentOperationCount:1];
[_emergencyPasswordQueue = [NSOperationQueue new] setMaxConcurrentOperationCount:1];
self.view.backgroundColor = [UIColor clearColor]; self.view.backgroundColor = [UIColor clearColor];
self.emergencyGeneratorDialog.layer.cornerRadius = 5; self.dialogView.layer.cornerRadius = 5;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self reset];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self reset];
} }
- (BOOL)canPerformUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender { - (BOOL)canPerformUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender {
@ -48,28 +64,112 @@
#pragma mark - UITextFieldDelegate #pragma mark - UITextFieldDelegate
- (void)textFieldDidEndEditing:(UITextField *)textField {
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField { - (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder]; [textField resignFirstResponder];
return YES; return YES;
} }
// This isn't really in UITextFieldDelegate. We fake it from UITextFieldTextDidChangeNotification.
- (void)textFieldEditingChanged:(UITextField *)textField {
}
#pragma mark - Actions #pragma mark - Actions
- (IBAction)emergencyClose:(id)sender { - (IBAction)controlChanged:(UIControl *)control {
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; if (control == self.userNameField || control == self.masterPasswordField)
[self updateKey];
else
[self updatePassword];
} }
- (IBAction)emergencyCopy:(id)sender { - (IBAction)copyPassword:(UITapGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateEnded) {
NSString *sitePassword = self.passwordLabel.text;
if ([sitePassword length]) {
[UIPasteboard generalPasteboard].string = sitePassword;
[UIView animateWithDuration:0.3f animations:^{
self.tipContainer.alpha = 1;
} completion:^(BOOL finished) {
if (finished)
PearlMainQueueAfter( 3, ^{
self.tipContainer.alpha = 0;
} );
}];
}
}
}
#pragma mark - Private
- (void)updateKey {
NSString *userName = self.userNameField.text;
NSString *masterPassword = self.masterPasswordField.text;
self.passwordLabel.text = nil;
[self.activity startAnimating];
[_emergencyKeyQueue cancelAllOperations];
[_emergencyKeyQueue addOperationWithBlock:^{
if ([masterPassword length] && [userName length])
_key = [MPAlgorithmDefault keyForPassword:masterPassword ofUserNamed:userName];
else
_key = nil;
PearlMainQueue( ^{
[self updatePassword];
} );
}];
}
- (void)updatePassword {
NSString *siteName = self.siteField.text;
MPElementType siteType = [self siteType];
NSUInteger siteCounter = (NSUInteger)self.counterStepper.value;
self.counterLabel.text = strf( @"%d", siteCounter );
self.passwordLabel.text = nil;
[self.activity startAnimating];
[_emergencyPasswordQueue cancelAllOperations];
[_emergencyPasswordQueue addOperationWithBlock:^{
NSString *sitePassword = nil;
if (_key && [siteName length])
sitePassword = [MPAlgorithmDefault generateContentNamed:siteName ofType:siteType withCounter:siteCounter usingKey:_key];
PearlMainQueue( ^{
[self.activity stopAnimating];
self.passwordLabel.text = sitePassword;
} );
}];
}
- (enum MPElementType)siteType {
switch (self.typeControl.selectedSegmentIndex) {
case 0:
return MPElementTypeGeneratedMaximum;
case 1:
return MPElementTypeGeneratedLong;
case 2:
return MPElementTypeGeneratedMedium;
case 3:
return MPElementTypeGeneratedBasic;
case 4:
return MPElementTypeGeneratedShort;
case 5:
return MPElementTypeGeneratedPIN;
default:
Throw(@"Unsupported type index: %ld", (long)self.typeControl.selectedSegmentIndex);
}
}
- (void)reset {
self.userNameField.text = nil;
self.masterPasswordField.text = nil;
self.siteField.text = nil;
self.counterStepper.value = 1;
self.typeControl.selectedSegmentIndex = 1;
[self updateKey];
} }
@end @end

View File

@ -25,6 +25,8 @@
@implementation MPPasswordLargeCell @implementation MPPasswordLargeCell
#pragma mark - Life
+ (instancetype)dequeueCellWithType:(MPElementType)type fromCollectionView:(UICollectionView *)collectionView + (instancetype)dequeueCellWithType:(MPElementType)type fromCollectionView:(UICollectionView *)collectionView
atIndexPath:(NSIndexPath *)indexPath { atIndexPath:(NSIndexPath *)indexPath {
@ -34,7 +36,7 @@
else if (type & MPElementTypeClassStored) else if (type & MPElementTypeClassStored)
reuseIdentifier = NSStringFromClass( [MPPasswordLargeStoredCell class] ); reuseIdentifier = NSStringFromClass( [MPPasswordLargeStoredCell class] );
else else
Throw(@"Unexpected password type: %@", [MPAlgorithmDefault nameOfType:type]); Throw(@"Unexpected password type: %@", [MPAlgorithmDefault nameOfType:type]);
MPPasswordLargeCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath]; MPPasswordLargeCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
cell.type = type; cell.type = type;
@ -42,6 +44,110 @@
return cell; return cell;
} }
- (void)awakeFromNib {
[super awakeFromNib];
[self prepareForReuse];
}
- (void)prepareForReuse {
_contentFieldMode = 0;
self.contentField.text = nil;
[super prepareForReuse];
}
- (void)reloadWithTransientSite:(NSString *)siteName {
[super reloadWithTransientSite:siteName];
self.loginButton.alpha = 0;
self.upgradeButton.alpha = 0;
self.typeLabel.text = [MPAlgorithmDefault nameOfType:self.type];
if (self.type & MPElementTypeClassStored) {
self.contentField.enabled = YES;
self.contentField.placeholder = strl( @"Set custom password" );
}
else if (self.type & MPElementTypeClassGenerated) {
self.contentField.enabled = NO;
self.contentField.placeholder = strl( @"Generating..." );
}
else {
self.contentField.enabled = NO;
self.contentField.placeholder = nil;
}
self.contentField.text = nil;
[self resolveContentOfCellTypeForTransientSite:siteName usingKey:[MPiOSAppDelegate get].key result:^(NSString *string) {
PearlMainQueue( ^{ self.contentField.text = string; } );
}];
}
- (void)reloadWithElement:(MPElementEntity *)mainElement {
[super reloadWithElement:mainElement];
self.loginButton.alpha = 1;
self.typeLabel.text = [mainElement.algorithm nameOfType:self.type];
if (mainElement.requiresExplicitMigration)
self.upgradeButton.alpha = 1;
else
self.upgradeButton.alpha = 0;
switch (self.contentFieldMode) {
case MPContentFieldModePassword: {
if (self.type & MPElementTypeClassStored) {
self.contentField.enabled = YES;
self.contentField.placeholder = strl( @"Set custom password" );
}
else if (self.type & MPElementTypeClassGenerated) {
self.contentField.enabled = NO;
self.contentField.placeholder = strl( @"Generating..." );
}
else {
self.contentField.enabled = NO;
self.contentField.placeholder = nil;
}
self.contentField.text = nil;
MPKey *key = [MPiOSAppDelegate get].key;
if (self.type == mainElement.type)
[mainElement resolveContentUsingKey:key result:^(NSString *string) {
PearlMainQueue( ^{ self.contentField.text = string; } );
}];
else
[self resolveContentOfCellTypeForElement:mainElement usingKey:key result:^(NSString *string) {
PearlMainQueue( ^{ self.contentField.text = string; } );
}];
break;
}
case MPContentFieldModeUser: {
self.contentField.enabled = YES;
self.contentField.placeholder = strl( @"Enter login name" );
self.contentField.text = mainElement.loginName;
break;
}
}
}
- (void)resolveContentOfCellTypeForTransientSite:(NSString *)siteName usingKey:(MPKey *)key result:(void (^)(NSString *))resultBlock {
resultBlock( nil );
}
- (void)resolveContentOfCellTypeForElement:(MPElementEntity *)element usingKey:(MPKey *)key result:(void (^)(NSString *))resultBlock {
resultBlock( nil );
}
- (MPElementEntity *)saveContentTypeWithElement:(MPElementEntity *)element saveInContext:(NSManagedObjectContext *)context {
return [[MPiOSAppDelegate get] changeElement:element saveInContext:context toType:self.type];
}
#pragma mark - UITextFieldDelegate #pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField *)textField { - (BOOL)textFieldShouldReturn:(UITextField *)textField {
@ -76,94 +182,6 @@
} }
} }
#pragma mark - Life cycle
- (void)prepareForReuse {
_contentFieldMode = 0;
[super prepareForReuse];
}
- (void)reloadWithTransientSite:(NSString *)siteName {
[super reloadWithTransientSite:siteName];
self.loginButton.alpha = 0;
self.upgradeButton.alpha = 0;
self.contentField.enabled = NO;
self.contentField.placeholder = strl( @"Tap to enter password" );
self.typeLabel.text = [MPAlgorithmDefault nameOfType:self.type];
[self resolveContentOfCellTypeForTransientSite:siteName usingKey:[MPiOSAppDelegate get].key result:^(NSString *string) {
PearlMainQueue( ^{ self.contentField.text = string; } );
}];
}
- (void)reloadWithElement:(MPElementEntity *)mainElement {
[super reloadWithElement:mainElement];
self.loginButton.alpha = 1;
self.typeLabel.text = [mainElement.algorithm nameOfType:self.type];
if (mainElement.requiresExplicitMigration)
self.upgradeButton.alpha = 1;
else
self.upgradeButton.alpha = 0;
switch (self.contentFieldMode) {
case MPContentFieldModePassword: {
if (self.type & MPElementTypeClassStored) {
self.contentField.enabled = YES;
self.contentField.placeholder = strl( @"Enter custom password" );
}
else if (self.type & MPElementTypeClassGenerated) {
self.contentField.enabled = NO;
self.contentField.placeholder = strl( @"Generating..." );
}
else {
self.contentField.enabled = NO;
self.contentField.placeholder = nil;
}
self.contentField.text = nil;
MPKey *key = [MPiOSAppDelegate get].key;
if (self.type == mainElement.type)
[mainElement resolveContentUsingKey:key result:^(NSString *string) {
PearlMainQueue( ^{ self.contentField.text = string; } );
}];
else
[self resolveContentOfCellTypeForElement:mainElement usingKey:key result:^(NSString *string) {
PearlMainQueue( ^{ self.contentField.text = string; } );
}];
break;
}
case MPContentFieldModeUser: {
self.contentField.enabled = YES;
self.contentField.placeholder = strl( @"Enter login name" );
self.contentField.text = mainElement.loginName;
break;
}
}
}
- (void)resolveContentOfCellTypeForTransientSite:(NSString *)siteName usingKey:(MPKey *)key result:(void (^)(NSString *))resultBlock {
resultBlock( nil );
}
- (void)resolveContentOfCellTypeForElement:(MPElementEntity *)element usingKey:(MPKey *)key result:(void (^)(NSString *))resultBlock {
resultBlock( nil );
}
- (MPElementEntity *)saveContentTypeWithElement:(MPElementEntity *)element saveInContext:(NSManagedObjectContext *)context {
return [[MPiOSAppDelegate get] changeElement:element saveInContext:context toType:self.type];
}
#pragma mark - Actions #pragma mark - Actions
- (IBAction)doUser:(id)sender { - (IBAction)doUser:(id)sender {

View File

@ -37,7 +37,6 @@
NSArray *_notificationObservers; NSArray *_notificationObservers;
__weak UITapGestureRecognizer *_passwordsDismissRecognizer; __weak UITapGestureRecognizer *_passwordsDismissRecognizer;
NSFetchedResultsController *_fetchedResultsController; NSFetchedResultsController *_fetchedResultsController;
NSManagedObjectID *_activeElementOID;
BOOL _exactMatch; BOOL _exactMatch;
NSMutableDictionary *_fetchedUpdates; NSMutableDictionary *_fetchedUpdates;
UIColor *_backgroundColor; UIColor *_backgroundColor;
@ -143,21 +142,24 @@
initAlert:nil tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) { initAlert:nil tappedButtonBlock:^(UIAlertView *alert, NSInteger buttonIndex) {
if (buttonIndex == [alert cancelButtonIndex]) { if (buttonIndex == [alert cancelButtonIndex]) {
// Cancel // Cancel
[collectionView selectItemAtIndexPath:indexPath animated:NO NSIndexPath *indexPath_ = [collectionView indexPathForCell:cell];
[collectionView selectItemAtIndexPath:indexPath_ animated:NO
scrollPosition:UICollectionViewScrollPositionCenteredHorizontally]; scrollPosition:UICollectionViewScrollPositionCenteredHorizontally];
[collectionView deselectItemAtIndexPath:indexPath animated:YES]; [collectionView deselectItemAtIndexPath:indexPath_ animated:YES];
return; return;
} }
// Create // Create
[[MPiOSAppDelegate get] addElementNamed:newSiteName completion:^(MPElementEntity *element) { [[MPiOSAppDelegate get] addElementNamed:newSiteName completion:^(MPElementEntity *element) {
self.activeElement = element; PearlMainQueue( ^{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[PearlOverlay showTemporaryOverlayWithTitle:strf( @"Added %@", newSiteName ) dismissAfter:2]; [PearlOverlay showTemporaryOverlayWithTitle:strf( @"Added %@", newSiteName ) dismissAfter:2];
[collectionView selectItemAtIndexPath:indexPath animated:NO PearlMainQueueAfter( 0.2f, ^{
scrollPosition:UICollectionViewScrollPositionCenteredHorizontally]; NSIndexPath *indexPath_ = [collectionView indexPathForCell:cell];
[collectionView deselectItemAtIndexPath:indexPath animated:YES]; [collectionView selectItemAtIndexPath:indexPath_ animated:NO
}]; scrollPosition:UICollectionViewScrollPositionCenteredHorizontally];
[collectionView deselectItemAtIndexPath:indexPath_ animated:YES];
} );
} );
}]; }];
} cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonYes, nil]; } cancelTitle:[PearlStrings get].commonButtonCancel otherTitles:[PearlStrings get].commonButtonYes, nil];
return; return;
@ -178,24 +180,32 @@
@"emergency" : @NO @"emergency" : @NO
} ); } );
[element use];
[element resolveContentUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) { [element resolveContentUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) {
if (![result length]) { if (![result length]) {
[collectionView selectItemAtIndexPath:indexPath animated:NO PearlMainQueue(^{
scrollPosition:UICollectionViewScrollPositionCenteredHorizontally]; NSIndexPath *indexPath_ = [collectionView indexPathForCell:cell];
[collectionView deselectItemAtIndexPath:indexPath animated:YES]; [collectionView selectItemAtIndexPath:indexPath_ animated:NO
scrollPosition:UICollectionViewScrollPositionCenteredHorizontally];
[collectionView deselectItemAtIndexPath:indexPath_ animated:YES];
});
return; return;
} }
[UIPasteboard generalPasteboard].string = result; [UIPasteboard generalPasteboard].string = result;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{ PearlMainQueue( ^{
[PearlOverlay showTemporaryOverlayWithTitle:@"Password Copied" dismissAfter:2]; [PearlOverlay showTemporaryOverlayWithTitle:@"Password Copied" dismissAfter:2];
PearlMainQueueAfter( 0.1f, ^{ PearlMainQueueAfter( 0.2f, ^{
[collectionView selectItemAtIndexPath:indexPath animated:NO NSIndexPath *indexPath_ = [collectionView indexPathForCell:cell];
[collectionView selectItemAtIndexPath:indexPath_ animated:NO
scrollPosition:UICollectionViewScrollPositionCenteredHorizontally]; scrollPosition:UICollectionViewScrollPositionCenteredHorizontally];
[collectionView deselectItemAtIndexPath:indexPath animated:YES]; [collectionView deselectItemAtIndexPath:indexPath_ animated:YES];
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
[[cell elementInContext:context] use];
[context saveToStore];
}];
} ); } );
}]; } );
}]; }];
} }
@ -335,6 +345,16 @@
#pragma mark - UISearchBarDelegate #pragma mark - UISearchBarDelegate
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
if (searchBar == self.passwordsSearchBar) {
searchBar.text = nil;
return YES;
}
return NO;
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar { - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
if (searchBar == self.passwordsSearchBar) { if (searchBar == self.passwordsSearchBar) {
@ -404,7 +424,6 @@
queue:nil usingBlock:^(NSNotification *note) { queue:nil usingBlock:^(NSNotification *note) {
Strongify(self); Strongify(self);
self.activeElement = nil;
_fetchedResultsController = nil; _fetchedResultsController = nil;
self.passwordsSearchBar.text = nil; self.passwordsSearchBar.text = nil;
[self updatePasswords]; [self updatePasswords];
@ -438,8 +457,8 @@
_mocObserver = [[NSNotificationCenter defaultCenter] _mocObserver = [[NSNotificationCenter defaultCenter]
addObserverForName:NSManagedObjectContextObjectsDidChangeNotification object:mainContext addObserverForName:NSManagedObjectContextObjectsDidChangeNotification object:mainContext
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
Strongify(self); // Strongify(self);
[self updatePasswords]; // [self updatePasswords];
}]; }];
if (!_storeObserver) if (!_storeObserver)
_storeObserver = [[NSNotificationCenter defaultCenter] _storeObserver = [[NSNotificationCenter defaultCenter]
@ -534,13 +553,6 @@
return _fetchedResultsController; return _fetchedResultsController;
} }
- (void)setActiveElement:(MPElementEntity *)activeElement {
_activeElementOID = activeElement.objectID;
[self updatePasswords];
}
- (void)setActive:(BOOL)active { - (void)setActive:(BOOL)active {
[self setActive:active animated:NO completion:nil]; [self setActive:active animated:NO completion:nil];

View File

@ -27,7 +27,8 @@
@property(weak, nonatomic) IBOutlet LLGitTip *gitTipButton; @property(weak, nonatomic) IBOutlet LLGitTip *gitTipButton;
@property(weak, nonatomic) IBOutlet UITextField *entryField; @property(weak, nonatomic) IBOutlet UITextField *entryField;
@property(weak, nonatomic) IBOutlet UILabel *entryLabel; @property(weak, nonatomic) IBOutlet UILabel *entryLabel;
@property(weak, nonatomic) IBOutlet UILabel *entryTip; @property(weak, nonatomic) IBOutlet UILabel *entryTipTitleLabel;
@property(weak, nonatomic) IBOutlet UILabel *entryTipSubtitleLabel;
@property(weak, nonatomic) IBOutlet UIView *entryTipContainer; @property(weak, nonatomic) IBOutlet UIView *entryTipContainer;
@property(weak, nonatomic) IBOutlet UIView *entryContainer; @property(weak, nonatomic) IBOutlet UIView *entryContainer;
@property(weak, nonatomic) IBOutlet UIView *footerContainer; @property(weak, nonatomic) IBOutlet UIView *footerContainer;

View File

@ -127,7 +127,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) {
if (!signedIn) { if (!signedIn) {
// Sign in failed. // Sign in failed.
[self showEntryTip:strl( @"Incorrect password! Typo?" )]; [self showEntryTip:strl( @"Looks like a typo!\nTry again; that password was incorrect." )];
return; return;
} }
}]; }];
@ -138,7 +138,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) {
NSString *userName = self.entryField.text; NSString *userName = self.entryField.text;
if (![userName length]) { if (![userName length]) {
// No name entered. // No name entered.
[self showEntryTip:strl( @"First, enter your name" )]; [self showEntryTip:strl( @"First, enter your name." )];
return NO; return NO;
} }
@ -150,7 +150,7 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) {
NSString *masterPassword = self.entryField.text; NSString *masterPassword = self.entryField.text;
if (![masterPassword length]) { if (![masterPassword length]) {
// No password entered. // No password entered.
[self showEntryTip:strl( @"Pick a master password" )]; [self showEntryTip:strl( @"Pick a master password." )];
return NO; return NO;
} }
@ -161,13 +161,13 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) {
NSString *masterPassword = self.entryField.text; NSString *masterPassword = self.entryField.text;
if (![masterPassword length]) { if (![masterPassword length]) {
// No password entered. // No password entered.
[self showEntryTip:strl( @"Confirm your master password" )]; [self showEntryTip:strl( @"Confirm your master password." )];
return NO; return NO;
} }
if (![masterPassword isEqualToString:_masterPasswordChoice]) { if (![masterPassword isEqualToString:_masterPasswordChoice]) {
// Master password confirmation failed. // Master password confirmation failed.
[self showEntryTip:strl( @"Looks like a typo! Try again." )]; [self showEntryTip:strl( @"Looks like a typo!\nTry again; enter your master password twice." )];
self.activeUserState = MPActiveUserStateMasterPasswordChoice; self.activeUserState = MPActiveUserStateMasterPasswordChoice;
return NO; return NO;
} }
@ -390,7 +390,12 @@ typedef NS_ENUM(NSUInteger, MPActiveUserState) {
- (void)showEntryTip:(NSString *)message { - (void)showEntryTip:(NSString *)message {
self.entryTip.text = message; NSUInteger newlineIndex = [message rangeOfString:@"\n"].location;
NSString *messageTitle = newlineIndex == NSNotFound? message: [message substringToIndex:newlineIndex];
NSString *messageSubtitle = newlineIndex == NSNotFound? nil: [message substringFromIndex:newlineIndex];
self.entryTipTitleLabel.text = messageTitle;
self.entryTipSubtitleLabel.text = messageSubtitle;
[UIView animateWithDuration:0.3f animations:^{ [UIView animateWithDuration:0.3f animations:^{
self.entryTipContainer.alpha = 1; self.entryTipContainer.alpha = 1;
} completion:^(BOOL finished) { } completion:^(BOOL finished) {

View File

@ -3829,7 +3829,7 @@
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = "/bin/bash -e"; shellPath = "/bin/bash -e";
shellScript = "[[ -x /usr/local/bin/moarfonts ]] || {\n echo >&2 \"moarfonts not installed, embedded fonts will not show up in IB.\"\n exit\n}\n\nfind \"${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}\" -name '*.otf' -exec /usr/local/bin/moarfonts install {} +"; shellScript = "[[ -x /usr/local/bin/moarfonts ]] || {\n echo >&2 \"moarfonts not installed, embedded fonts will not show up in IB.\"\n exit\n}\n\n[[ -w \"$SDKROOT/System/Library/.lilid/.lilic\" ]] || {\n /usr/local/bin/moarfonts reset\n}\n\nfind \"${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}\" -name '*.otf' -exec /usr/local/bin/moarfonts install {} +";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
DAD3125D155288AA00A3F9ED /* Run Script: Crashlytics */ = { DAD3125D155288AA00A3F9ED /* Run Script: Crashlytics */ = {

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="5053" systemVersion="13C64" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="Q1S-vU-GGO"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="5056" systemVersion="13C64" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="Q1S-vU-GGO">
<dependencies> <dependencies>
<deployment defaultVersion="1792" identifier="iOS"/> <deployment defaultVersion="1792" identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3733"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3733"/>
@ -20,7 +20,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rWM-08-aab" userLabel="Users Root"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rWM-08-aab" userLabel="Users Root">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/> <rect key="frame" x="0.0" y="0.0" width="321" height="568"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews> <subviews>
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="VDd-oM-ZOO" userLabel="Store Activity"> <activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="VDd-oM-ZOO" userLabel="Store Activity">
@ -28,7 +28,7 @@
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</activityIndicatorView> </activityIndicatorView>
<navigationBar contentMode="scaleToFill" translucent="NO" translatesAutoresizingMaskIntoConstraints="NO" id="790-G2-I8g"> <navigationBar contentMode="scaleToFill" translucent="NO" translatesAutoresizingMaskIntoConstraints="NO" id="790-G2-I8g">
<rect key="frame" x="0.0" y="20" width="320" height="44"/> <rect key="frame" x="0.0" y="20" width="321" height="44"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<color key="barTintColor" red="0.12549020350000001" green="0.1411764771" blue="0.14901961389999999" alpha="1" colorSpace="calibratedRGB"/> <color key="barTintColor" red="0.12549020350000001" green="0.1411764771" blue="0.14901961389999999" alpha="1" colorSpace="calibratedRGB"/>
<items> <items>
@ -36,7 +36,7 @@
</items> </items>
</navigationBar> </navigationBar>
<collectionView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" alpha="0.0" contentMode="scaleToFill" minimumZoomScale="0.0" maximumZoomScale="0.0" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="L6J-pd-gcp" userLabel="Avatar Collection"> <collectionView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" alpha="0.0" contentMode="scaleToFill" minimumZoomScale="0.0" maximumZoomScale="0.0" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="L6J-pd-gcp" userLabel="Avatar Collection">
<rect key="frame" x="0.0" y="20" width="320" height="548"/> <rect key="frame" x="0.0" y="20" width="321" height="548"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="0.0" minimumInteritemSpacing="0.0" id="ATB-kM-EGu"> <collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="0.0" minimumInteritemSpacing="0.0" id="ATB-kM-EGu">
@ -50,7 +50,7 @@
<rect key="frame" x="80" y="-10" width="160" height="568"/> <rect key="frame" x="80" y="-10" width="160" height="568"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<userGuides> <userGuides>
<userLayoutGuide location="209" affinity="minY"/> <userLayoutGuide location="210" affinity="minY"/>
</userGuides> </userGuides>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center"> <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="160" height="568"/> <rect key="frame" x="0.0" y="0.0" width="160" height="568"/>
@ -131,7 +131,7 @@
</connections> </connections>
</collectionView> </collectionView>
<button opaque="NO" alpha="0.69999999999999996" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9u7-pu-Wtv" userLabel="Previous Avatar"> <button opaque="NO" alpha="0.69999999999999996" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="9u7-pu-Wtv" userLabel="Previous Avatar">
<rect key="frame" x="0.0" y="191.5" width="44" height="53"/> <rect key="frame" x="0.0" y="171" width="44" height="93"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="44" id="Ay6-Jg-c3T"/> <constraint firstAttribute="width" constant="44" id="Ay6-Jg-c3T"/>
@ -147,7 +147,7 @@
</connections> </connections>
</button> </button>
<button opaque="NO" alpha="0.69999999999999996" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fUK-gJ-NRE" userLabel="Next Avatar"> <button opaque="NO" alpha="0.69999999999999996" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fUK-gJ-NRE" userLabel="Next Avatar">
<rect key="frame" x="276" y="191.5" width="44" height="53"/> <rect key="frame" x="277" y="191" width="44" height="53"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<constraints> <constraints>
<constraint firstAttribute="width" constant="44" id="oAm-YX-Fx5"/> <constraint firstAttribute="width" constant="44" id="oAm-YX-Fx5"/>
@ -161,23 +161,23 @@
</connections> </connections>
</button> </button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qp1-nX-o4i" userLabel="Entry" customClass="PearlUIView"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qp1-nX-o4i" userLabel="Entry" customClass="PearlUIView">
<rect key="frame" x="20" y="280" width="280" height="63"/> <rect key="frame" x="20" y="280" width="281" height="63"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<subviews> <subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Enter your full name:" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="5fe-rt-zFa" userLabel="Entry Label"> <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Enter your full name:" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="5fe-rt-zFa" userLabel="Entry Label">
<rect key="frame" x="20" y="0.0" width="240" height="18"/> <rect key="frame" x="20" y="0.0" width="241" height="18"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="Copperplate" family="Copperplate" pointSize="17"/> <fontDescription key="fontDescription" name="Copperplate" family="Copperplate" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="ui_textfield.png" translatesAutoresizingMaskIntoConstraints="NO" id="UfK-na-vOU" userLabel="Field Background"> <imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="ui_textfield.png" translatesAutoresizingMaskIntoConstraints="NO" id="UfK-na-vOU" userLabel="Field Background">
<rect key="frame" x="0.0" y="26" width="280" height="37"/> <rect key="frame" x="0.0" y="26" width="281" height="37"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<rect key="contentStretch" x="0.25" y="0.25" width="0.49999999999999961" height="0.49999999999999961"/> <rect key="contentStretch" x="0.25" y="0.25" width="0.49999999999999961" height="0.49999999999999961"/>
</imageView> </imageView>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="center" clearsOnBeginEditing="YES" minimumFontSize="14" translatesAutoresizingMaskIntoConstraints="NO" id="z3Z-AB-fG2" userLabel="Entry Field"> <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" textAlignment="center" clearsOnBeginEditing="YES" minimumFontSize="14" translatesAutoresizingMaskIntoConstraints="NO" id="z3Z-AB-fG2" userLabel="Entry Field">
<rect key="frame" x="10" y="30" width="260" height="29"/> <rect key="frame" x="10" y="30" width="261" height="29"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<fontDescription key="fontDescription" name="Copperplate" family="Copperplate" pointSize="28"/> <fontDescription key="fontDescription" name="Copperplate" family="Copperplate" pointSize="28"/>
@ -187,29 +187,41 @@
</connections> </connections>
</textField> </textField>
<view userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fdS-zb-K9I" userLabel="Entry Tip"> <view userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fdS-zb-K9I" userLabel="Entry Tip">
<rect key="frame" x="35" y="-16" width="210" height="60"/> <rect key="frame" x="28" y="-38" width="225" height="82"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews> <subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black.png" translatesAutoresizingMaskIntoConstraints="NO" id="g2g-5i-er4"> <imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black.png" translatesAutoresizingMaskIntoConstraints="NO" id="g2g-5i-er4">
<rect key="frame" x="0.0" y="0.0" width="210" height="60"/> <rect key="frame" x="0.0" y="0.0" width="225" height="82"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<rect key="contentStretch" x="0.15000000000000002" y="0.14999999999999999" width="0.69999999999999973" height="0.44999999999999996"/> <rect key="contentStretch" x="0.15000000000000002" y="0.14999999999999999" width="0.69999999999999973" height="0.44999999999999996"/>
</imageView> </imageView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Incorrect Password" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" minimumFontSize="10" preferredMaxLayoutWidth="170" translatesAutoresizingMaskIntoConstraints="NO" id="ZI7-qg-7OW"> <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Looks like a typo!" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="ZI7-qg-7OW">
<rect key="frame" x="20" y="12" width="170" height="17"/> <rect key="frame" x="20" y="12" width="185" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/> <fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/> <color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Try again; the password was wrong." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" minimumFontSize="10" preferredMaxLayoutWidth="185" translatesAutoresizingMaskIntoConstraints="NO" id="KhE-Yj-Kvm">
<rect key="frame" x="20" y="37" width="185" height="14"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews> </subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<constraints> <constraints>
<constraint firstAttribute="trailing" secondItem="KhE-Yj-Kvm" secondAttribute="trailing" constant="20" id="2aT-TC-6e8"/>
<constraint firstItem="g2g-5i-er4" firstAttribute="leading" secondItem="fdS-zb-K9I" secondAttribute="leading" id="5ZK-p5-ihF"/> <constraint firstItem="g2g-5i-er4" firstAttribute="leading" secondItem="fdS-zb-K9I" secondAttribute="leading" id="5ZK-p5-ihF"/>
<constraint firstAttribute="trailing" secondItem="g2g-5i-er4" secondAttribute="trailing" id="8hg-ky-ZAt"/> <constraint firstAttribute="trailing" secondItem="g2g-5i-er4" secondAttribute="trailing" id="8hg-ky-ZAt"/>
<constraint firstItem="ZI7-qg-7OW" firstAttribute="leading" secondItem="fdS-zb-K9I" secondAttribute="leading" constant="20" id="Mh3-5h-v8I"/> <constraint firstItem="ZI7-qg-7OW" firstAttribute="leading" secondItem="fdS-zb-K9I" secondAttribute="leading" constant="20" id="Mh3-5h-v8I"/>
<constraint firstItem="ZI7-qg-7OW" firstAttribute="centerX" secondItem="KhE-Yj-Kvm" secondAttribute="centerX" id="aOO-Eh-pPT"/>
<constraint firstItem="g2g-5i-er4" firstAttribute="top" secondItem="fdS-zb-K9I" secondAttribute="top" id="gg2-xC-JDl"/> <constraint firstItem="g2g-5i-er4" firstAttribute="top" secondItem="fdS-zb-K9I" secondAttribute="top" id="gg2-xC-JDl"/>
<constraint firstItem="ZI7-qg-7OW" firstAttribute="centerY" secondItem="fdS-zb-K9I" secondAttribute="top" constant="20" id="ipO-Or-BYy"/> <constraint firstItem="ZI7-qg-7OW" firstAttribute="top" secondItem="fdS-zb-K9I" secondAttribute="top" constant="12" id="jX5-Hc-Wab"/>
<constraint firstItem="KhE-Yj-Kvm" firstAttribute="leading" secondItem="fdS-zb-K9I" secondAttribute="leading" constant="20" id="qF3-b1-F3u"/>
<constraint firstItem="KhE-Yj-Kvm" firstAttribute="top" secondItem="ZI7-qg-7OW" secondAttribute="bottom" constant="8" id="rOG-Mb-Hio"/>
<constraint firstAttribute="bottom" secondItem="KhE-Yj-Kvm" secondAttribute="bottom" constant="31" id="vLQ-PH-o8a"/>
<constraint firstAttribute="trailing" secondItem="ZI7-qg-7OW" secondAttribute="trailing" constant="20" id="wEs-fc-uQi"/> <constraint firstAttribute="trailing" secondItem="ZI7-qg-7OW" secondAttribute="trailing" constant="20" id="wEs-fc-uQi"/>
<constraint firstAttribute="bottom" secondItem="g2g-5i-er4" secondAttribute="bottom" id="ycz-7a-HTB"/> <constraint firstAttribute="bottom" secondItem="g2g-5i-er4" secondAttribute="bottom" id="ycz-7a-HTB"/>
</constraints> </constraints>
@ -236,7 +248,7 @@
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</view> </view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XEP-O3-ayG" userLabel="Footer" customClass="PearlUIView"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XEP-O3-ayG" userLabel="Footer" customClass="PearlUIView">
<rect key="frame" x="0.0" y="455" width="320" height="113"/> <rect key="frame" x="0.0" y="455" width="321" height="113"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews> <subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vHz-dw-oPb" userLabel="GitTip" customClass="LLGitTip"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vHz-dw-oPb" userLabel="GitTip" customClass="LLGitTip">
@ -276,7 +288,7 @@
</constraints> </constraints>
</view> </view>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.5" contentMode="left" text="Press and hold to delete or reset user." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="N9g-Kk-yjc" userLabel="Hint"> <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.5" contentMode="left" text="Press and hold to delete or reset user." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="N9g-Kk-yjc" userLabel="Hint">
<rect key="frame" x="20" y="79" width="280" height="14"/> <rect key="frame" x="20" y="79" width="281" height="14"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<fontDescription key="fontDescription" name="Copperplate" family="Copperplate" pointSize="12"/> <fontDescription key="fontDescription" name="Copperplate" family="Copperplate" pointSize="12"/>
<color key="textColor" cocoaTouchSystemColor="lightTextColor"/> <color key="textColor" cocoaTouchSystemColor="lightTextColor"/>
@ -337,8 +349,9 @@
<outlet property="entryContainer" destination="qp1-nX-o4i" id="tSJ-e8-W8b"/> <outlet property="entryContainer" destination="qp1-nX-o4i" id="tSJ-e8-W8b"/>
<outlet property="entryField" destination="z3Z-AB-fG2" id="iAO-Gd-flO"/> <outlet property="entryField" destination="z3Z-AB-fG2" id="iAO-Gd-flO"/>
<outlet property="entryLabel" destination="5fe-rt-zFa" id="Nn1-nQ-oy3"/> <outlet property="entryLabel" destination="5fe-rt-zFa" id="Nn1-nQ-oy3"/>
<outlet property="entryTip" destination="ZI7-qg-7OW" id="dZj-rZ-efd"/>
<outlet property="entryTipContainer" destination="fdS-zb-K9I" id="sJc-4z-usV"/> <outlet property="entryTipContainer" destination="fdS-zb-K9I" id="sJc-4z-usV"/>
<outlet property="entryTipSubtitleLabel" destination="KhE-Yj-Kvm" id="G0X-19-RmH"/>
<outlet property="entryTipTitleLabel" destination="ZI7-qg-7OW" id="dZj-rZ-efd"/>
<outlet property="footerContainer" destination="XEP-O3-ayG" id="9cI-p9-av3"/> <outlet property="footerContainer" destination="XEP-O3-ayG" id="9cI-p9-av3"/>
<outlet property="gitTipButton" destination="vHz-dw-oPb" id="3tG-8S-u13"/> <outlet property="gitTipButton" destination="vHz-dw-oPb" id="3tG-8S-u13"/>
<outlet property="gitTipTip" destination="069-Pu-yXe" id="wWf-2X-Ryw"/> <outlet property="gitTipTip" destination="069-Pu-yXe" id="wWf-2X-Ryw"/>
@ -928,8 +941,19 @@
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/> <rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="i0q-rq-0T2" userLabel="Dismiss Button">
<rect key="frame" x="0.0" y="0.0" width="320" height="568"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="calibratedRGB"/>
<state key="normal">
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections>
<segue destination="p6o-h3-NRH" kind="unwind" unwindAction="unwindToCombined:" id="E2V-ll-ZD7"/>
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1lc-e7-Qme" userLabel="Emergency Generator"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1lc-e7-Qme" userLabel="Emergency Generator">
<rect key="frame" x="8" y="28" width="304" height="374"/> <rect key="frame" x="8" y="28" width="304" height="384"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Emergency Generator" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="4Lh-s0-Dbt"> <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Emergency Generator" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="4Lh-s0-Dbt">
@ -950,34 +974,37 @@
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/> <color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
<size key="shadowOffset" width="0.0" height="1"/> <size key="shadowOffset" width="0.0" height="1"/>
</label> </label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Your Name" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="XAC-Da-lpf"> <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Your Name" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="XAC-Da-lpf" userLabel="User Name">
<rect key="frame" x="20" y="106" width="264" height="30"/> <rect key="frame" x="20" y="106" width="264" height="30"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/> <fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocapitalizationType="words" keyboardAppearance="alert" returnKeyType="next" enablesReturnKeyAutomatically="YES"/> <textInputTraits key="textInputTraits" autocapitalizationType="words" keyboardAppearance="alert" returnKeyType="next" enablesReturnKeyAutomatically="YES"/>
<connections> <connections>
<action selector="controlChanged:" destination="osn-5H-SWW" eventType="editingChanged" id="cDg-Lx-6qf"/>
<outlet property="delegate" destination="osn-5H-SWW" id="VQI-Lq-GWG"/> <outlet property="delegate" destination="osn-5H-SWW" id="VQI-Lq-GWG"/>
</connections> </connections>
</textField> </textField>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Your Master Password" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="J46-0E-no3"> <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Your Master Password" clearsOnBeginEditing="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="J46-0E-no3" userLabel="Master Password">
<rect key="frame" x="20" y="144" width="264" height="30"/> <rect key="frame" x="20" y="144" width="264" height="30"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/> <fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardAppearance="alert" returnKeyType="next" enablesReturnKeyAutomatically="YES" secureTextEntry="YES"/> <textInputTraits key="textInputTraits" autocorrectionType="no" keyboardAppearance="alert" returnKeyType="next" enablesReturnKeyAutomatically="YES" secureTextEntry="YES"/>
<connections> <connections>
<action selector="controlChanged:" destination="osn-5H-SWW" eventType="editingChanged" id="u70-5j-UrY"/>
<outlet property="delegate" destination="osn-5H-SWW" id="bpf-YA-5XP"/> <outlet property="delegate" destination="osn-5H-SWW" id="bpf-YA-5XP"/>
</connections> </connections>
</textField> </textField>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Site Name" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="56H-xR-09J"> <textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="Site Name" clearsOnBeginEditing="YES" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="56H-xR-09J" userLabel="Site Name">
<rect key="frame" x="20" y="182" width="264" height="30"/> <rect key="frame" x="20" y="182" width="264" height="30"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/> <fontDescription key="fontDescription" type="system" pointSize="14"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="URL" keyboardAppearance="alert" returnKeyType="done" enablesReturnKeyAutomatically="YES"/> <textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="URL" keyboardAppearance="alert" returnKeyType="done" enablesReturnKeyAutomatically="YES"/>
<connections> <connections>
<action selector="controlChanged:" destination="osn-5H-SWW" eventType="editingChanged" id="ycr-oN-lhp"/>
<outlet property="delegate" destination="osn-5H-SWW" id="QgA-TS-5KG"/> <outlet property="delegate" destination="osn-5H-SWW" id="QgA-TS-5KG"/>
</connections> </connections>
</textField> </textField>
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" selectedSegmentIndex="1" translatesAutoresizingMaskIntoConstraints="NO" id="e4b-Iv-Pk9"> <segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bar" selectedSegmentIndex="1" translatesAutoresizingMaskIntoConstraints="NO" id="e4b-Iv-Pk9" userLabel="Type">
<rect key="frame" x="20" y="220" width="264" height="29"/> <rect key="frame" x="20" y="220" width="264" height="29"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<segments> <segments>
@ -989,6 +1016,9 @@
<segment title="PIN"/> <segment title="PIN"/>
</segments> </segments>
<color key="tintColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="1" colorSpace="calibratedRGB"/> <color key="tintColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="1" colorSpace="calibratedRGB"/>
<connections>
<action selector="controlChanged:" destination="osn-5H-SWW" eventType="valueChanged" id="sRc-3g-wqY"/>
</connections>
</segmentedControl> </segmentedControl>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Counter" lineBreakMode="tailTruncation" numberOfLines="0" minimumFontSize="10" preferredMaxLayoutWidth="64" translatesAutoresizingMaskIntoConstraints="NO" id="cAo-K2-E23"> <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Counter" lineBreakMode="tailTruncation" numberOfLines="0" minimumFontSize="10" preferredMaxLayoutWidth="64" translatesAutoresizingMaskIntoConstraints="NO" id="cAo-K2-E23">
<rect key="frame" x="20" y="259" width="64" height="22"/> <rect key="frame" x="20" y="259" width="64" height="22"/>
@ -999,9 +1029,12 @@
<color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/> <color key="shadowColor" cocoaTouchSystemColor="darkTextColor"/>
<size key="shadowOffset" width="0.0" height="1"/> <size key="shadowOffset" width="0.0" height="1"/>
</label> </label>
<stepper opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" maximumValue="100" translatesAutoresizingMaskIntoConstraints="NO" id="ZPT-EI-yuv"> <stepper opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" maximumValue="100" translatesAutoresizingMaskIntoConstraints="NO" id="ZPT-EI-yuv" userLabel="Counter">
<rect key="frame" x="190" y="256" width="94" height="29"/> <rect key="frame" x="190" y="256" width="94" height="29"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<connections>
<action selector="controlChanged:" destination="osn-5H-SWW" eventType="valueChanged" id="eQA-3X-uc9"/>
</connections>
</stepper> </stepper>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="1" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="3Cd-XH-Wau"> <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="1" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="3Cd-XH-Wau">
<rect key="frame" x="172" y="259" width="10" height="21"/> <rect key="frame" x="172" y="259" width="10" height="21"/>
@ -1010,7 +1043,7 @@
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<color key="highlightedColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <color key="highlightedColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</label> </label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bON-0a-K0M"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="bON-0a-K0M" userLabel="Close Button">
<rect key="frame" x="260" y="0.0" width="44" height="44"/> <rect key="frame" x="260" y="0.0" width="44" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" hint="" label="Close"/> <accessibility key="accessibilityConfiguration" hint="" label="Close"/>
@ -1030,7 +1063,7 @@
<segue destination="p6o-h3-NRH" kind="unwind" identifier="emergency" unwindAction="unwindToCombined:" id="VI2-VR-bQc"/> <segue destination="p6o-h3-NRH" kind="unwind" identifier="emergency" unwindAction="unwindToCombined:" id="VI2-VR-bQc"/>
</connections> </connections>
</button> </button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="J2u-kc-30c"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="J2u-kc-30c" userLabel="Settings Button">
<rect key="frame" x="0.0" y="0.0" width="44" height="44"/> <rect key="frame" x="0.0" y="0.0" width="44" height="44"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<accessibility key="accessibilityConfiguration" hint="" label="Close"/> <accessibility key="accessibilityConfiguration" hint="" label="Close"/>
@ -1048,27 +1081,23 @@
</state> </state>
</button> </button>
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="4sN-hm-xio"> <activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="4sN-hm-xio">
<rect key="frame" x="133" y="317" width="37" height="37"/> <rect key="frame" x="134" y="326" width="37" height="37"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
</activityIndicatorView> </activityIndicatorView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="W8a-1e-Qpz"> <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="XapaNuwjFihn6$" textAlignment="center" lineBreakMode="clip" baselineAdjustment="alignBaselines" minimumFontSize="10" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bHR-he-dnZ" userLabel="Password Label">
<rect key="frame" x="0.0" y="325" width="304" height="49"/> <rect key="frame" x="20" y="325" width="264" height="39"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" name="AmericanTypewriter-Bold" family="American Typewriter" pointSize="30"/> <gestureRecognizers/>
<size key="titleShadowOffset" width="0.0" height="1"/> <fontDescription key="fontDescription" name="SourceCodePro-Black" family="Source Code Pro" pointSize="30"/>
<state key="normal" title="Kucy9-RimuTich"> <color key="textColor" red="0.47450980390000003" green="0.86666666670000003" blue="0.98431372549999996" alpha="1" colorSpace="calibratedRGB"/>
<color key="titleColor" red="0.47450980390000003" green="0.86666666670000003" blue="0.98431372549999996" alpha="1" colorSpace="calibratedRGB"/> <nil key="highlightedColor"/>
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> <color key="shadowColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="1" colorSpace="calibratedRGB"/>
</state>
<state key="highlighted">
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</state>
<connections> <connections>
<action selector="emergencyCopy:" destination="osn-5H-SWW" eventType="touchUpInside" id="JvH-n0-6k8"/> <outletCollection property="gestureRecognizers" destination="gJb-50-mjy" appends="YES" id="3Ho-tp-mDE"/>
</connections> </connections>
</button> </label>
<view hidden="YES" userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="beo-cJ-jIn" userLabel="View - Content Tip"> <view userInteractionEnabled="NO" alpha="0.0" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="beo-cJ-jIn" userLabel="View - Content Tip">
<rect key="frame" x="47" y="289" width="210" height="60"/> <rect key="frame" x="47" y="284" width="210" height="60"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews> <subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black.png" translatesAutoresizingMaskIntoConstraints="NO" id="nyL-cO-aPa"> <imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black.png" translatesAutoresizingMaskIntoConstraints="NO" id="nyL-cO-aPa">
@ -1099,10 +1128,10 @@
<color key="backgroundColor" cocoaTouchSystemColor="viewFlipsideBackgroundColor"/> <color key="backgroundColor" cocoaTouchSystemColor="viewFlipsideBackgroundColor"/>
<constraints> <constraints>
<constraint firstItem="J46-0E-no3" firstAttribute="top" secondItem="XAC-Da-lpf" secondAttribute="bottom" constant="8" symbolic="YES" id="0sm-dC-Ype"/> <constraint firstItem="J46-0E-no3" firstAttribute="top" secondItem="XAC-Da-lpf" secondAttribute="bottom" constant="8" symbolic="YES" id="0sm-dC-Ype"/>
<constraint firstItem="W8a-1e-Qpz" firstAttribute="top" secondItem="ZPT-EI-yuv" secondAttribute="bottom" constant="40" id="2N2-cs-FPH"/>
<constraint firstAttribute="trailing" secondItem="56H-xR-09J" secondAttribute="trailing" constant="20" symbolic="YES" id="38q-U5-ROK"/> <constraint firstAttribute="trailing" secondItem="56H-xR-09J" secondAttribute="trailing" constant="20" symbolic="YES" id="38q-U5-ROK"/>
<constraint firstAttribute="bottom" secondItem="4sN-hm-xio" secondAttribute="bottom" constant="20" symbolic="YES" id="5Eu-eF-yJE"/> <constraint firstAttribute="bottom" secondItem="bHR-he-dnZ" secondAttribute="bottom" constant="20" symbolic="YES" id="634-F6-VfW"/>
<constraint firstItem="XAC-Da-lpf" firstAttribute="top" secondItem="vHS-3A-Tae" secondAttribute="bottom" constant="8" symbolic="YES" id="6DM-0p-7ZN"/> <constraint firstItem="XAC-Da-lpf" firstAttribute="top" secondItem="vHS-3A-Tae" secondAttribute="bottom" constant="8" symbolic="YES" id="6DM-0p-7ZN"/>
<constraint firstItem="4sN-hm-xio" firstAttribute="centerX" secondItem="bHR-he-dnZ" secondAttribute="centerX" id="6zE-cB-Cw3"/>
<constraint firstAttribute="trailing" secondItem="bON-0a-K0M" secondAttribute="trailing" id="A9o-KP-Gco"/> <constraint firstAttribute="trailing" secondItem="bON-0a-K0M" secondAttribute="trailing" id="A9o-KP-Gco"/>
<constraint firstAttribute="trailing" secondItem="XAC-Da-lpf" secondAttribute="trailing" constant="20" symbolic="YES" id="AM8-r9-7JZ"/> <constraint firstAttribute="trailing" secondItem="XAC-Da-lpf" secondAttribute="trailing" constant="20" symbolic="YES" id="AM8-r9-7JZ"/>
<constraint firstAttribute="trailing" secondItem="4Lh-s0-Dbt" secondAttribute="trailing" constant="20" symbolic="YES" id="AiF-cY-b3S"/> <constraint firstAttribute="trailing" secondItem="4Lh-s0-Dbt" secondAttribute="trailing" constant="20" symbolic="YES" id="AiF-cY-b3S"/>
@ -1112,35 +1141,38 @@
<constraint firstItem="vHS-3A-Tae" firstAttribute="top" secondItem="4Lh-s0-Dbt" secondAttribute="bottom" constant="8" symbolic="YES" id="KSY-FU-zZo"/> <constraint firstItem="vHS-3A-Tae" firstAttribute="top" secondItem="4Lh-s0-Dbt" secondAttribute="bottom" constant="8" symbolic="YES" id="KSY-FU-zZo"/>
<constraint firstItem="56H-xR-09J" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" constant="20" symbolic="YES" id="Mau-H7-qGk"/> <constraint firstItem="56H-xR-09J" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" constant="20" symbolic="YES" id="Mau-H7-qGk"/>
<constraint firstItem="J2u-kc-30c" firstAttribute="top" secondItem="1lc-e7-Qme" secondAttribute="top" id="P6z-yO-yf1"/> <constraint firstItem="J2u-kc-30c" firstAttribute="top" secondItem="1lc-e7-Qme" secondAttribute="top" id="P6z-yO-yf1"/>
<constraint firstAttribute="bottom" secondItem="W8a-1e-Qpz" secondAttribute="bottom" id="UHK-Oa-dVz"/> <constraint firstItem="beo-cJ-jIn" firstAttribute="bottom" secondItem="bHR-he-dnZ" secondAttribute="centerY" id="R9G-XW-hhn"/>
<constraint firstAttribute="trailing" secondItem="W8a-1e-Qpz" secondAttribute="trailing" id="Wto-bi-7cK"/>
<constraint firstItem="beo-cJ-jIn" firstAttribute="centerX" secondItem="W8a-1e-Qpz" secondAttribute="centerX" id="XKG-YV-Ywc"/>
<constraint firstAttribute="trailing" secondItem="ZPT-EI-yuv" secondAttribute="trailing" constant="20" symbolic="YES" id="Y6S-XB-LZw"/> <constraint firstAttribute="trailing" secondItem="ZPT-EI-yuv" secondAttribute="trailing" constant="20" symbolic="YES" id="Y6S-XB-LZw"/>
<constraint firstItem="cAo-K2-E23" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" constant="20" symbolic="YES" id="ana-bH-tXF"/> <constraint firstItem="cAo-K2-E23" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" constant="20" symbolic="YES" id="ana-bH-tXF"/>
<constraint firstItem="cAo-K2-E23" firstAttribute="centerY" secondItem="3Cd-XH-Wau" secondAttribute="centerY" id="bNn-uS-xFD"/> <constraint firstItem="cAo-K2-E23" firstAttribute="centerY" secondItem="3Cd-XH-Wau" secondAttribute="centerY" id="bNn-uS-xFD"/>
<constraint firstItem="beo-cJ-jIn" firstAttribute="centerX" secondItem="bHR-he-dnZ" secondAttribute="centerX" id="c6g-9Y-zp8"/>
<constraint firstItem="J2u-kc-30c" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" id="dAy-CG-bok"/> <constraint firstItem="J2u-kc-30c" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" id="dAy-CG-bok"/>
<constraint firstAttribute="trailing" secondItem="e4b-Iv-Pk9" secondAttribute="trailing" constant="20" symbolic="YES" id="eJc-ik-sKE"/> <constraint firstAttribute="trailing" secondItem="e4b-Iv-Pk9" secondAttribute="trailing" constant="20" symbolic="YES" id="eJc-ik-sKE"/>
<constraint firstItem="4sN-hm-xio" firstAttribute="centerY" secondItem="bHR-he-dnZ" secondAttribute="centerY" id="evM-RH-hWz"/>
<constraint firstAttribute="trailing" secondItem="vHS-3A-Tae" secondAttribute="trailing" constant="20" symbolic="YES" id="f5B-0z-RcZ"/> <constraint firstAttribute="trailing" secondItem="vHS-3A-Tae" secondAttribute="trailing" constant="20" symbolic="YES" id="f5B-0z-RcZ"/>
<constraint firstItem="e4b-Iv-Pk9" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" constant="20" symbolic="YES" id="gO9-M2-f6V"/> <constraint firstItem="e4b-Iv-Pk9" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" constant="20" symbolic="YES" id="gO9-M2-f6V"/>
<constraint firstItem="bHR-he-dnZ" firstAttribute="top" secondItem="ZPT-EI-yuv" secondAttribute="bottom" constant="40" id="h5p-p9-1Bn"/>
<constraint firstItem="4Lh-s0-Dbt" firstAttribute="top" secondItem="1lc-e7-Qme" secondAttribute="top" constant="20" symbolic="YES" id="hIW-2I-3FE"/> <constraint firstItem="4Lh-s0-Dbt" firstAttribute="top" secondItem="1lc-e7-Qme" secondAttribute="top" constant="20" symbolic="YES" id="hIW-2I-3FE"/>
<constraint firstItem="bON-0a-K0M" firstAttribute="top" secondItem="1lc-e7-Qme" secondAttribute="top" id="ikF-Ua-E4r"/> <constraint firstItem="bON-0a-K0M" firstAttribute="top" secondItem="1lc-e7-Qme" secondAttribute="top" id="ikF-Ua-E4r"/>
<constraint firstItem="W8a-1e-Qpz" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" id="mMd-GF-btJ"/> <constraint firstItem="bHR-he-dnZ" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" constant="20" symbolic="YES" id="khT-uV-5VC"/>
<constraint firstAttribute="trailing" secondItem="J46-0E-no3" secondAttribute="trailing" constant="20" symbolic="YES" id="n1Q-ie-qM5"/> <constraint firstAttribute="trailing" secondItem="J46-0E-no3" secondAttribute="trailing" constant="20" symbolic="YES" id="n1Q-ie-qM5"/>
<constraint firstItem="4Lh-s0-Dbt" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" constant="20" symbolic="YES" id="oS6-8x-NDj"/> <constraint firstItem="4Lh-s0-Dbt" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" constant="20" symbolic="YES" id="oS6-8x-NDj"/>
<constraint firstItem="ZPT-EI-yuv" firstAttribute="leading" secondItem="3Cd-XH-Wau" secondAttribute="trailing" constant="8" symbolic="YES" id="rX1-52-d9v"/> <constraint firstItem="ZPT-EI-yuv" firstAttribute="leading" secondItem="3Cd-XH-Wau" secondAttribute="trailing" constant="8" symbolic="YES" id="rX1-52-d9v"/>
<constraint firstItem="vHS-3A-Tae" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" constant="20" symbolic="YES" id="tHF-hR-QxL"/> <constraint firstItem="vHS-3A-Tae" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" constant="20" symbolic="YES" id="tHF-hR-QxL"/>
<constraint firstItem="J46-0E-no3" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" constant="20" symbolic="YES" id="tbN-R3-voN"/> <constraint firstItem="J46-0E-no3" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" constant="20" symbolic="YES" id="tbN-R3-voN"/>
<constraint firstItem="beo-cJ-jIn" firstAttribute="bottom" secondItem="W8a-1e-Qpz" secondAttribute="centerY" id="xiJ-7N-2e0"/> <constraint firstAttribute="trailing" secondItem="bHR-he-dnZ" secondAttribute="trailing" constant="20" symbolic="YES" id="tkx-0V-wpi"/>
<constraint firstItem="XAC-Da-lpf" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" constant="20" symbolic="YES" id="yrb-LB-Pha"/> <constraint firstItem="XAC-Da-lpf" firstAttribute="leading" secondItem="1lc-e7-Qme" secondAttribute="leading" constant="20" symbolic="YES" id="yrb-LB-Pha"/>
<constraint firstItem="ZPT-EI-yuv" firstAttribute="top" secondItem="e4b-Iv-Pk9" secondAttribute="bottom" constant="8" symbolic="YES" id="yul-EL-xCT"/> <constraint firstItem="ZPT-EI-yuv" firstAttribute="top" secondItem="e4b-Iv-Pk9" secondAttribute="bottom" constant="8" symbolic="YES" id="yul-EL-xCT"/>
<constraint firstAttribute="centerX" secondItem="4sN-hm-xio" secondAttribute="centerX" constant="0.5" id="zQh-Ka-9zH"/>
</constraints> </constraints>
</view> </view>
</subviews> </subviews>
<color key="backgroundColor" white="0.0" alpha="0.5" colorSpace="calibratedWhite"/>
<constraints> <constraints>
<constraint firstItem="1lc-e7-Qme" firstAttribute="leading" secondItem="GiS-3g-cDj" secondAttribute="leading" constant="8" id="3xS-Ou-InS"/> <constraint firstItem="1lc-e7-Qme" firstAttribute="leading" secondItem="GiS-3g-cDj" secondAttribute="leading" constant="8" id="3xS-Ou-InS"/>
<constraint firstItem="i0q-rq-0T2" firstAttribute="leading" secondItem="GiS-3g-cDj" secondAttribute="leading" id="Jvz-1G-8UK"/>
<constraint firstAttribute="trailing" secondItem="1lc-e7-Qme" secondAttribute="trailing" constant="8" id="KWW-Vx-P8J"/> <constraint firstAttribute="trailing" secondItem="1lc-e7-Qme" secondAttribute="trailing" constant="8" id="KWW-Vx-P8J"/>
<constraint firstAttribute="bottom" secondItem="i0q-rq-0T2" secondAttribute="bottom" id="Leo-BC-ix6"/>
<constraint firstItem="i0q-rq-0T2" firstAttribute="top" secondItem="GiS-3g-cDj" secondAttribute="top" id="hlj-vB-7AH"/>
<constraint firstAttribute="trailing" secondItem="i0q-rq-0T2" secondAttribute="trailing" id="r8s-OP-rWe"/>
</constraints> </constraints>
</view> </view>
</subviews> </subviews>
@ -1157,21 +1189,26 @@
<barButtonItem key="backBarButtonItem" title="Log Out" id="cKa-vZ-q96"/> <barButtonItem key="backBarButtonItem" title="Log Out" id="cKa-vZ-q96"/>
</navigationItem> </navigationItem>
<connections> <connections>
<outlet property="emergencyActivity" destination="4sN-hm-xio" id="OR9-Pj-ygm"/> <outlet property="activity" destination="4sN-hm-xio" id="OR9-Pj-ygm"/>
<outlet property="emergencyContentTipContainer" destination="beo-cJ-jIn" id="BdT-0M-8qC"/> <outlet property="containerView" destination="GiS-3g-cDj" id="01o-PU-SNZ"/>
<outlet property="emergencyCounter" destination="3Cd-XH-Wau" id="wv7-jZ-6tX"/> <outlet property="counterLabel" destination="3Cd-XH-Wau" id="wv7-jZ-6tX"/>
<outlet property="emergencyCounterStepper" destination="ZPT-EI-yuv" id="w5c-hO-T51"/> <outlet property="counterStepper" destination="ZPT-EI-yuv" id="w5c-hO-T51"/>
<outlet property="emergencyGeneratorContainer" destination="GiS-3g-cDj" id="01o-PU-SNZ"/> <outlet property="dialogView" destination="1lc-e7-Qme" id="JYt-mv-XV2"/>
<outlet property="emergencyGeneratorDialog" destination="1lc-e7-Qme" id="JYt-mv-XV2"/> <outlet property="masterPasswordField" destination="J46-0E-no3" id="DfH-4n-cop"/>
<outlet property="emergencyMasterPassword" destination="J46-0E-no3" id="DfH-4n-cop"/> <outlet property="passwordLabel" destination="bHR-he-dnZ" id="0Mo-gc-Ls2"/>
<outlet property="emergencyName" destination="XAC-Da-lpf" id="XCk-0H-IcI"/> <outlet property="siteField" destination="56H-xR-09J" id="8no-IN-nsH"/>
<outlet property="emergencyPassword" destination="W8a-1e-Qpz" id="Xfx-nM-1LX"/> <outlet property="tipContainer" destination="beo-cJ-jIn" id="BdT-0M-8qC"/>
<outlet property="emergencySite" destination="56H-xR-09J" id="8no-IN-nsH"/> <outlet property="typeControl" destination="e4b-Iv-Pk9" id="S69-yO-7bv"/>
<outlet property="emergencyTypeControl" destination="e4b-Iv-Pk9" id="S69-yO-7bv"/> <outlet property="userNameField" destination="XAC-Da-lpf" id="XCk-0H-IcI"/>
</connections> </connections>
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="2GS-rH-ANj" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="2GS-rH-ANj" userLabel="First Responder" sceneMemberID="firstResponder"/>
<exit id="p6o-h3-NRH" userLabel="Exit" sceneMemberID="exit"/> <exit id="p6o-h3-NRH" userLabel="Exit" sceneMemberID="exit"/>
<tapGestureRecognizer id="gJb-50-mjy">
<connections>
<action selector="copyPassword:" destination="osn-5H-SWW" id="qCd-S2-Bvk"/>
</connections>
</tapGestureRecognizer>
</objects> </objects>
<point key="canvasLocation" x="1350" y="-264"/> <point key="canvasLocation" x="1350" y="-264"/>
</scene> </scene>