2
0
Fork 0

Compare commits

...

14 Commits

Author SHA1 Message Date
Maarten Billemont 0b6e43a18f The root of the users VC interferes with touches from the sites VC when it appears. 2021-11-03 21:13:04 -04:00
Maarten Billemont c94c52f4b6 Fix migration tips no longer interactable when logged in. 2021-11-03 16:51:37 -04:00
Maarten Billemont 5de9b05299 Move Spectre migration dialogs fully global & make closeable. 2021-11-01 21:16:00 -04:00
Maarten Billemont f27607e63c fixup! Support for unset login type. 2021-11-01 20:52:04 -04:00
Maarten Billemont 0b45dc584f Fix deadlock when loadStore posts notifications to the main thread. 2021-11-01 20:07:13 -04:00
Maarten Billemont 88a4d7ba4d Support for unset login type. 2021-11-01 20:06:37 -04:00
Maarten Billemont 94a6c925bc Update Sentry SDK. 2021-10-31 14:32:31 -04:00
Maarten Billemont eda9749cf2 Time to crack script updates.
[ADDED]     Calculate cost for cracking a password.
[UPDATED]   Hardware cost data based on various GPUs with updated hashcat metrics.
[ADDED]     Ability to calculate the strength of an arbitrary password.
2021-10-31 14:17:21 -04:00
Maarten Billemont 4c096555d0 Spectre migration updates.
[ADDED]     Migration prompt to sign-in screen.
[FIXED]     Spectre Apple ID.
2021-10-31 14:15:46 -04:00
Maarten Billemont 403c45519a 2.7-java-12 2021-03-02 19:33:53 -05:00
Maarten Billemont 8d33ff8ec5 Fix password field manipulation bugs.
[FIXED]     By stubbing the password field's document, we broke some editing capabilities. Stub the document in a way that respects its length.
2021-03-02 19:31:47 -05:00
Maarten Billemont c38f713f05 Update site after release. 2021-02-18 11:27:18 -05:00
Maarten Billemont d59595824b Fix path for C release VERSION and TAG. 2021-02-18 10:15:40 -05:00
Maarten Billemont 2b78449a48 Update site after release. 2021-02-18 09:58:10 -05:00
18 changed files with 348 additions and 252 deletions

View File

@ -16,7 +16,7 @@ buildscript {
allprojects {
group = 'com.lyndir.masterpassword'
version = '2.7.11'
version = '2.7.12'
}
subprojects {

View File

@ -146,10 +146,10 @@ static NSOperationQueue *_mpwQueue = nil;
- (NSString *)nameOfType:(MPResultType)type {
if (!type)
return nil;
switch (type) {
case MPResultTypeNone:
return @"None";
case MPResultTypeTemplateMaximum:
return @"Maximum Security Password";
@ -189,10 +189,10 @@ static NSOperationQueue *_mpwQueue = nil;
- (NSString *)shortNameOfType:(MPResultType)type {
if (!type)
return nil;
switch (type) {
case MPResultTypeNone:
return @"None";
case MPResultTypeTemplateMaximum:
return @"Maximum";
@ -237,9 +237,6 @@ static NSOperationQueue *_mpwQueue = nil;
- (Class)classOfType:(MPResultType)type {
if (!type)
Throw( @"No type given." );
switch (type) {
case MPResultTypeTemplateMaximum:
return [MPGeneratedSiteEntity class];
@ -271,6 +268,7 @@ static NSOperationQueue *_mpwQueue = nil;
case MPResultTypeStatefulDevice:
return [MPStoredSiteEntity class];
case MPResultTypeNone:
case MPResultTypeDeriveKey:
break;
}
@ -322,6 +320,7 @@ static NSOperationQueue *_mpwQueue = nil;
return MPResultTypeStatefulDevice;
case MPResultTypeStatefulDevice:
return MPResultTypeTemplatePhrase;
case MPResultTypeNone:
case MPResultTypeDeriveKey:
break;
}
@ -531,8 +530,13 @@ static NSOperationQueue *_mpwQueue = nil;
return;
}
case MPResultTypeDeriveKey:
case MPResultTypeNone:
case MPResultTypeDeriveKey: {
PearlNotMainQueue( ^{
resultBlock( nil );
} );
return;
}
}
Throw( @"Type not supported: %lu", (long)type );

View File

@ -43,7 +43,7 @@ __END_DECLS
\
if (__error && [[MPConfig get].sendInfo boolValue]) { \
SentryEvent *event = [[SentryEvent alloc] initWithLevel:kSentryLevelError]; \
event.message = strf( message_ @": %@", ##__VA_ARGS__, [__error localizedDescription]); \
event.message = [[SentryMessage alloc] initWithFormatted:strf( message_ @": %@", ##__VA_ARGS__, [__error localizedDescription])]; \
event.logger = @"MPError"; \
event.fingerprint = @[ message_, __error.domain, @(__error.code) ]; \
[SentrySDK captureEvent:event]; \

View File

@ -124,7 +124,7 @@
switch (self.mode) {
case MPCombinedModeUserSelection: {
self.usersVC.view.userInteractionEnabled = YES;
self.usersVC.userSelectionContainer.userInteractionEnabled = YES;
[self.usersVC setActive:YES animated:animated];
if (self.sitesVC) {
MPSitesSegue *segue = [[MPSitesSegue alloc] initWithIdentifier:@"passwords" source:self.sitesVC destination:self];
@ -134,7 +134,7 @@
break;
}
case MPCombinedModePasswordSelection: {
self.usersVC.view.userInteractionEnabled = NO;
self.usersVC.userSelectionContainer.userInteractionEnabled = NO;
[self.usersVC setActive:NO animated:animated];
[self performSegueWithIdentifier:@"passwords" sender:@{ @"animated": @(animated) }];
break;

View File

@ -30,8 +30,6 @@
@property(nonatomic, strong) IBOutlet UIView *badNameTipContainer;
@property(nonatomic, strong) IBOutlet UIView *popdownView;
@property(nonatomic, strong) IBOutlet UIView *popdownContainer;
@property(nonatomic, strong) IBOutlet UIView *spectreInstallAlert;
@property(nonatomic, strong) IBOutlet UIView *spectreMigrateAlert;
@property(assign, nonatomic) BOOL active;
@ -39,6 +37,5 @@
- (void)reloadSites;
- (IBAction)dismissPopdown:(id)sender;
- (IBAction)upgradeSpectre:(UIButton *)sender;
@end

View File

@ -74,7 +74,6 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
[self registerObservers];
[self updateConfigKey:nil];
[self updateSpectreAlerts];
static NSRegularExpression *bareHostRE = nil;
static dispatch_once_t once = 0;
@ -318,7 +317,6 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
PearlAddNotificationObserver( UIApplicationWillEnterForegroundNotification, nil, [NSOperationQueue mainQueue],
^(MPSitesViewController *self, NSNotification *note) {
[self viewWillAppear:YES];
[self updateSpectreAlerts];
} );
PearlAddNotificationObserver( MPSignedOutNotification, nil, nil,
^(MPSitesViewController *self, NSNotification *note) {
@ -466,24 +464,4 @@ typedef NS_OPTIONS( NSUInteger, MPPasswordsTips ) {
self.popdownToTopConstraint.priority = UILayoutPriorityDefaultHigh;
}
- (IBAction)upgradeSpectre:(UIButton *)sender {
[[MPiOSAppDelegate get] migrateFor:[MPiOSAppDelegate get].activeUserForMainThread];
}
#pragma mark - Private
- (void)updateSpectreAlerts {
BOOL spectreInstalled = [UIApp canOpenURL:[[NSURL alloc] initWithString:@"spectre:"]];
if (spectreInstalled) {
self.spectreInstallAlert.visible = NO;
self.spectreMigrateAlert.visible = YES;
}
else {
self.spectreInstallAlert.visible = [MPiOSAppDelegate get].spectreViewController != nil;
self.spectreMigrateAlert.visible = NO;
}
}
@end

View File

@ -35,10 +35,14 @@
@property(weak, nonatomic) IBOutlet UIButton *nextAvatarButton;
@property(weak, nonatomic) IBOutlet UIButton *previousAvatarButton;
@property(weak, nonatomic) IBOutlet NSLayoutConstraint *keyboardHeightConstraint;
@property(weak, nonatomic) IBOutlet UIView *spectreInstallAlert;
@property(weak, nonatomic) IBOutlet UIView *spectreMigrateAlert;
@property(assign, nonatomic, readonly) BOOL active;
- (void)setActive:(BOOL)active animated:(BOOL)animated;
- (IBAction)changeAvatar:(UIButton *)sender;
- (IBAction)upgradeSpectre:(UIButton *)sender;
- (IBAction)dismissSpectre:(UIButton *)sender;
@end

View File

@ -100,6 +100,7 @@ typedef NS_ENUM( NSUInteger, MPActiveUserState ) {
[self registerObservers];
[self reloadUsers];
[self updateSpectreAlerts];
[self.marqueeTipTimer invalidate];
self.marqueeTipTimer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector( firedMarqueeTimer: )
@ -660,6 +661,7 @@ referenceSizeForFooterInSection:(NSInteger)section {
PearlAddNotificationObserver( UIApplicationWillEnterForegroundNotification, nil, [NSOperationQueue mainQueue],
^(MPUsersViewController *self, NSNotification *note) {
[self reloadUsers];
[self updateSpectreAlerts];
} );
PearlAddNotificationObserver( UIApplicationDidBecomeActiveNotification, nil, [NSOperationQueue mainQueue],
^(MPUsersViewController *self, NSNotification *note) {
@ -726,6 +728,19 @@ referenceSizeForFooterInSection:(NSInteger)section {
}];
}
- (void)updateSpectreAlerts {
BOOL spectreInstalled = [UIApp canOpenURL:[[NSURL alloc] initWithString:@"spectre:"]];
if (spectreInstalled) {
self.spectreInstallAlert.visible = NO;
self.spectreMigrateAlert.visible = YES;
}
else {
self.spectreInstallAlert.visible = [MPiOSAppDelegate get].spectreViewController != nil;
self.spectreMigrateAlert.visible = NO;
}
}
#pragma mark - NSFetchedResultsControllerDelegate
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
@ -907,4 +922,15 @@ referenceSizeForFooterInSection:(NSInteger)section {
++[self selectedAvatar].avatar;
}
- (IBAction)upgradeSpectre:(UIButton *)sender {
[[MPiOSAppDelegate get] migrateFor:[MPiOSAppDelegate get].activeUserForMainThread];
}
- (IBAction)dismissSpectre:(UIButton *)sender {
self.spectreInstallAlert.visible = NO;
self.spectreMigrateAlert.visible = NO;
}
@end

View File

@ -60,22 +60,6 @@ MP_LIBS_END
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
@try {
// Sentry
[SentrySDK startWithOptions:@{
@"dsn" : NilToNSNull( decrypt( sentryDSN ) ),
#ifdef DEBUG
@"debug" : @(NO), //@(YES),
@"environment" : @"Development",
#elif PUBLIC
@"debug" : @(NO),
@"environment" : @"Public",
#else
@"debug" : @(NO),
@"environment" : @"Private",
#endif
@"enabled" : @([[MPiOSConfig get].sendInfo boolValue] || ![[MPiOSConfig get].sendInfoDecided boolValue]),
@"enableAutoSessionTracking": @(YES),
}];
[[PearlLogger get] registerListener:^BOOL(PearlLogMessage *message) {
PearlLogLevel level = PearlLogLevelWarn;
if ([[MPConfig get].sendInfo boolValue])
@ -148,7 +132,9 @@ MP_LIBS_END
[self updateConfigKey:note.object];
} );
PearlAddNotificationObserver( NSUserDefaultsDidChangeNotification, nil, nil, ^(id self, NSNotification *note) {
[[NSNotificationCenter defaultCenter] postNotificationName:MPCheckConfigNotification object:nil];
PearlMainQueueOperation( ^{
[[NSNotificationCenter defaultCenter] postNotificationName:MPCheckConfigNotification object:nil];
} );
} );
}
@catch (id exception) {
@ -189,7 +175,7 @@ MP_LIBS_END
SKStoreProductParameterCampaignToken : @"app-masterpassword.ios", /* Campaign: From MasterPassword iOS */
SKStoreProductParameterProviderToken : @153897, /* Provider: Maarten Billemont */
// SKStoreProductParameterITunesItemIdentifier: @510296984, /* Application: MasterPassword iOS */
SKStoreProductParameterITunesItemIdentifier: @1500430196, /* Application: Spectre iOS */
SKStoreProductParameterITunesItemIdentifier: @1526402806, /* Application: Spectre iOS */
} completionBlock:^(BOOL result, NSError *error) {
if (error)
err( @"Failed loading Spectre product information: %@", error );
@ -834,7 +820,23 @@ MP_LIBS_END
if ([PearlLogger get].printLevel > PearlLogLevelInfo)
[PearlLogger get].printLevel = PearlLogLevelInfo;
[SentrySDK.currentHub getClient].options.enabled = @YES;
// Sentry
if (!SentrySDK.isEnabled)
[SentrySDK startWithOptions:@{
@"dsn" : NilToNSNull( decrypt( sentryDSN ) ),
#ifdef DEBUG
@"debug" : @(NO), //@(YES),
@"environment" : @"Development",
#elif PUBLIC
@"debug" : @(NO),
@"environment" : @"Public",
#else
@"debug" : @(NO),
@"environment" : @"Private",
#endif
@"enableAutoSessionTracking": @(YES),
}];
[SentrySDK configureScope:^(SentryScope *scope) {
[scope setExtraValue:[MPiOSConfig get].rememberLogin forKey:@"rememberLogin"];
[scope setExtraValue:[MPiOSConfig get].sendInfo forKey:@"sendInfo"];
@ -859,7 +861,7 @@ MP_LIBS_END
}
else {
[Countly.sharedInstance cancelConsentForFeatures:countlyFeatures];
[SentrySDK.currentHub getClient].options.enabled = @NO;
[SentrySDK close];
}
}

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17154" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES" initialViewController="Q1S-vU-GGO">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19162" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES" initialViewController="Q1S-vU-GGO">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17124"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19144"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<customFonts key="customFonts">
@ -69,7 +69,7 @@
</collectionViewFlowLayout>
<cells>
<collectionViewCell opaque="NO" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="MPAvatarCell" id="Zab-uQ-uk9" customClass="MPAvatarCell">
<rect key="frame" x="80" y="114.5" width="215" height="667"/>
<rect key="frame" x="80" y="115" width="215" height="667"/>
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="215" height="667"/>
@ -410,21 +410,112 @@
<constraint firstItem="9u7-pu-Wtv" firstAttribute="leading" secondItem="rWM-08-aab" secondAttribute="leading" id="sez-BC-G3I"/>
</constraints>
</view>
<view opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tOT-TZ-yse" userLabel="Install Spectre Tip">
<rect key="frame" x="0.0" y="740" width="414" height="156"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ded-Ii-gyf" userLabel="Migrate">
<rect key="frame" x="8" y="8" width="398" height="106"/>
<state key="normal" backgroundImage="tip_alert_black"/>
<connections>
<action selector="upgradeSpectre:" destination="S8q-YF-Kt9" eventType="touchUpInside" id="Mmn-CK-C45"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bqa-qH-Bia">
<rect key="frame" x="80" y="15" width="267" height="84"/>
<string key="text">The next generation of password security is now called «Spectre»:
Tap to install the upgrade.
This app is now out of maintenance.</string>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" horizontalCompressionResistancePriority="751" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="tDY-IR-ak2" userLabel="Close">
<rect key="frame" x="347" y="20" width="47" height="31"/>
<buttonConfiguration key="configuration" style="plain" title=""/>
<connections>
<action selector="dismissSpectre:" destination="S8q-YF-Kt9" eventType="touchUpInside" id="7a6-W3-NIK"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="ded-Ii-gyf" firstAttribute="leading" secondItem="tOT-TZ-yse" secondAttribute="leadingMargin" id="3fy-Qc-KlM"/>
<constraint firstItem="bqa-qH-Bia" firstAttribute="top" secondItem="ded-Ii-gyf" secondAttribute="top" constant="7" id="8Rd-qC-ttx"/>
<constraint firstItem="bqa-qH-Bia" firstAttribute="bottom" secondItem="ded-Ii-gyf" secondAttribute="bottom" constant="-15" id="VLO-QZ-6Jf"/>
<constraint firstItem="ded-Ii-gyf" firstAttribute="top" secondItem="tOT-TZ-yse" secondAttribute="topMargin" id="Y6k-Ep-Skv"/>
<constraint firstAttribute="trailingMargin" secondItem="ded-Ii-gyf" secondAttribute="trailing" id="d8e-pL-U3v"/>
<constraint firstAttribute="trailing" secondItem="tDY-IR-ak2" secondAttribute="trailing" constant="20" symbolic="YES" id="lb2-4g-zJV"/>
<constraint firstItem="bqa-qH-Bia" firstAttribute="leading" secondItem="ded-Ii-gyf" secondAttribute="leading" constant="72" id="nD7-ie-dHF"/>
<constraint firstItem="tDY-IR-ak2" firstAttribute="top" secondItem="tOT-TZ-yse" secondAttribute="top" constant="20" symbolic="YES" id="pDc-SL-x9W"/>
<constraint firstItem="tDY-IR-ak2" firstAttribute="leading" secondItem="bqa-qH-Bia" secondAttribute="trailing" id="suM-kx-xRY"/>
<constraint firstAttribute="bottomMargin" secondItem="ded-Ii-gyf" secondAttribute="bottom" id="xzD-vT-p1O"/>
</constraints>
</view>
<view opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="e7i-8u-nyd" userLabel="Migrate Spectre Tip">
<rect key="frame" x="0.0" y="740" width="414" height="156"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4s3-Ex-jpT" userLabel="Migrate">
<rect key="frame" x="8" y="8" width="398" height="106"/>
<state key="normal" backgroundImage="tip_alert_black"/>
<connections>
<action selector="upgradeSpectre:" destination="S8q-YF-Kt9" eventType="touchUpInside" id="059-Sa-0EF"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bWt-lb-7xL">
<rect key="frame" x="80" y="15" width="267" height="84"/>
<string key="text">The next generation of password security is now called «Spectre»:
Tap to copy your user into Spectre.
This app is now out of maintenance.</string>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" horizontalCompressionResistancePriority="751" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="3WO-6r-WEn" userLabel="Close">
<rect key="frame" x="347" y="20" width="47" height="31"/>
<buttonConfiguration key="configuration" style="plain" title=""/>
<connections>
<action selector="dismissSpectre:" destination="S8q-YF-Kt9" eventType="touchUpInside" id="aEC-nX-WeV"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="3WO-6r-WEn" firstAttribute="leading" secondItem="bWt-lb-7xL" secondAttribute="trailing" id="49f-Eg-XMb"/>
<constraint firstItem="bWt-lb-7xL" firstAttribute="leading" secondItem="4s3-Ex-jpT" secondAttribute="leading" constant="72" id="4rw-uH-p06"/>
<constraint firstItem="3WO-6r-WEn" firstAttribute="top" secondItem="e7i-8u-nyd" secondAttribute="top" constant="20" id="50L-TI-WJ8"/>
<constraint firstItem="bWt-lb-7xL" firstAttribute="top" secondItem="4s3-Ex-jpT" secondAttribute="top" constant="7" id="AwO-Pj-Wnr"/>
<constraint firstAttribute="bottomMargin" secondItem="4s3-Ex-jpT" secondAttribute="bottom" id="LWF-xQ-l5k"/>
<constraint firstItem="4s3-Ex-jpT" firstAttribute="leading" secondItem="e7i-8u-nyd" secondAttribute="leadingMargin" id="OKe-0I-vdR"/>
<constraint firstItem="4s3-Ex-jpT" firstAttribute="top" secondItem="e7i-8u-nyd" secondAttribute="topMargin" id="TRy-eS-Ch4"/>
<constraint firstAttribute="trailing" secondItem="3WO-6r-WEn" secondAttribute="trailing" constant="20" id="aPO-KL-k9X"/>
<constraint firstItem="bWt-lb-7xL" firstAttribute="bottom" secondItem="4s3-Ex-jpT" secondAttribute="bottom" constant="-15" id="cYX-vL-MKX"/>
<constraint firstAttribute="trailingMargin" secondItem="4s3-Ex-jpT" secondAttribute="trailing" id="lRd-Hq-SH2"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" red="0.1215686275" green="0.12941176469999999" blue="0.14117647059999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="VGz-R0-vMD" firstAttribute="top" secondItem="X8H-vh-j7B" secondAttribute="bottom" id="8Ed-3Y-ll0"/>
<constraint firstAttribute="trailing" secondItem="X8H-vh-j7B" secondAttribute="trailing" id="8Gr-Dq-UpZ"/>
<constraint firstAttribute="bottom" secondItem="rWM-08-aab" secondAttribute="bottom" id="9Yx-cj-wHh"/>
<constraint firstItem="tOT-TZ-yse" firstAttribute="leading" secondItem="DOr-Xu-P9q" secondAttribute="leading" id="CKQ-85-U4k"/>
<constraint firstAttribute="bottom" secondItem="e7i-8u-nyd" secondAttribute="bottom" id="G00-FW-tqE"/>
<constraint firstItem="X8H-vh-j7B" firstAttribute="top" secondItem="9u7-pu-Wtv" secondAttribute="centerY" priority="500" constant="180" id="Gp5-h6-53S"/>
<constraint firstItem="rWM-08-aab" firstAttribute="leading" secondItem="DOr-Xu-P9q" secondAttribute="leading" id="Il8-kg-Dra"/>
<constraint firstItem="X8H-vh-j7B" firstAttribute="top" secondItem="fUK-gJ-NRE" secondAttribute="centerY" priority="500" constant="180" id="PgC-ZL-cQo"/>
<constraint firstAttribute="trailing" secondItem="rWM-08-aab" secondAttribute="trailing" id="UPP-1n-zIe"/>
<constraint firstItem="X8H-vh-j7B" firstAttribute="top" secondItem="qp1-nX-o4i" secondAttribute="bottom" constant="20" id="WdK-tA-njz"/>
<constraint firstItem="e7i-8u-nyd" firstAttribute="leading" secondItem="DOr-Xu-P9q" secondAttribute="leading" id="au3-Bw-ioi"/>
<constraint firstItem="X8H-vh-j7B" firstAttribute="leading" secondItem="DOr-Xu-P9q" secondAttribute="leading" id="jbn-ko-MPq"/>
<constraint firstAttribute="trailing" secondItem="e7i-8u-nyd" secondAttribute="trailing" id="l3l-d3-Y68"/>
<constraint firstItem="zCP-wo-gTl" firstAttribute="top" secondItem="zp4-4O-wZI" secondAttribute="bottom" id="nAS-Jf-o5m"/>
<constraint firstAttribute="bottom" secondItem="tOT-TZ-yse" secondAttribute="bottom" id="oNx-xq-124"/>
<constraint firstAttribute="trailing" secondItem="tOT-TZ-yse" secondAttribute="trailing" id="wI5-eh-S2b"/>
<constraint firstAttribute="top" secondItem="rWM-08-aab" secondAttribute="top" id="xBe-1Q-mz2"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="ignoreTouches" value="YES"/>
</userDefinedRuntimeAttributes>
</view>
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="lightContent"/>
<connections>
@ -442,6 +533,8 @@
<outlet property="nextAvatarButton" destination="fUK-gJ-NRE" id="5qo-lK-rSa"/>
<outlet property="preferencesTipContainer" destination="0Um-Ot-hI6" id="Cv8-Bp-ZZs"/>
<outlet property="previousAvatarButton" destination="9u7-pu-Wtv" id="Hgv-lN-S1n"/>
<outlet property="spectreInstallAlert" destination="tOT-TZ-yse" id="2hk-xb-psR"/>
<outlet property="spectreMigrateAlert" destination="e7i-8u-nyd" id="6oI-L9-VgE"/>
<outlet property="storeLoadingActivity" destination="VDd-oM-ZOO" id="MJ7-2f-e8n"/>
<outlet property="thanksTipContainer" destination="069-Pu-yXe" id="wWf-2X-Ryw"/>
<outlet property="userSelectionContainer" destination="rWM-08-aab" id="Yme-hX-8P0"/>
@ -449,7 +542,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="8hZ-Tb-wZw" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2041" y="226"/>
<point key="canvasLocation" x="2040.5797101449277" y="225.66964285714283"/>
</scene>
<!--Web View Controller-->
<scene sceneID="JQz-u7-oA7">
@ -624,20 +717,20 @@
<tableViewSection id="FEv-Rb-jst">
<cells>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="eth-Dc-JYn" userLabel="Show Help">
<rect key="frame" x="0.0" y="28" width="414" height="250"/>
<rect key="frame" x="0.0" y="44.5" width="414" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="eth-Dc-JYn" id="8m6-pP-lda">
<rect key="frame" x="0.0" y="0.0" width="383" height="250"/>
<rect key="frame" x="0.0" y="0.0" width="384.5" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Show Help" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="x9b-Qa-Pza">
<rect key="frame" x="20" y="20" width="343" height="20"/>
<rect key="frame" x="20" y="20" width="344.5" height="20"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" text="Open the short step-by-step guide which explains how to use Master Password." lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bKz-o1-gHv">
<rect key="frame" x="20" y="48" width="343" height="182"/>
<rect key="frame" x="20" y="48" width="344.5" height="182"/>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@ -656,20 +749,20 @@
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="R30-AU-bR6" userLabel="Sign Out">
<rect key="frame" x="0.0" y="278" width="414" height="250"/>
<rect key="frame" x="0.0" y="294.5" width="414" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="R30-AU-bR6" id="f6h-Ff-2Qc">
<rect key="frame" x="0.0" y="0.0" width="383" height="250"/>
<rect key="frame" x="0.0" y="0.0" width="384.5" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Sign Out" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nr5-ze-6PW">
<rect key="frame" x="20" y="20" width="343" height="20"/>
<rect key="frame" x="20" y="20" width="344.5" height="20"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" text="Log yourself out and return to the user selection screen." lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0G1-cX-MT3">
<rect key="frame" x="20" y="48" width="343" height="182"/>
<rect key="frame" x="20" y="48" width="344.5" height="182"/>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@ -688,7 +781,7 @@
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="B8R-iE-Ffe" userLabel="Default Password Type">
<rect key="frame" x="0.0" y="528" width="414" height="250"/>
<rect key="frame" x="0.0" y="544.5" width="414" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="B8R-iE-Ffe" id="8r5-Zc-TRj">
<rect key="frame" x="0.0" y="0.0" width="414" height="250"/>
@ -772,7 +865,7 @@
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="Sz1-JP-dw2" userLabel="Avatar">
<rect key="frame" x="0.0" y="778" width="414" height="250"/>
<rect key="frame" x="0.0" y="794.5" width="414" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Sz1-JP-dw2" id="R4X-LE-ir9">
<rect key="frame" x="0.0" y="0.0" width="414" height="250"/>
@ -847,25 +940,25 @@
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="fRZ-Uh-FR8" userLabel="Save Password">
<rect key="frame" x="0.0" y="1028" width="414" height="250"/>
<rect key="frame" x="0.0" y="1044.5" width="414" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="fRZ-Uh-FR8" id="qCQ-L5-teL">
<rect key="frame" x="0.0" y="0.0" width="414" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" verticalCompressionResistancePriority="751" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Jr5-mX-nw0">
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" verticalCompressionResistancePriority="751" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Jr5-mX-nw0">
<rect key="frame" x="182.5" y="199" width="51" height="31"/>
<connections>
<action selector="valueChanged:" destination="JFc-sj-awD" eventType="valueChanged" id="KMj-5x-BcK"/>
</connections>
</switch>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Save Password" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3fk-Io-xQI">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" ambiguous="YES" text="Save Password" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3fk-Io-xQI">
<rect key="frame" x="20" y="20" width="374" height="20"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Z1N-JR-4fr">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" ambiguous="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Z1N-JR-4fr">
<rect key="frame" x="20" y="48" width="374" height="143"/>
<string key="text">This will store your master password in your device's keychain. As a result, you'll be able to log in without entering your master password. This is somewhat less secure in the event of theft: anyone who figures out your device's PIN can get in. You can compensate for the reduced security by setting a more secure passcode for your device (in Settings, go to: General-&gt;Passcode Lock, disable "Simple Passcode") or by purchasing and enabling support for TouchID.</string>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
@ -888,25 +981,25 @@
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="bKn-6f-TKE" userLabel="TouchID">
<rect key="frame" x="0.0" y="1278" width="414" height="250"/>
<rect key="frame" x="0.0" y="1294.5" width="414" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="bKn-6f-TKE" id="GBL-TP-VnH">
<rect key="frame" x="0.0" y="0.0" width="414" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" verticalCompressionResistancePriority="751" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wOM-X3-jCG">
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" verticalCompressionResistancePriority="751" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="wOM-X3-jCG">
<rect key="frame" x="182.5" y="199" width="51" height="31"/>
<connections>
<action selector="valueChanged:" destination="JFc-sj-awD" eventType="valueChanged" id="KmT-CO-GZh"/>
</connections>
</switch>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Biometrics" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6xf-vt-aXd">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" ambiguous="YES" text="Biometrics" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6xf-vt-aXd">
<rect key="frame" x="20" y="20" width="374" height="20"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="URR-yZ-QuC">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" ambiguous="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="URR-yZ-QuC">
<rect key="frame" x="20" y="48" width="374" height="143"/>
<string key="text">When enabled on a biometrics-enabled device, your fingerprint or face scan will be required to load your stored master password.
Note that this feature requires you enable the Save Password option and have purchased Biometrics support from the in-app store.</string>
@ -930,19 +1023,19 @@ Note that this feature requires you enable the Save Password option and have pur
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="9QG-lM-ymM" userLabel="Feedback">
<rect key="frame" x="0.0" y="1528" width="414" height="250"/>
<rect key="frame" x="0.0" y="1544.5" width="414" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="9QG-lM-ymM" id="hK8-XQ-lLz">
<rect key="frame" x="0.0" y="0.0" width="383" height="250"/>
<rect key="frame" x="0.0" y="0.0" width="396.5" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Feedback" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5zr-Nr-zRb">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" ambiguous="YES" text="Feedback" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5zr-Nr-zRb">
<rect key="frame" x="20" y="20" width="343" height="20"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" text="Contact me if you have a question, idea, praise or issue. Try to be as detailed as possible." lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8dg-Ew-Vy1">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" ambiguous="YES" text="Contact me if you have a question, idea, praise or issue. Try to be as detailed as possible." lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8dg-Ew-Vy1">
<rect key="frame" x="20" y="48" width="343" height="182"/>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -962,19 +1055,19 @@ Note that this feature requires you enable the Save Password option and have pur
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="UdB-BV-AHA" userLabel="Check Inconsistencies">
<rect key="frame" x="0.0" y="1778" width="414" height="250"/>
<rect key="frame" x="0.0" y="1794.5" width="414" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="UdB-BV-AHA" id="V2Y-nu-jhZ">
<rect key="frame" x="0.0" y="0.0" width="383" height="250"/>
<rect key="frame" x="0.0" y="0.0" width="396.5" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Check For Inconsistencies" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WXh-sg-l2h">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" ambiguous="YES" text="Check For Inconsistencies" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WXh-sg-l2h">
<rect key="frame" x="20" y="20" width="343" height="20"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" text="Perform a check to see if there are any inconsistencies in your site data that might cause issues." lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gTs-JA-zmL">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" ambiguous="YES" text="Perform a check to see if there are any inconsistencies in your site data that might cause issues." lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="gTs-JA-zmL">
<rect key="frame" x="20" y="48" width="343" height="182"/>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
@ -994,19 +1087,19 @@ Note that this feature requires you enable the Save Password option and have pur
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="IVT-Rs-nTu" userLabel="Export">
<rect key="frame" x="0.0" y="2028" width="414" height="250"/>
<rect key="frame" x="0.0" y="2044.5" width="414" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="IVT-Rs-nTu" id="Q5J-2f-mmz">
<rect key="frame" x="0.0" y="0.0" width="383" height="250"/>
<rect key="frame" x="0.0" y="0.0" width="396.5" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Export" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KEh-y5-Obc">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" ambiguous="YES" text="Export" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="KEh-y5-Obc">
<rect key="frame" x="20" y="20" width="343" height="20"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="U77-XF-Bvb">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" ambiguous="YES" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="U77-XF-Bvb">
<rect key="frame" x="20" y="48" width="343" height="182"/>
<string key="text">An export saves all your sites and optionally their passwords to a file that you can store separately. It can function as a back-up or a way to move all your sites to a new device.</string>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
@ -1027,19 +1120,19 @@ Note that this feature requires you enable the Save Password option and have pur
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" id="hmf-Wz-9l2" userLabel="Footer">
<rect key="frame" x="0.0" y="2278" width="414" height="250"/>
<rect key="frame" x="0.0" y="2294.5" width="414" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="hmf-Wz-9l2" id="AL3-2q-tgO">
<rect key="frame" x="0.0" y="0.0" width="414" height="250"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="999" verticalCompressionResistancePriority="1000" text="© 2011-2020, Maarten Billemont (lhunath)" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sPw-mV-mFF">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999999999999996" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="999" verticalCompressionResistancePriority="1000" ambiguous="YES" text="© 2011-2020, Maarten Billemont (lhunath)" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sPw-mV-mFF">
<rect key="frame" x="20" y="4" width="374" height="106"/>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rl7-cr-FHf">
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rl7-cr-FHf">
<rect key="frame" x="20" y="118" width="374" height="27"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="12"/>
<state key="normal" title="Home Page">
@ -1049,7 +1142,7 @@ Note that this feature requires you enable the Save Password option and have pur
<action selector="homePageButton:" destination="JFc-sj-awD" eventType="touchUpInside" id="ptD-cv-NMr"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="epW-Rm-9St">
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="epW-Rm-9St">
<rect key="frame" x="20" y="153" width="374" height="27"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="12"/>
<state key="normal" title="Understanding Master Password's Security">
@ -1059,7 +1152,7 @@ Note that this feature requires you enable the Save Password option and have pur
<action selector="securityButton:" destination="JFc-sj-awD" eventType="touchUpInside" id="Efv-cp-Xfh"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LTN-ch-h8D">
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LTN-ch-h8D">
<rect key="frame" x="20" y="188" width="374" height="27"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="12"/>
<state key="normal" title="Get the Master Password source code">
@ -1069,7 +1162,7 @@ Note that this feature requires you enable the Save Password option and have pur
<action selector="sourceButton:" destination="JFc-sj-awD" eventType="touchUpInside" id="Y3O-di-CZo"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Z60-lc-Nka">
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="1000" verticalCompressionResistancePriority="1000" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Z60-lc-Nka">
<rect key="frame" x="20" y="223" width="374" height="27"/>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
<state key="normal" title="Send Thanks">
@ -1594,9 +1687,9 @@ Note that this feature requires you enable the Save Password option and have pur
</constraints>
</view>
<visualEffectView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cHF-cD-2Ge">
<rect key="frame" x="0.0" y="0.0" width="414" height="144"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="139"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="CkH-CQ-k0G">
<rect key="frame" x="0.0" y="0.0" width="414" height="144"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="139"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<navigationBar hidden="YES" opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" barStyle="black" translatesAutoresizingMaskIntoConstraints="NO" id="uuT-jm-2La" userLabel="Navigation" customClass="PearlUINavigationBar">
@ -1616,14 +1709,14 @@ Note that this feature requires you enable the Save Password option and have pur
</connections>
</button>
<searchBar contentMode="redraw" barStyle="black" searchBarStyle="minimal" placeholder="eg. apple.com" translatesAutoresizingMaskIntoConstraints="NO" id="aGs-1S-aC3">
<rect key="frame" x="0.0" y="88" width="414" height="56"/>
<rect key="frame" x="0.0" y="88" width="414" height="51"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" spellCheckingType="no" keyboardType="URL"/>
<connections>
<outlet property="delegate" destination="nkY-z6-8jd" id="ENG-q5-XwX"/>
</connections>
</searchBar>
<view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LEX-BK-PdS" userLabel="Bad Name Tip">
<rect key="frame" x="57" y="116" width="300.5" height="75.5"/>
<rect key="frame" x="57" y="113.5" width="300.5" height="75.5"/>
<subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" image="tip_basic_black_top.png" translatesAutoresizingMaskIntoConstraints="NO" id="Rt5-v4-I0R">
<rect key="frame" x="0.0" y="0.0" width="300.5" height="75.5"/>
@ -1672,70 +1765,6 @@ eg. apple.com, rmitchell@twitter.com</string>
</view>
<blurEffect style="regular"/>
</visualEffectView>
<view opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3ve-eR-1IW">
<rect key="frame" x="0.0" y="740" width="414" height="156"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="PWC-I5-RSl">
<rect key="frame" x="8" y="8" width="398" height="106"/>
<state key="normal" backgroundImage="tip_alert_black"/>
<connections>
<action selector="upgradeSpectre:" destination="nkY-z6-8jd" eventType="touchUpInside" id="8KJ-vm-3D0"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XgC-Ky-oVC">
<rect key="frame" x="80" y="15" width="315" height="84"/>
<string key="text">The next generation of password security is now called «Spectre»:
Tap to install the upgrade.
This app is now out of maintenance.</string>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="PWC-I5-RSl" firstAttribute="top" secondItem="3ve-eR-1IW" secondAttribute="topMargin" id="0gi-j6-mfg"/>
<constraint firstItem="XgC-Ky-oVC" firstAttribute="leading" secondItem="PWC-I5-RSl" secondAttribute="leading" constant="72" id="E88-An-rzp"/>
<constraint firstAttribute="bottomMargin" secondItem="PWC-I5-RSl" secondAttribute="bottom" id="FrN-5c-k1V"/>
<constraint firstItem="XgC-Ky-oVC" firstAttribute="trailing" secondItem="PWC-I5-RSl" secondAttribute="trailing" constant="-11" id="Scl-zE-fTg"/>
<constraint firstAttribute="trailingMargin" secondItem="PWC-I5-RSl" secondAttribute="trailing" id="gwp-DL-I06"/>
<constraint firstItem="XgC-Ky-oVC" firstAttribute="bottom" secondItem="PWC-I5-RSl" secondAttribute="bottom" constant="-15" id="hFa-k3-yr9"/>
<constraint firstItem="PWC-I5-RSl" firstAttribute="leading" secondItem="3ve-eR-1IW" secondAttribute="leadingMargin" id="jod-TY-7Iu"/>
<constraint firstItem="XgC-Ky-oVC" firstAttribute="top" secondItem="PWC-I5-RSl" secondAttribute="top" constant="7" id="yjZ-x1-6JY"/>
</constraints>
</view>
<view opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="67c-5R-Foa">
<rect key="frame" x="0.0" y="740" width="414" height="156"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="EZK-er-8ql">
<rect key="frame" x="8" y="8" width="398" height="106"/>
<state key="normal" backgroundImage="tip_alert_black"/>
<connections>
<action selector="upgradeSpectre:" destination="nkY-z6-8jd" eventType="touchUpInside" id="P4a-tL-9yX"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fLB-gA-32p">
<rect key="frame" x="80" y="15" width="315" height="84"/>
<string key="text">The next generation of password security is now called «Spectre»:
Tap to copy this user into Spectre.
This app is now out of maintenance.</string>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="14"/>
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="trailingMargin" secondItem="EZK-er-8ql" secondAttribute="trailing" id="2v6-0n-EXu"/>
<constraint firstItem="fLB-gA-32p" firstAttribute="bottom" secondItem="EZK-er-8ql" secondAttribute="bottom" constant="-15" id="KET-Ct-225"/>
<constraint firstAttribute="bottomMargin" secondItem="EZK-er-8ql" secondAttribute="bottom" id="LqJ-v9-IDf"/>
<constraint firstItem="fLB-gA-32p" firstAttribute="trailing" secondItem="EZK-er-8ql" secondAttribute="trailing" constant="-11" id="ivM-cA-Fn9"/>
<constraint firstItem="fLB-gA-32p" firstAttribute="leading" secondItem="EZK-er-8ql" secondAttribute="leading" constant="72" id="iwL-1a-Tgo"/>
<constraint firstItem="fLB-gA-32p" firstAttribute="top" secondItem="EZK-er-8ql" secondAttribute="top" constant="7" id="mHI-WQ-tMx"/>
<constraint firstItem="EZK-er-8ql" firstAttribute="top" secondItem="67c-5R-Foa" secondAttribute="topMargin" id="xMX-Iy-gkw"/>
<constraint firstItem="EZK-er-8ql" firstAttribute="leading" secondItem="67c-5R-Foa" secondAttribute="leadingMargin" id="ycd-o8-QVl"/>
</constraints>
</view>
<view opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XNM-XQ-rMe" userLabel="Popdown">
<rect key="frame" x="0.0" y="-896" width="414" height="896"/>
<subviews>
@ -1779,13 +1808,8 @@ This app is now out of maintenance.</string>
</subviews>
<color key="backgroundColor" red="0.1215686275" green="0.12941176469999999" blue="0.14117647059999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="67c-5R-Foa" secondAttribute="trailing" id="0mY-Tq-ZT4"/>
<constraint firstItem="cHF-cD-2Ge" firstAttribute="top" secondItem="XNM-XQ-rMe" secondAttribute="bottom" id="6V9-tX-50t"/>
<constraint firstAttribute="trailing" secondItem="3ve-eR-1IW" secondAttribute="trailing" id="7hd-C3-Akk"/>
<constraint firstAttribute="bottom" secondItem="67c-5R-Foa" secondAttribute="bottom" id="8xp-Si-tWG"/>
<constraint firstAttribute="top" secondItem="XNM-XQ-rMe" secondAttribute="bottom" priority="750" id="BdD-Kc-eHl"/>
<constraint firstItem="67c-5R-Foa" firstAttribute="leading" secondItem="tI8-OT-LrO" secondAttribute="leading" id="Ftn-Yi-mdI"/>
<constraint firstAttribute="bottom" secondItem="3ve-eR-1IW" secondAttribute="bottom" id="GOa-ky-jfJ"/>
<constraint firstItem="uuT-jm-2La" firstAttribute="bottom" secondItem="S9X-2T-e1e" secondAttribute="bottom" priority="500" constant="44" id="HAi-jL-BdJ"/>
<constraint firstAttribute="trailing" secondItem="K2e-Gh-7hH" secondAttribute="trailing" id="Hnk-mU-GSd"/>
<constraint firstAttribute="top" secondItem="cHF-cD-2Ge" secondAttribute="bottom" priority="1" id="JO5-ph-0ce"/>
@ -1797,7 +1821,6 @@ This app is now out of maintenance.</string>
<constraint firstItem="cHF-cD-2Ge" firstAttribute="leading" secondItem="tI8-OT-LrO" secondAttribute="leading" id="TJC-eP-DDE"/>
<constraint firstItem="uuT-jm-2La" firstAttribute="bottom" secondItem="VOY-zU-XQR" secondAttribute="bottom" id="U4C-1P-lIR"/>
<constraint firstItem="K2e-Gh-7hH" firstAttribute="height" secondItem="tI8-OT-LrO" secondAttribute="height" id="Xfe-XT-eOn"/>
<constraint firstItem="3ve-eR-1IW" firstAttribute="leading" secondItem="tI8-OT-LrO" secondAttribute="leading" id="bKZ-qF-SL5"/>
<constraint firstAttribute="trailing" secondItem="XNM-XQ-rMe" secondAttribute="trailing" id="bgl-u9-shU"/>
<constraint firstItem="K2e-Gh-7hH" firstAttribute="top" secondItem="tI8-OT-LrO" secondAttribute="bottom" priority="1" id="dNt-uf-8BC"/>
<constraint firstItem="K2e-Gh-7hH" firstAttribute="top" secondItem="tI8-OT-LrO" secondAttribute="top" priority="500" id="vtB-e4-L8o"/>
@ -1816,8 +1839,6 @@ This app is now out of maintenance.</string>
<outlet property="popdownView" destination="XNM-XQ-rMe" id="FaW-4m-Fff"/>
<outlet property="searchBar" destination="aGs-1S-aC3" id="rTp-DP-rIz"/>
<outlet property="sitesToBottomConstraint" destination="dNt-uf-8BC" id="Ta6-eL-z7w"/>
<outlet property="spectreInstallAlert" destination="3ve-eR-1IW" id="Ah5-OX-XhQ"/>
<outlet property="spectreMigrateAlert" destination="67c-5R-Foa" id="aTi-fu-opO"/>
<segue destination="z9O-w0-6oR" kind="modal" identifier="guide" id="Ql4-wf-T8u"/>
<segue destination="Foa-Er-RBr" kind="custom" identifier="message" customClass="MPOverlaySegue" id="Xne-Sm-HQt"/>
</connections>
@ -2147,10 +2168,10 @@ This app is now out of maintenance.</string>
</items>
</navigationBar>
<pageControl opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" numberOfPages="3" translatesAutoresizingMaskIntoConstraints="NO" id="8A2-ly-WTX">
<rect key="frame" x="141" y="778.5" width="132" height="29.5"/>
<rect key="frame" x="129.5" y="782" width="155.5" height="26"/>
</pageControl>
<collectionView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" minimumZoomScale="0.0" maximumZoomScale="0.0" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="i2y-lo-HXR">
<rect key="frame" x="0.0" y="44" width="414" height="644.5"/>
<rect key="frame" x="0.0" y="44" width="414" height="648"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
<collectionViewFlowLayout key="collectionViewLayout" scrollDirection="horizontal" minimumLineSpacing="0.0" minimumInteritemSpacing="0.0" id="m8O-kY-22j">
<size key="itemSize" width="320" height="458"/>
@ -2160,7 +2181,7 @@ This app is now out of maintenance.</string>
</collectionViewFlowLayout>
<cells>
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="MPGuideStepCell" id="oGu-pJ-3bQ" customClass="MPGuideStepCell">
<rect key="frame" x="0.0" y="93.5" width="320" height="458"/>
<rect key="frame" x="0.0" y="95" width="320" height="458"/>
<autoresizingMask key="autoresizingMask"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
<rect key="frame" x="0.0" y="0.0" width="320" height="458"/>
@ -2189,13 +2210,13 @@ This app is now out of maintenance.</string>
</connections>
</collectionView>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="To begin, tap the &quot;New User&quot; icon and add yourself as a user to the application." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ciw-56-nNy" userLabel="Caption">
<rect key="frame" x="8" y="696.5" width="398" height="82"/>
<rect key="frame" x="8" y="700" width="398" height="82"/>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="13"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<label hidden="YES" opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Oop-Ff-gbz" userLabel="Caption Height Strut">
<rect key="frame" x="8" y="696.5" width="1" height="82"/>
<rect key="frame" x="8" y="700" width="1" height="82"/>
<string key="text" base64-UTF8="YES">
CgoKCgoKCgoKCgoKCg
</string>
@ -2611,7 +2632,7 @@ See </string>
<color key="separatorColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<prototypes>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreProductCell" id="JVW-tG-xxe" userLabel="Product" customClass="MPStoreProductCell">
<rect key="frame" x="0.0" y="28" width="414" height="380"/>
<rect key="frame" x="0.0" y="44.5" width="414" height="380"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="JVW-tG-xxe" id="CLQ-CW-NGn">
<rect key="frame" x="0.0" y="0.0" width="414" height="380"/>
@ -2679,7 +2700,7 @@ See </string>
</connections>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreFuelProductCell" id="le3-Q5-MSO" userLabel="Fuel" customClass="MPStoreFuelProductCell">
<rect key="frame" x="0.0" y="408" width="414" height="380"/>
<rect key="frame" x="0.0" y="424.5" width="414" height="380"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="le3-Q5-MSO" id="SzQ-Y5-XIF">
<rect key="frame" x="0.0" y="0.0" width="414" height="380"/>
@ -2774,7 +2795,7 @@ Invested: 3.7 work hours</string>
</connections>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreCellSpinner" rowHeight="170" id="LOh-72-Ifp" userLabel="Spinner">
<rect key="frame" x="0.0" y="788" width="414" height="170"/>
<rect key="frame" x="0.0" y="804.5" width="414" height="170"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="LOh-72-Ifp" id="gjr-8l-JJ0">
<rect key="frame" x="0.0" y="0.0" width="414" height="170"/>
@ -2801,19 +2822,19 @@ Invested: 3.7 work hours</string>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPStoreCellFooter" rowHeight="100" id="jsY-TE-4y5" userLabel="Footer">
<rect key="frame" x="0.0" y="958" width="414" height="100"/>
<rect key="frame" x="0.0" y="974.5" width="414" height="100"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="jsY-TE-4y5" id="guB-Eb-KpI">
<rect key="frame" x="0.0" y="0.0" width="414" height="100"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999998807907104" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="749" verticalCompressionResistancePriority="751" text="© 2012-2014, Maarten Billemont (lhunath)" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="26U-st-xNs">
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" alpha="0.69999998807907104" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="749" verticalCompressionResistancePriority="751" ambiguous="YES" text="© 2012-2014, Maarten Billemont (lhunath)" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="26U-st-xNs">
<rect key="frame" x="20" y="4" width="374" height="22"/>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="11"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" verticalCompressionResistancePriority="751" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lQ1-b9-Xp4">
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" verticalCompressionResistancePriority="751" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lQ1-b9-Xp4">
<rect key="frame" x="20" y="34" width="374" height="27"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="12"/>
<state key="normal" title="Restore Previous Purchases">
@ -2823,7 +2844,7 @@ Invested: 3.7 work hours</string>
<action selector="restorePurchases:" destination="pdl-xv-zjX" eventType="touchUpInside" id="Q8M-ud-OHL"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="eus-kQ-emn">
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" ambiguous="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="eus-kQ-emn">
<rect key="frame" x="8" y="69" width="398" height="27"/>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="12"/>
<state key="normal" title="Send Thanks">
@ -2887,7 +2908,7 @@ Invested: 3.7 work hours</string>
<color key="separatorColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<prototypes>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPGlobalAnswersCell" rowHeight="133" id="DT2-Vb-uXj" userLabel="Global Answer" customClass="MPGlobalAnswersCell">
<rect key="frame" x="0.0" y="28" width="414" height="133"/>
<rect key="frame" x="0.0" y="44.5" width="414" height="133"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="DT2-Vb-uXj" id="URA-cl-MJP">
<rect key="frame" x="0.0" y="0.0" width="414" height="133"/>
@ -2931,14 +2952,14 @@ Invested: 3.7 work hours</string>
</connections>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPSendAnswersCell" rowHeight="44" id="tvm-WZ-MDZ" userLabel="Send Answers" customClass="MPSendAnswersCell">
<rect key="frame" x="0.0" y="161" width="414" height="44"/>
<rect key="frame" x="0.0" y="177.5" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="tvm-WZ-MDZ" id="BTm-Lm-V9p">
<rect key="frame" x="0.0" y="0.0" width="383" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="384.5" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="Send the answer(s) to my email" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AAV-yg-dfK">
<rect key="frame" x="8" y="8" width="367" height="28"/>
<rect key="frame" x="8" y="8" width="368.5" height="28"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="12"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@ -2954,14 +2975,14 @@ Invested: 3.7 work hours</string>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" accessoryType="checkmark" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPMultipleAnswersCell" rowHeight="44" id="5MB-qb-oPk" userLabel="Multiple Answers" customClass="MPMultipleAnswersCell">
<rect key="frame" x="0.0" y="205" width="414" height="44"/>
<rect key="frame" x="0.0" y="221.5" width="414" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="5MB-qb-oPk" id="4wX-xO-9QU">
<rect key="frame" x="0.0" y="0.0" width="370" height="44"/>
<rect key="frame" x="0.0" y="0.0" width="373.5" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="This site needs different answers for each question" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="een-0g-CMy">
<rect key="frame" x="8" y="8" width="354" height="28"/>
<rect key="frame" x="8" y="8" width="357.5" height="28"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="12"/>
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
@ -2977,7 +2998,7 @@ Invested: 3.7 work hours</string>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</tableViewCell>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" shouldIndentWhileEditing="NO" reuseIdentifier="MPAnswersQuestionCell" rowHeight="130" id="iFm-3w-hOv" userLabel="Question" customClass="MPAnswersQuestionCell">
<rect key="frame" x="0.0" y="249" width="414" height="130"/>
<rect key="frame" x="0.0" y="265.5" width="414" height="130"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="iFm-3w-hOv" id="X5d-5g-uJa">
<rect key="frame" x="0.0" y="0.0" width="414" height="130"/>

View File

@ -14,9 +14,9 @@ echo "Cleaning .."
git clean -ffdx .
echo "Creating archive $mpwArchive .."
echo "$version" > VERSION
git show --show-signature --pretty=format:%H --quiet "$tag" > TAG
{ git ls-files -z .; printf '%s\0' VERSION TAG; } | xargs -0 tar -Lcvzf "$mpwArchive"
echo "$version" > cli/VERSION
git show --show-signature --pretty=format:%H --quiet "$tag" > cli/TAG
{ git ls-files -z .; printf '%s\0' cli/VERSION cli/TAG; } | xargs -0 tar -Lcvzf "$mpwArchive"
echo "Creating archive signature $mpwArchive.sig .."
gpg --detach-sign --local-user 5C2D1D61853F20F2FCDDCCB70EF21226F43EA6BC "$mpwArchive"

View File

@ -122,7 +122,10 @@ const char *mpw_site_result(
return NULL;
}
if (resultType & MPResultTypeClassTemplate) {
if (resultType == MPResultTypeNone) {
return NULL;
}
else if (resultType & MPResultTypeClassTemplate) {
switch (algorithmVersion) {
case MPAlgorithmVersionV0:
return mpw_site_template_password_v0( masterKey, siteKey, resultType, resultParam );
@ -203,6 +206,10 @@ const char *mpw_site_state(
return NULL;
}
if (resultType == MPResultTypeNone) {
return NULL;
}
switch (algorithmVersion) {
case MPAlgorithmVersionV0:
return mpw_site_state_v0( masterKey, siteKey, resultType, resultParam );

View File

@ -93,7 +93,7 @@ MPMarshalledUser *mpw_marshal_user(
.fullName = mpw_strdup( fullName ),
.identicon = MPIdenticonUnset,
.keyID = NULL,
.defaultType = MPResultTypeDefault,
.defaultType = MPResultTypeDefaultResult,
.lastUsed = 0,
.sites_count = 0,
@ -122,7 +122,7 @@ MPMarshalledSite *mpw_marshal_site(
.resultType = resultType,
.resultState = NULL,
.loginType = MPResultTypeTemplateName,
.loginType = MPResultTypeDefaultLogin,
.loginState = NULL,
.url = NULL,
@ -864,7 +864,7 @@ static void mpw_marshal_read_flat(
char *fullName = NULL, *keyID = NULL;
MPAlgorithmVersion algorithm = MPAlgorithmVersionCurrent;
MPIdenticon identicon = MPIdenticonUnset;
MPResultType defaultType = MPResultTypeDefault;
MPResultType defaultType = MPResultTypeDefaultResult;
time_t exportDate = 0;
bool headerStarted = false, headerEnded = false, importRedacted = false;
for (const char *endOfLine, *positionInLine = in; (endOfLine = strstr( positionInLine, "\n" )); positionInLine = endOfLine + 1) {
@ -1014,13 +1014,14 @@ static void mpw_marshal_read_flat(
mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid site last used: %s: %s", siteName, str_lastUsed );
continue;
}
MPResultType siteLoginType = siteLoginState && strlen( siteLoginState )? MPResultTypeStatefulPersonal: MPResultTypeNone;
char dateString[21];
mpw_marshal_data_set_num( siteCounter, file->data, "sites", siteName, "counter", NULL );
mpw_marshal_data_set_num( siteAlgorithm, file->data, "sites", siteName, "algorithm", NULL );
mpw_marshal_data_set_num( siteType, file->data, "sites", siteName, "type", NULL );
mpw_marshal_data_set_str( siteResultState, file->data, "sites", siteName, "password", NULL );
mpw_marshal_data_set_num( MPResultTypeDefault, file->data, "sites", siteName, "login_type", NULL );
mpw_marshal_data_set_num( siteLoginType, file->data, "sites", siteName, "login_type", NULL );
mpw_marshal_data_set_str( siteLoginState, file->data, "sites", siteName, "login_name", NULL );
mpw_marshal_data_set_num( strtol( str_uses, NULL, 10 ), file->data, "sites", siteName, "uses", NULL );
if (strftime( dateString, sizeof( dateString ), "%FT%TZ", gmtime( &siteLastUsed ) ))
@ -1150,7 +1151,7 @@ MPMarshalledUser *mpw_marshal_auth(
}
MPIdenticon identicon = mpw_identicon_encoded( mpw_marshal_data_get_str( file->data, "user", "identicon", NULL ) );
const char *keyID = mpw_marshal_data_get_str( file->data, "user", "key_id", NULL );
MPResultType defaultType = mpw_default_n( MPResultTypeDefault, mpw_marshal_data_get_num( file->data, "user", "default_type", NULL ) );
MPResultType defaultType = mpw_default_n( MPResultTypeDefaultResult, mpw_marshal_data_get_num( file->data, "user", "default_type", NULL ) );
if (!mpw_type_short_name( defaultType )) {
mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid user default type: %u", defaultType );
return NULL;
@ -1216,7 +1217,7 @@ MPMarshalledUser *mpw_marshal_auth(
return NULL;
}
const char *siteResultState = mpw_marshal_data_get_str( siteData, "password", NULL );
MPResultType siteLoginType = mpw_default_n( MPResultTypeTemplateName, mpw_marshal_data_get_num( siteData, "login_type", NULL ) );
MPResultType siteLoginType = mpw_default_n( MPResultTypeDefaultLogin, mpw_marshal_data_get_num( siteData, "login_type", NULL ) );
if (!mpw_type_short_name( siteLoginType )) {
mpw_marshal_error( file, MPMarshalErrorIllegal, "Invalid site login type: %s: %u", siteName, siteLoginType );
mpw_free( &masterKey, MPMasterKeySize );
@ -1258,10 +1259,10 @@ MPMarshalledUser *mpw_marshal_auth(
return NULL;
}
if (siteResultState && strlen( siteResultState ))
if (siteResultState && strlen( siteResultState ) && masterKey)
site->resultState = mpw_site_state( masterKey, site->siteName, site->counter,
MPKeyPurposeAuthentication, NULL, site->resultType, siteResultState, site->algorithm );
if (siteLoginState && strlen( siteLoginState ))
if (siteLoginState && strlen( siteLoginState ) && masterKey)
site->loginState = mpw_site_state( masterKey, site->siteName, MPCounterValueInitial,
MPKeyPurposeIdentification, NULL, site->loginType, siteLoginState, site->algorithm );
}
@ -1282,7 +1283,7 @@ MPMarshalledUser *mpw_marshal_auth(
if (!user->redacted) {
// Clear Text
if (answerState && strlen( answerState ))
if (answerState && strlen( answerState ) && masterKey)
question->state = mpw_site_state( masterKey, site->siteName, MPCounterValueInitial,
MPKeyPurposeRecovery, question->keyword, question->type, answerState, site->algorithm );
}

View File

@ -38,6 +38,8 @@ const MPResultType mpw_type_named(const char *typeName) {
// Find what password type is represented by the type letter.
if (strlen( typeName ) == 1) {
if ('0' == typeName[0])
return MPResultTypeNone;
if ('x' == typeName[0])
return MPResultTypeTemplateMaximum;
if ('l' == typeName[0])
@ -63,6 +65,8 @@ const MPResultType mpw_type_named(const char *typeName) {
}
// Find what password type is represented by the type name.
if (mpw_strncasecmp( mpw_type_short_name( MPResultTypeNone ), typeName, strlen( typeName ) ) == OK)
return MPResultTypeNone;
if (mpw_strncasecmp( mpw_type_short_name( MPResultTypeTemplateMaximum ), typeName, strlen( typeName ) ) == OK)
return MPResultTypeTemplateMaximum;
if (mpw_strncasecmp( mpw_type_short_name( MPResultTypeTemplateLong ), typeName, strlen( typeName ) ) == OK)
@ -93,6 +97,8 @@ const MPResultType mpw_type_named(const char *typeName) {
const char *mpw_type_abbreviation(const MPResultType resultType) {
switch (resultType) {
case MPResultTypeNone:
return "no";
case MPResultTypeTemplateMaximum:
return "max";
case MPResultTypeTemplateLong:
@ -125,6 +131,8 @@ const char *mpw_type_abbreviation(const MPResultType resultType) {
const char *mpw_type_short_name(const MPResultType resultType) {
switch (resultType) {
case MPResultTypeNone:
return "none";
case MPResultTypeTemplateMaximum:
return "maximum";
case MPResultTypeTemplateLong:
@ -157,6 +165,8 @@ const char *mpw_type_short_name(const MPResultType resultType) {
const char *mpw_type_long_name(const MPResultType resultType) {
switch (resultType) {
case MPResultTypeNone:
return "None";
case MPResultTypeTemplateMaximum:
return "Maximum Security Password";
case MPResultTypeTemplateLong:

View File

@ -80,6 +80,9 @@ typedef mpw_opts( uint16_t, MPSiteFeature ) {
// bit 0-3 | MPResultTypeClass | MPSiteFeature
typedef mpw_enum( uint32_t, MPResultType ) {
/** 0: Don't produce a result */
MPResultTypeNone = 0,
/** 16: pg^VMAUBk5x3p%HP%i4= */
MPResultTypeTemplateMaximum = 0x0 | MPResultTypeClassTemplate | 0x0,
/** 17: BiroYena8:Kixa */
@ -105,7 +108,8 @@ typedef mpw_enum( uint32_t, MPResultType ) {
/** 4160: Derive a unique binary key. */
MPResultTypeDeriveKey = 0x0 | MPResultTypeClassDerive | MPSiteFeatureAlternative,
MPResultTypeDefault = MPResultTypeTemplateLong,
MPResultTypeDefaultResult = MPResultTypeTemplateLong,
MPResultTypeDefaultLogin = MPResultTypeTemplateName,
};
typedef mpw_enum ( uint32_t, MPCounterValue ) {

View File

@ -212,7 +212,7 @@ public abstract class Components {
@Override
public String getString(final int where, final int len)
throws BadLocationException {
return "";
return new String( new char[this.length()] );
}
} ), null, 0 ) {
{

View File

@ -1,6 +1,20 @@
#!/usr/bin/env bash
source bashlib
calc() { python -c "import math; print $1"; }
scale() {
local number=$1 precision=$2 definition unit weight; shift 2
for definition in "$@"; do
definition=$definition
weight=${definition#*:}
[[ ! $weight || $(calc "($number) > ($weight)") = True ]] || break
number=$(calc "(1.0 * $number) / (1.0 * ${weight:-1})") unit=${definition%:*}
done
printf "%'0.${precision}f %s" "$number" "$unit"
}
scaleTime() { scale "$1" "${2:-2}" 'Seconds:' "Hours:3600" "Days:24" "Months:30" "Years:356/30" "K Years:1000" "M Years:1000" "B Years:1000" "T Years:1000"; }
scaleEnergy() { scale "$1" "${2:-2}" 'Wh:' 'kWh:1000' 'MWh:1000' 'GWh:1000' 'TWh:1000'; }
scaleCost() { scale "$1" "${2:-2}" '$US:' 'K$US:1000' 'M$US:1000' 'B$US:1000' 'T$US:1000'; }
inf 'Calculate the maximum amount of time required to brute-force search for a password.'
@ -17,44 +31,45 @@ x="$a$n!@#\$%^&*()"
w="@words.txt"
## METRICS
# Last update: 2016-09
# GTX Titan X can generate about 402.7M HMAC-SHA-256 hashes per second (5301.7M SHA1). (ref. https://hashcat.net/forum/thread-4314.html)
# GTX Titan X can be bought for about 950$ used. (ref. amazon.com)
#hardwareName='GTX Titan X (SHA1)' hardwareSpeed='5302M'
#hardwareName='GTX Titan X (SHA1 @ 5k$)' hardwareSpeed='5302M * 5k / 950'
#hardwareName='GTX Titan X (SHA1 @ 20k$)' hardwareSpeed='5302M * 20k / 950'
#hardwareName='GTX Titan X (SHA1 @ 20M$)' hardwareSpeed='5302M * 20M / 950'
#hardwareName='GTX Titan X (SHA1 @ 5B$)' hardwareSpeed='5302M * 5B / 950'
hardwareName='GTX Titan X (HMAC-SHA-256 @ 950$)' hardwareSpeed='403M'
#hardwareName='GTX Titan X (HMAC-SHA-256 @ 5k$)' hardwareSpeed='403M * 5k / 950'
#hardwareName='GTX Titan X (HMAC-SHA-256 @ 20k$)' hardwareSpeed='403M * 20k / 950'
#hardwareName='GTX Titan X (HMAC-SHA-256 @ 20M$)' hardwareSpeed='403M * 20M / 950'
#hardwareName='GTX Titan X (HMAC-SHA-256 @ 5B$)' hardwareSpeed='403M * 5B / 950'
# GTX Titan X -- https://gist.github.com/epixoip/1f26f43e9036d9ce0eb8
#hardwareName='GTX Titan X (SHA1)' hardwareHPS='5302M' hardwareCost='950' hardwareWatt='250' # -mpl: 4.67 m
#hardwareName='GTX Titan X (HMAC-SHA-256)' hardwareHPS='2113M' hardwareCost='950' hardwareWatt='250' # -mpl: 0.99 y
#hardwareName='GTX Titan X (bcrypt-10)' hardwareHPS='14440/32' hardwareCost='950' hardwareWatt='250' # -mpl: 4.62 My
# GTX 980 Ti -- https://gist.github.com/epixoip/d34245293ccecbfcc7c7
#hardwareName='GTX 980 Ti (SHA1)' hardwareHPS='5366M' hardwareCost='450' hardwareWatt='250' # -mpl: 4.61 m
#hardwareName='GTX 980 Ti (SHA256)' hardwareHPS='2032M' hardwareCost='450' hardwareWatt='250' # -mpl: 1.03 y
#hardwareName='GTX 980 Ti (bcrypt-10)' hardwareHPS='14521/32' hardwareCost='450' hardwareWatt='250' # -mpl: 4.60 My
# GTX 1060 -- https://gist.github.com/derpasaurusz/817638385a35026383331b22e6f2d490
#hardwareName='GTX 1060 (SHA1)' hardwareHPS='4218M' hardwareCost='400' hardwareWatt='120' # -mpl: 5.87 m
#hardwareName='GTX 1060 (SHA256)' hardwareHPS='1632M' hardwareCost='400' hardwareWatt='120' # -mpl: 1.28 y
#hardwareName='GTX 1060 (bcrypt-10)' hardwareHPS='8046/32' hardwareCost='400' hardwareWatt='120' # -mpl: 8.30 My
# GTX 1080 Ti -- https://gist.github.com/epixoip/ace60d09981be09544fdd35005051505
#hardwareName='GTX 1080 Ti (SHA1)' hardwareHPS='12696M' hardwareCost='1200' hardwareWatt='250' # -mpl: 1.95 m
#hardwareName='GTX 1080 Ti (SHA256)' hardwareHPS='4967M' hardwareCost='1200' hardwareWatt='250' # -mpl: 4.99 m
#hardwareName='GTX 1080 Ti (bcrypt-10)' hardwareHPS='23266/32' hardwareCost='1200' hardwareWatt='250' # -mpl: 2.87 My
hardwareName='GTX 1080 Ti (mpw?)' hardwareHPS='56*3' hardwareCost='1200' hardwareWatt='250' # -mpl: 2.87 My
# ASICs
hardwareName='AntMiner L3+ (scrypt)' hardwareSpeed='1M'
#hardwareName='AntMiner L3+ (scrypt @ 5k$)' hardwareSpeed='1M * 5k / 2500'
#hardwareName='AntMiner L3+ (scrypt @ 20k$)' hardwareSpeed='1M * 20k / 2500'
#hardwareName='AntMiner L3+ (scrypt @ 20M$)' hardwareSpeed='1M * 20M / 2500'
#hardwareName='AntMiner L3+ (scrypt @ 5B$)' hardwareSpeed='1M * 5B / 2500'
hardwareName='AntMiner S9 (SHA256)' hardwareSpeed='14T'
#hardwareName='AntMiner S9 (SHA256 @ 5k$)' hardwareSpeed='14T * 5k / 1288'
#hardwareName='AntMiner S9 (SHA256 @ 20k$)' hardwareSpeed='14T * 20k / 1288'
#hardwareName='AntMiner S9 (SHA256 @ 20M$)' hardwareSpeed='14T * 20M / 1288'
#hardwareName='AntMiner S9 (SHA256 @ 5B$)' hardwareSpeed='14T * 5B / 1288'
#hardwareName='AntMiner L3+ (scrypt)' hardwareHPS='1M' hardwareCost='2500' hardwareWatt='800'
#hardwareName='AntMiner S9 (SHA256)' hardwareHPS='14T' hardwareCost='1288' hardwareWatt='1400'
# mpw-bench
#hardwareName='2.3 GHz i7, 8GB (MPW)' hardwareSpeed=7.46
#hardwareName='2.3 GHz i7, 8GB (MPW)' hardwareHPS=7.46
costPerKWh='0.1' # ~0.1$/kWh
hardwareQuantity=$(calc "5000000000 / ($hardwareCost)")
second='1'
secondsInHour='3600'
secondsInDay='3600 * 24'
secondsInMonth='3600 * 24 * 30'
secondsInYear='3600 * 24 * 356'
hardwareSpeed=${hardwareSpeed//k/000}
hardwareSpeed=${hardwareSpeed//M/000000}
hardwareSpeed=${hardwareSpeed//G/000000000}
hardwareSpeed=${hardwareSpeed//T/000000000000}
hardwareHPS=${hardwareHPS//k/000}
hardwareHPS=${hardwareHPS//M/000000}
hardwareHPS=${hardwareHPS//G/000000000}
hardwareHPS=${hardwareHPS//T/000000000000}
## SEARCH SPACE
hr
@ -74,7 +89,7 @@ for _c in V C v c A a n o x w; do
inf '%s: Class contains %d entities: %s' "$_c" "$cs" "$cc"
done
spaceString=${1:-$(ask -d "x ** 12" "Amount of space?")}
spaceString=${1:-$(ask -d "x ** 12" "Size of the space?")}
case "$spaceString" in
-mp*) mpmode=${spaceString#-mp} mpmode=${mpmode:-long}
case "$mpmode" in
@ -82,9 +97,18 @@ case "$spaceString" in
max|secure|x) spaceString='aonxxxxxxxxxxxxxxxxx+axxxxxxxxxxxxxxxxxon' ;;
med|m) spaceString='CvcnoCvc+CvcCvcno' ;;
basic|b) spaceString='aaanaaan+aannaaan+aaannaaa' ;;
*) ftl 'Unknown mode: %s' "$mpmode" || exit
esac ;;
-pw*) password=${spaceString#-pw} spaceString=
while read -N1 pwchar; do
for _c in v c a n x; do
cc=${!_c}
[[ $cc = *$pwchar* ]] && spaceString+=$_c && break
done || spaceString+=" 256 "
done <<< "$password"
;;
esac
space=$spaceString
spaceSize=$spaceString
for _c in V C v c A a n o x w; do
cc=${!_c}
if [[ $cc = @* ]]; then
@ -94,35 +118,39 @@ for _c in V C v c A a n o x w; do
cs=${#cc}
fi
space=${space//$_c/ 0$cs }
spaceSize=${spaceSize//$_c/ 0$cs }
done
# Replace sequences of numbers by multiplication of those numbers. Then, pretty-print.
space=$(sed -e 's/\([[:digit:]]\) *\([[:digit:]]\)/\1 * \2/g' -e 's/ 00*\([1-9]\)/ \1/g' <<< "$space")
space=$(tr -s ' ' <<< "$space") space=${space# } space=${space% }
spaceSize=$(sed -e 's/\([[:digit:]]\) *\([[:digit:]]\)/\1 * \2/g' -e 's/ 00*\([1-9]\)/ \1/g' <<< "$spaceSize")
spaceSize=$(tr -s ' ' <<< "$spaceSize") spaceSize=${spaceSize# } spaceSize=${spaceSize% }
inf ''
inf "Search space: %s = %s = %'.f possibilities to try (~%.1f bit)." "$spaceString" "$space" "$(calc "$space")" "$(bc -l <<< "l($(calc "$space")) / l(2)")"
inf "Search space: %s = %s = %'.f possibilities to try (~%.1f bit)." "$spaceString" "$spaceSize" "$(calc "$spaceSize")" "$(bc -l <<< "l($(calc "$spaceSize")) / l(2)")"
## CLUSTER SIZE
hr
inf 'CLUSTER SIZE'
inf "Simulating %s at a rate of about %'.1f attempts per second." "$hardwareName" "$(calc "$hardwareSpeed")"
cluster=$(ask -d 1 "Amount of GPUs?")
inf "Simulating %s at a rate of about %'.1f attempts per second." "$hardwareName" "$(calc "$hardwareHPS")"
cluster=$(ask -d "$hardwareQuantity" "Amount of units?")
## CALCULATE
hr
inf 'TIMING'
inf "Time to search the entire space using %d GPUs of type %s (rate=%'.1f/s)" "$cluster" "$hardwareName" "$(calc "$hardwareSpeed")"
inf "Time to search the entire space using %dx %s units (unit rate=%'.1f H/s)" "$cluster" "$hardwareName" "$(calc "$hardwareHPS")"
seconds=$(calc "(1.0 * $spaceSize) / (1.0 * $hardwareHPS * $cluster)")
inf "Time to crack: %s (ie. %s Seconds)" "$(scale "$seconds" 2 'Seconds:' "Hours:3600" "Days:24" "Months:30" "Years:356/30")" "$seconds"
timing() {
local title=$1 unit=$2 precision=$3 seconds=$4
time=$(calc "1.0 * ($space) / ($hardwareSpeed * $cluster) / ($seconds)")
percent=$(calc "100.0 * ($hardwareSpeed * $cluster) * ($seconds) / ($space)")
time=$(calc "(1.0 * $spaceSize) / (1.0 * $hardwareHPS * $cluster) / ($seconds)")
percent=$(calc "(100.0 * $hardwareHPS * $cluster * $seconds) / (1.0 * $spaceSize)")
amount=$(calc "$percent / 100.0")
if [[ $amount = 0.* ]]; then
inf "%10s to crack: %'0.${precision}f (search rate is %0.0f%% / %s)" \
if [[ $(calc "$percent < 100") = True ]]; then
inf " - %10s: %'0.${precision}f (ie. %0.1f%% / %s)" \
"$title" "$time" "$percent" "$unit"
else
inf "%10s to crack: %'0.${precision}f (completes %0.1fx / %s)" \
inf " - %10s: %'0.${precision}f (ie. %0.1fx / %s)" \
"$title" "$time" "$amount" "$unit"
fi
}
@ -131,3 +159,17 @@ timing Hours h 2 "$secondsInHour"
timing Days d 3 "$secondsInDay"
timing Months m 4 "$secondsInMonth"
timing Years y 4 "$secondsInYear"
hr
inf 'COST'
inf "Budget required to search the entire space using %dx %s units (unit cost=%s + %s / year => %s annum, %s / HPS)" \
"$cluster" "$hardwareName" "$(scaleCost "$hardwareCost")" "$(scaleCost "1.0 * $hardwareWatt * 356 * 24 * $costPerKWh / 1000")" "$(scaleCost "$hardwareCost + 1.0 * $hardwareWatt * 356 * 24 * $costPerKWh / 1000")" "$(scaleCost "$hardwareCost / (1.0 * $hardwareHPS)")"
fixedCost=$(calc "(1.0 * $cluster * $hardwareCost)")
energyCost=$(calc "(1.0 * $cluster * $hardwareWatt * $seconds) / 3600") # Wh
totalCost=$(calc "1.0 * $fixedCost + ($energyCost * $costPerKWh) / 1000.0")
inf "Time cost : %s" "$(scaleTime "$seconds")"
inf "Fixed costs: %s" "$(scaleCost "$fixedCost")"
inf "Energy cost: %s" "$(scaleEnergy "$energyCost")"
inf "Budget cost: %s" "$(scaleCost "$totalCost")"

@ -1 +1 @@
Subproject commit 1e9ad48d2ceb59ec5ec5db9b9a7ea946939ed61e
Subproject commit 1e7491e0d9f39ac6d49e4078cf445ca69e71020a