2
0

Element -> Site WIP

This commit is contained in:
Maarten Billemont 2014-09-21 10:39:09 -04:00
parent 68e6106ee7
commit 4396ce436e
39 changed files with 752 additions and 648 deletions

View File

@ -16,8 +16,8 @@
// //
#import "MPKey.h" #import "MPKey.h"
#import "MPElementStoredEntity.h" #import "MPSiteStoredEntity.h"
#import "MPElementGeneratedEntity.h" #import "MPSiteGeneratedEntity.h"
#define MPAlgorithmDefaultVersion 1 #define MPAlgorithmDefaultVersion 1
#define MPAlgorithmDefault MPAlgorithmForVersion(MPAlgorithmDefaultVersion) #define MPAlgorithmDefault MPAlgorithmForVersion(MPAlgorithmDefaultVersion)
@ -44,48 +44,48 @@ NSString *NSStringFromTimeToCrack(TimeToCrack timeToCrack);
@required @required
- (NSUInteger)version; - (NSUInteger)version;
- (BOOL)migrateUser:(MPUserEntity *)user inContext:(NSManagedObjectContext *)moc; - (BOOL)migrateUser:(MPUserEntity *)user inContext:(NSManagedObjectContext *)moc;
- (BOOL)migrateElement:(MPElementEntity *)element explicit:(BOOL)explicit; - (BOOL)migrateSite:(MPSiteEntity *)site explicit:(BOOL)explicit;
- (MPKey *)keyForPassword:(NSString *)password ofUserNamed:(NSString *)userName; - (MPKey *)keyForPassword:(NSString *)password ofUserNamed:(NSString *)userName;
- (MPKey *)keyFromKeyData:(NSData *)keyData; - (MPKey *)keyFromKeyData:(NSData *)keyData;
- (NSData *)keyIDForKeyData:(NSData *)keyData; - (NSData *)keyIDForKeyData:(NSData *)keyData;
- (NSString *)scopeForVariant:(MPElementVariant)variant; - (NSString *)scopeForVariant:(MPSiteVariant)variant;
- (NSString *)nameOfType:(MPElementType)type; - (NSString *)nameOfType:(MPSiteType)type;
- (NSString *)shortNameOfType:(MPElementType)type; - (NSString *)shortNameOfType:(MPSiteType)type;
- (NSString *)classNameOfType:(MPElementType)type; - (NSString *)classNameOfType:(MPSiteType)type;
- (Class)classOfType:(MPElementType)type; - (Class)classOfType:(MPSiteType)type;
- (NSArray *)allTypes; - (NSArray *)allTypes;
- (NSArray *)allTypesStartingWith:(MPElementType)startingType; - (NSArray *)allTypesStartingWith:(MPSiteType)startingType;
- (MPElementType)nextType:(MPElementType)type; - (MPSiteType)nextType:(MPSiteType)type;
- (MPElementType)previousType:(MPElementType)type; - (MPSiteType)previousType:(MPSiteType)type;
- (NSString *)generateLoginForSiteNamed:(NSString *)name usingKey:(MPKey *)key; - (NSString *)generateLoginForSiteNamed:(NSString *)name usingKey:(MPKey *)key;
- (NSString *)generatePasswordForSiteNamed:(NSString *)name ofType:(MPElementType)type withCounter:(NSUInteger)counter - (NSString *)generatePasswordForSiteNamed:(NSString *)name ofType:(MPSiteType)type withCounter:(NSUInteger)counter
usingKey:(MPKey *)key; usingKey:(MPKey *)key;
- (NSString *)generateContentForSiteNamed:(NSString *)name ofType:(MPElementType)type withCounter:(NSUInteger)counter - (NSString *)generateContentForSiteNamed:(NSString *)name ofType:(MPSiteType)type withCounter:(NSUInteger)counter
variant:(MPElementVariant)variant usingKey:(MPKey *)key; variant:(MPSiteVariant)variant usingKey:(MPKey *)key;
- (NSString *)storedLoginForElement:(MPElementStoredEntity *)element usingKey:(MPKey *)key; - (NSString *)storedLoginForSite:(MPSiteStoredEntity *)site usingKey:(MPKey *)key;
- (NSString *)storedPasswordForElement:(MPElementStoredEntity *)element usingKey:(MPKey *)key; - (NSString *)storedPasswordForSite:(MPSiteStoredEntity *)site usingKey:(MPKey *)key;
- (BOOL)savePassword:(NSString *)clearPassword toElement:(MPElementEntity *)element usingKey:(MPKey *)elementKey; - (BOOL)savePassword:(NSString *)clearPassword toSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey;
- (NSString *)resolveLoginForElement:(MPElementEntity *)element usingKey:(MPKey *)elementKey; - (NSString *)resolveLoginForSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey;
- (NSString *)resolvePasswordForElement:(MPElementEntity *)element usingKey:(MPKey *)elementKey; - (NSString *)resolvePasswordForSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey;
- (void)resolveLoginForElement:(MPElementEntity *)element usingKey:(MPKey *)elementKey - (void)resolveLoginForSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey
result:(void ( ^ )(NSString *result))resultBlock;
- (void)resolvePasswordForSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey
result:(void ( ^ )(NSString *result))resultBlock; result:(void ( ^ )(NSString *result))resultBlock;
- (void)resolvePasswordForElement:(MPElementEntity *)element usingKey:(MPKey *)elementKey
result:(void ( ^ )(NSString *result))resultBlock;
- (void)importProtectedPassword:(NSString *)protectedPassword protectedByKey:(MPKey *)importKey - (void)importProtectedPassword:(NSString *)protectedPassword protectedByKey:(MPKey *)importKey
intoElement:(MPElementEntity *)element usingKey:(MPKey *)elementKey; intoSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey;
- (void)importClearTextPassword:(NSString *)clearPassword intoElement:(MPElementEntity *)element - (void)importClearTextPassword:(NSString *)clearPassword intoSite:(MPSiteEntity *)site
usingKey:(MPKey *)elementKey; usingKey:(MPKey *)siteKey;
- (NSString *)exportPasswordForElement:(MPElementEntity *)element usingKey:(MPKey *)elementKey; - (NSString *)exportPasswordForSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey;
- (BOOL)timeToCrack:(out TimeToCrack *)timeToCrack passwordOfType:(MPElementType)type byAttacker:(MPAttacker)attacker; - (BOOL)timeToCrack:(out TimeToCrack *)timeToCrack passwordOfType:(MPSiteType)type byAttacker:(MPAttacker)attacker;
- (BOOL)timeToCrack:(out TimeToCrack *)timeToCrack passwordString:(NSString *)password byAttacker:(MPAttacker)attacker; - (BOOL)timeToCrack:(out TimeToCrack *)timeToCrack passwordString:(NSString *)password byAttacker:(MPAttacker)attacker;
@end @end

View File

@ -20,7 +20,7 @@
@interface MPAlgorithmV0 : NSObject<MPAlgorithm> @interface MPAlgorithmV0 : NSObject<MPAlgorithm>
- (NSDictionary *)allCiphers; - (NSDictionary *)allCiphers;
- (NSArray *)ciphersForType:(MPElementType)type; - (NSArray *)ciphersForType:(MPSiteType)type;
- (NSArray *)cipherClasses; - (NSArray *)cipherClasses;
- (NSArray *)cipherClassCharacters; - (NSArray *)cipherClassCharacters;
- (NSString *)charactersForCipherClass:(NSString *)cipherClass; - (NSString *)charactersForCipherClass:(NSString *)cipherClass;

View File

@ -75,7 +75,7 @@
- (BOOL)migrateUser:(MPUserEntity *)user inContext:(NSManagedObjectContext *)moc { - (BOOL)migrateUser:(MPUserEntity *)user inContext:(NSManagedObjectContext *)moc {
NSError *error = nil; NSError *error = nil;
NSFetchRequest *migrationRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPElementEntity class] )]; NSFetchRequest *migrationRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
migrationRequest.predicate = [NSPredicate predicateWithFormat:@"version_ < %d AND user == %@", self.version, user]; migrationRequest.predicate = [NSPredicate predicateWithFormat:@"version_ < %d AND user == %@", self.version, user];
NSArray *migrationElements = [moc executeFetchRequest:migrationRequest error:&error]; NSArray *migrationElements = [moc executeFetchRequest:migrationRequest error:&error];
if (!migrationElements) { if (!migrationElements) {
@ -84,14 +84,14 @@
} }
BOOL requiresExplicitMigration = NO; BOOL requiresExplicitMigration = NO;
for (MPElementEntity *migrationElement in migrationElements) for (MPSiteEntity *migrationElement in migrationElements)
if (![migrationElement migrateExplicitly:NO]) if (![migrationElement migrateExplicitly:NO])
requiresExplicitMigration = YES; requiresExplicitMigration = YES;
return requiresExplicitMigration; return requiresExplicitMigration;
} }
- (BOOL)migrateElement:(MPElementEntity *)element explicit:(BOOL)explicit { - (BOOL)migrateSite:(MPSiteEntity *)element explicit:(BOOL)explicit {
if (element.version != [self version] - 1) if (element.version != [self version] - 1)
// Only migrate from previous version. // Only migrate from previous version.
@ -138,129 +138,138 @@
return [keyData hashWith:MP_hash]; return [keyData hashWith:MP_hash];
} }
- (NSString *)scopeForVariant:(MPElementVariant)variant { - (NSString *)scopeForVariant:(MPSiteVariant)variant {
switch (variant) { switch (variant) {
case MPElementVariantPassword: case MPSiteVariantPassword:
return @"com.lyndir.masterpassword"; return @"com.lyndir.masterpassword";
case MPElementVariantLogin: case MPSiteVariantLogin:
return @"com.lyndir.masterpassword.login"; return @"com.lyndir.masterpassword.login";
} }
Throw( @"Unsupported variant: %ld", (long)variant ); Throw( @"Unsupported variant: %ld", (long)variant );
} }
- (NSString *)nameOfType:(MPElementType)type { - (NSString *)nameOfType:(MPSiteType)type {
if (!type) if (!type)
return nil; return nil;
switch (type) { switch (type) {
case MPElementTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
return @"Maximum Security Password"; return @"Maximum Security Password";
case MPElementTypeGeneratedLong: case MPSiteTypeGeneratedLong:
return @"Long Password"; return @"Long Password";
case MPElementTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
return @"Medium Password"; return @"Medium Password";
case MPElementTypeGeneratedBasic: case MPSiteTypeGeneratedBasic:
return @"Basic Password"; return @"Basic Password";
case MPElementTypeGeneratedShort: case MPSiteTypeGeneratedShort:
return @"Short Password"; return @"Short Password";
case MPElementTypeGeneratedPIN: case MPSiteTypeGeneratedPIN:
return @"PIN"; return @"PIN";
case MPElementTypeGeneratedName: case MPSiteTypeGeneratedName:
return @"Login Name"; return @"Login Name";
case MPElementTypeStoredPersonal: case MPSiteTypeGeneratedPhrase:
return @"Phrase";
case MPSiteTypeStoredPersonal:
return @"Personal Password"; return @"Personal Password";
case MPElementTypeStoredDevicePrivate: case MPSiteTypeStoredDevicePrivate:
return @"Device Private Password"; return @"Device Private Password";
} }
Throw( @"Type not supported: %lu", (long)type ); Throw( @"Type not supported: %lu", (long)type );
} }
- (NSString *)shortNameOfType:(MPElementType)type { - (NSString *)shortNameOfType:(MPSiteType)type {
if (!type) if (!type)
return nil; return nil;
switch (type) { switch (type) {
case MPElementTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
return @"Maximum"; return @"Maximum";
case MPElementTypeGeneratedLong: case MPSiteTypeGeneratedLong:
return @"Long"; return @"Long";
case MPElementTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
return @"Medium"; return @"Medium";
case MPElementTypeGeneratedBasic: case MPSiteTypeGeneratedBasic:
return @"Basic"; return @"Basic";
case MPElementTypeGeneratedShort: case MPSiteTypeGeneratedShort:
return @"Short"; return @"Short";
case MPElementTypeGeneratedPIN: case MPSiteTypeGeneratedPIN:
return @"PIN"; return @"PIN";
case MPElementTypeGeneratedName: case MPSiteTypeGeneratedName:
return @"Name"; return @"Name";
case MPElementTypeStoredPersonal: case MPSiteTypeGeneratedPhrase:
return @"Phrase";
case MPSiteTypeStoredPersonal:
return @"Personal"; return @"Personal";
case MPElementTypeStoredDevicePrivate: case MPSiteTypeStoredDevicePrivate:
return @"Device"; return @"Device";
} }
Throw( @"Type not supported: %lu", (long)type ); Throw( @"Type not supported: %lu", (long)type );
} }
- (NSString *)classNameOfType:(MPElementType)type { - (NSString *)classNameOfType:(MPSiteType)type {
return NSStringFromClass( [self classOfType:type] ); return NSStringFromClass( [self classOfType:type] );
} }
- (Class)classOfType:(MPElementType)type { - (Class)classOfType:(MPSiteType)type {
if (!type) if (!type)
Throw( @"No type given." ); Throw( @"No type given." );
switch (type) { switch (type) {
case MPElementTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
return [MPElementGeneratedEntity class]; return [MPElementGeneratedEntity class];
case MPElementTypeGeneratedLong: case MPSiteTypeGeneratedLong:
return [MPElementGeneratedEntity class]; return [MPElementGeneratedEntity class];
case MPElementTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
return [MPElementGeneratedEntity class]; return [MPElementGeneratedEntity class];
case MPElementTypeGeneratedBasic: case MPSiteTypeGeneratedBasic:
return [MPElementGeneratedEntity class]; return [MPElementGeneratedEntity class];
case MPElementTypeGeneratedShort: case MPSiteTypeGeneratedShort:
return [MPElementGeneratedEntity class]; return [MPElementGeneratedEntity class];
case MPElementTypeGeneratedPIN: case MPSiteTypeGeneratedPIN:
return [MPElementGeneratedEntity class]; return [MPElementGeneratedEntity class];
case MPElementTypeGeneratedName: case MPSiteTypeGeneratedName:
return [MPElementGeneratedEntity class]; return [MPElementGeneratedEntity class];
case MPElementTypeStoredPersonal: case MPSiteTypeGeneratedPhrase:
return [MPElementStoredEntity class]; return [MPElementGeneratedEntity class];
case MPElementTypeStoredDevicePrivate: case MPSiteTypeStoredPersonal:
return [MPElementStoredEntity class]; return [MPSiteStoredEntity class];
case MPSiteTypeStoredDevicePrivate:
return [MPSiteStoredEntity class];
} }
Throw( @"Type not supported: %lu", (long)type ); Throw( @"Type not supported: %lu", (long)type );
@ -268,13 +277,13 @@
- (NSArray *)allTypes { - (NSArray *)allTypes {
return [self allTypesStartingWith:MPElementTypeGeneratedMaximum]; return [self allTypesStartingWith:MPSiteTypeGeneratedMaximum];
} }
- (NSArray *)allTypesStartingWith:(MPElementType)startingType { - (NSArray *)allTypesStartingWith:(MPSiteType)startingType {
NSMutableArray *allTypes = [[NSMutableArray alloc] initWithCapacity:8]; NSMutableArray *allTypes = [[NSMutableArray alloc] initWithCapacity:8];
MPElementType currentType = startingType; MPSiteType currentType = startingType;
do { do {
[allTypes addObject:@(currentType)]; [allTypes addObject:@(currentType)];
} while ((currentType = [self nextType:currentType]) != startingType); } while ((currentType = [self nextType:currentType]) != startingType);
@ -282,33 +291,33 @@
return allTypes; return allTypes;
} }
- (MPElementType)nextType:(MPElementType)type { - (MPSiteType)nextType:(MPSiteType)type {
switch (type) { switch (type) {
case MPElementTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
return MPElementTypeGeneratedLong; return MPSiteTypeGeneratedLong;
case MPElementTypeGeneratedLong: case MPSiteTypeGeneratedLong:
return MPElementTypeGeneratedMedium; return MPSiteTypeGeneratedMedium;
case MPElementTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
return MPElementTypeGeneratedBasic; return MPSiteTypeGeneratedBasic;
case MPElementTypeGeneratedBasic: case MPSiteTypeGeneratedBasic:
return MPElementTypeGeneratedShort; return MPSiteTypeGeneratedShort;
case MPElementTypeGeneratedShort: case MPSiteTypeGeneratedShort:
return MPElementTypeGeneratedPIN; return MPSiteTypeGeneratedPIN;
case MPElementTypeGeneratedPIN: case MPSiteTypeGeneratedPIN:
return MPElementTypeStoredPersonal; return MPSiteTypeStoredPersonal;
case MPElementTypeStoredPersonal: case MPSiteTypeStoredPersonal:
return MPElementTypeStoredDevicePrivate; return MPSiteTypeStoredDevicePrivate;
case MPElementTypeStoredDevicePrivate: case MPSiteTypeStoredDevicePrivate:
return MPElementTypeGeneratedMaximum; return MPSiteTypeGeneratedMaximum;
default: default:
return MPElementTypeGeneratedLong; return MPSiteTypeGeneratedLong;
} }
} }
- (MPElementType)previousType:(MPElementType)type { - (MPSiteType)previousType:(MPSiteType)type {
MPElementType previousType = type, nextType = type; MPSiteType previousType = type, nextType = type;
while ((nextType = [self nextType:nextType]) != type) while ((nextType = [self nextType:nextType]) != type)
previousType = nextType; previousType = nextType;
@ -327,7 +336,7 @@
return ciphers; return ciphers;
} }
- (NSArray *)ciphersForType:(MPElementType)type { - (NSArray *)ciphersForType:(MPSiteType)type {
NSString *typeClass = [self classNameOfType:type]; NSString *typeClass = [self classNameOfType:type];
NSString *typeName = [self nameOfType:type]; NSString *typeName = [self nameOfType:type];
@ -351,19 +360,19 @@
- (NSString *)generateLoginForSiteNamed:(NSString *)name usingKey:(MPKey *)key { - (NSString *)generateLoginForSiteNamed:(NSString *)name usingKey:(MPKey *)key {
return [self generateContentForSiteNamed:name ofType:MPElementTypeGeneratedName withCounter:1 return [self generateContentForSiteNamed:name ofType:MPSiteTypeGeneratedName withCounter:1
variant:MPElementVariantLogin usingKey:key]; variant:MPSiteVariantLogin usingKey:key];
} }
- (NSString *)generatePasswordForSiteNamed:(NSString *)name ofType:(MPElementType)type withCounter:(NSUInteger)counter - (NSString *)generatePasswordForSiteNamed:(NSString *)name ofType:(MPSiteType)type withCounter:(NSUInteger)counter
usingKey:(MPKey *)key { usingKey:(MPKey *)key {
return [self generateContentForSiteNamed:name ofType:type withCounter:counter return [self generateContentForSiteNamed:name ofType:type withCounter:counter
variant:MPElementVariantPassword usingKey:key]; variant:MPSiteVariantPassword usingKey:key];
} }
- (NSString *)generateContentForSiteNamed:(NSString *)name ofType:(MPElementType)type withCounter:(NSUInteger)counter - (NSString *)generateContentForSiteNamed:(NSString *)name ofType:(MPSiteType)type withCounter:(NSUInteger)counter
variant:(MPElementVariant)variant usingKey:(MPKey *)key { variant:(MPSiteVariant)variant usingKey:(MPKey *)key {
// Determine the seed whose bytes will be used for calculating a password // Determine the seed whose bytes will be used for calculating a password
uint32_t ncounter = htonl( counter ), nnameLength = htonl( name.length ); uint32_t ncounter = htonl( counter ), nnameLength = htonl( name.length );
@ -404,49 +413,50 @@
return content; return content;
} }
- (NSString *)storedLoginForElement:(MPElementStoredEntity *)element usingKey:(MPKey *)key { - (NSString *)storedLoginForSite:(MPSiteStoredEntity *)element usingKey:(MPKey *)key {
return nil; return nil;
} }
- (NSString *)storedPasswordForElement:(MPElementStoredEntity *)element usingKey:(MPKey *)key { - (NSString *)storedPasswordForSite:(MPSiteStoredEntity *)element usingKey:(MPKey *)key {
return [self decryptContent:element.contentObject usingKey:key]; return [self decryptContent:element.contentObject usingKey:key];
} }
- (BOOL)savePassword:(NSString *)clearContent toElement:(MPElementEntity *)element usingKey:(MPKey *)elementKey { - (BOOL)savePassword:(NSString *)clearContent toSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey {
NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." ); NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." );
switch (element.type) { switch (element.type) {
case MPElementTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
case MPElementTypeGeneratedLong: case MPSiteTypeGeneratedLong:
case MPElementTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
case MPElementTypeGeneratedBasic: case MPSiteTypeGeneratedBasic:
case MPElementTypeGeneratedShort: case MPSiteTypeGeneratedShort:
case MPElementTypeGeneratedPIN: case MPSiteTypeGeneratedPIN:
case MPElementTypeGeneratedName: { case MPSiteTypeGeneratedName:
case MPSiteTypeGeneratedPhrase: {
wrn( @"Cannot save content to element with generated type %lu.", (long)element.type ); wrn( @"Cannot save content to element with generated type %lu.", (long)element.type );
return NO; return NO;
} }
case MPElementTypeStoredPersonal: { case MPSiteTypeStoredPersonal: {
if (![element isKindOfClass:[MPElementStoredEntity class]]) { if (![element isKindOfClass:[MPSiteStoredEntity class]]) {
wrn( @"Element with stored type %lu is not an MPElementStoredEntity, but a %@.", wrn( @"Element with stored type %lu is not an MPSiteStoredEntity, but a %@.",
(long)element.type, [element class] ); (long)element.type, [element class] );
return NO; return NO;
} }
NSData *encryptedContent = [[clearContent dataUsingEncoding:NSUTF8StringEncoding] NSData *encryptedContent = [[clearContent dataUsingEncoding:NSUTF8StringEncoding]
encryptWithSymmetricKey:[elementKey subKeyOfLength:PearlCryptKeySize].keyData padding:YES]; encryptWithSymmetricKey:[elementKey subKeyOfLength:PearlCryptKeySize].keyData padding:YES];
if ([((MPElementStoredEntity *)element).contentObject isEqualToData:encryptedContent]) if ([((MPSiteStoredEntity *)element).contentObject isEqualToData:encryptedContent])
return NO; return NO;
((MPElementStoredEntity *)element).contentObject = encryptedContent; ((MPSiteStoredEntity *)element).contentObject = encryptedContent;
return YES; return YES;
} }
case MPElementTypeStoredDevicePrivate: { case MPSiteTypeStoredDevicePrivate: {
if (![element isKindOfClass:[MPElementStoredEntity class]]) { if (![element isKindOfClass:[MPSiteStoredEntity class]]) {
wrn( @"Element with stored type %lu is not an MPElementStoredEntity, but a %@.", wrn( @"Element with stored type %lu is not an MPSiteStoredEntity, but a %@.",
(long)element.type, [element class] ); (long)element.type, [element class] );
return NO; return NO;
} }
@ -463,7 +473,7 @@
(__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly, (__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
#endif #endif
}]; }];
((MPElementStoredEntity *)element).contentObject = nil; ((MPSiteStoredEntity *)element).contentObject = nil;
return YES; return YES;
} }
} }
@ -471,12 +481,12 @@
Throw( @"Unsupported type: %ld", (long)element.type ); Throw( @"Unsupported type: %ld", (long)element.type );
} }
- (NSString *)resolveLoginForElement:(MPElementEntity *)element usingKey:(MPKey *)elementKey { - (NSString *)resolveLoginForSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey {
dispatch_group_t group = dispatch_group_create(); dispatch_group_t group = dispatch_group_create();
dispatch_group_enter( group ); dispatch_group_enter( group );
__block NSString *result = nil; __block NSString *result = nil;
[self resolveLoginForElement:element usingKey:elementKey result:^(NSString *result_) { [self resolveLoginForSite:element usingKey:elementKey result:^(NSString *result_) {
result = result_; result = result_;
dispatch_group_leave( group ); dispatch_group_leave( group );
}]; }];
@ -485,12 +495,12 @@
return result; return result;
} }
- (NSString *)resolvePasswordForElement:(MPElementEntity *)element usingKey:(MPKey *)elementKey { - (NSString *)resolvePasswordForSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey {
dispatch_group_t group = dispatch_group_create(); dispatch_group_t group = dispatch_group_create();
dispatch_group_enter( group ); dispatch_group_enter( group );
__block NSString *result = nil; __block NSString *result = nil;
[self resolvePasswordForElement:element usingKey:elementKey result:^(NSString *result_) { [self resolvePasswordForSite:element usingKey:elementKey result:^(NSString *result_) {
result = result_; result = result_;
dispatch_group_leave( group ); dispatch_group_leave( group );
}]; }];
@ -499,7 +509,7 @@
return result; return result;
} }
- (void)resolveLoginForElement:(MPElementEntity *)element usingKey:(MPKey *)elementKey result:(void ( ^ )(NSString *result))resultBlock { - (void)resolveLoginForSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey result:(void ( ^ )(NSString *result))resultBlock {
NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." ); NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." );
NSString *name = element.name; NSString *name = element.name;
@ -521,25 +531,26 @@
} ); } );
} }
- (void)resolvePasswordForElement:(MPElementEntity *)element usingKey:(MPKey *)elementKey result:(void ( ^ )(NSString *result))resultBlock { - (void)resolvePasswordForSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey result:(void ( ^ )(NSString *result))resultBlock {
NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." ); NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." );
switch (element.type) { switch (element.type) {
case MPElementTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
case MPElementTypeGeneratedLong: case MPSiteTypeGeneratedLong:
case MPElementTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
case MPElementTypeGeneratedBasic: case MPSiteTypeGeneratedBasic:
case MPElementTypeGeneratedShort: case MPSiteTypeGeneratedShort:
case MPElementTypeGeneratedPIN: case MPSiteTypeGeneratedPIN:
case MPElementTypeGeneratedName: { case MPSiteTypeGeneratedName:
case MPSiteTypeGeneratedPhrase: {
if (![element isKindOfClass:[MPElementGeneratedEntity class]]) { if (![element isKindOfClass:[MPElementGeneratedEntity class]]) {
wrn( @"Element with generated type %lu is not an MPElementGeneratedEntity, but a %@.", wrn( @"Element with generated type %lu is not an MPSiteGeneratedEntity, but a %@.",
(long)element.type, [element class] ); (long)element.type, [element class] );
break; break;
} }
NSString *name = element.name; NSString *name = element.name;
MPElementType type = element.type; MPSiteType type = element.type;
NSUInteger counter = ((MPElementGeneratedEntity *)element).counter; NSUInteger counter = ((MPElementGeneratedEntity *)element).counter;
id<MPAlgorithm> algorithm = nil; id<MPAlgorithm> algorithm = nil;
if (!element.name.length) if (!element.name.length)
@ -556,14 +567,14 @@
break; break;
} }
case MPElementTypeStoredPersonal: { case MPSiteTypeStoredPersonal: {
if (![element isKindOfClass:[MPElementStoredEntity class]]) { if (![element isKindOfClass:[MPSiteStoredEntity class]]) {
wrn( @"Element with stored type %lu is not an MPElementStoredEntity, but a %@.", wrn( @"Element with stored type %lu is not an MPSiteStoredEntity, but a %@.",
(long)element.type, [element class] ); (long)element.type, [element class] );
break; break;
} }
NSData *encryptedContent = ((MPElementStoredEntity *)element).contentObject; NSData *encryptedContent = ((MPSiteStoredEntity *)element).contentObject;
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{ dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
NSString *result = [self decryptContent:encryptedContent usingKey:elementKey]; NSString *result = [self decryptContent:encryptedContent usingKey:elementKey];
@ -571,9 +582,9 @@
} ); } );
break; break;
} }
case MPElementTypeStoredDevicePrivate: { case MPSiteTypeStoredDevicePrivate: {
NSAssert( [element isKindOfClass:[MPElementStoredEntity class]], NSAssert( [element isKindOfClass:[MPSiteStoredEntity class]],
@"Element with stored type %lu is not an MPElementStoredEntity, but a %@.", (long)element.type, @"Element with stored type %lu is not an MPSiteStoredEntity, but a %@.", (long)element.type,
[element class] ); [element class] );
NSDictionary *elementQuery = [self queryForDevicePrivateElementNamed:element.name]; NSDictionary *elementQuery = [self queryForDevicePrivateElementNamed:element.name];
@ -589,93 +600,96 @@
} }
- (void)importProtectedPassword:(NSString *)protectedContent protectedByKey:(MPKey *)importKey - (void)importProtectedPassword:(NSString *)protectedContent protectedByKey:(MPKey *)importKey
intoElement:(MPElementEntity *)element usingKey:(MPKey *)elementKey { intoSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey {
NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." ); NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." );
switch (element.type) { switch (element.type) {
case MPElementTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
case MPElementTypeGeneratedLong: case MPSiteTypeGeneratedLong:
case MPElementTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
case MPElementTypeGeneratedBasic: case MPSiteTypeGeneratedBasic:
case MPElementTypeGeneratedShort: case MPSiteTypeGeneratedShort:
case MPElementTypeGeneratedPIN: case MPSiteTypeGeneratedPIN:
case MPElementTypeGeneratedName: case MPSiteTypeGeneratedName:
case MPSiteTypeGeneratedPhrase:
break; break;
case MPElementTypeStoredPersonal: { case MPSiteTypeStoredPersonal: {
if (![element isKindOfClass:[MPElementStoredEntity class]]) { if (![element isKindOfClass:[MPSiteStoredEntity class]]) {
wrn( @"Element with stored type %lu is not an MPElementStoredEntity, but a %@.", wrn( @"Element with stored type %lu is not an MPSiteStoredEntity, but a %@.",
(long)element.type, [element class] ); (long)element.type, [element class] );
break; break;
} }
if ([importKey.keyID isEqualToData:elementKey.keyID]) if ([importKey.keyID isEqualToData:elementKey.keyID])
((MPElementStoredEntity *)element).contentObject = [protectedContent decodeBase64]; ((MPSiteStoredEntity *)element).contentObject = [protectedContent decodeBase64];
else { else {
NSString *clearContent = [self decryptContent:[protectedContent decodeBase64] usingKey:importKey]; NSString *clearContent = [self decryptContent:[protectedContent decodeBase64] usingKey:importKey];
[self importClearTextPassword:clearContent intoElement:element usingKey:elementKey]; [self importClearTextPassword:clearContent intoSite:element usingKey:elementKey];
} }
break; break;
} }
case MPElementTypeStoredDevicePrivate: case MPSiteTypeStoredDevicePrivate:
break; break;
} }
} }
- (void)importClearTextPassword:(NSString *)clearContent intoElement:(MPElementEntity *)element usingKey:(MPKey *)elementKey { - (void)importClearTextPassword:(NSString *)clearContent intoSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey {
NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." ); NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." );
switch (element.type) { switch (element.type) {
case MPElementTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
case MPElementTypeGeneratedLong: case MPSiteTypeGeneratedLong:
case MPElementTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
case MPElementTypeGeneratedBasic: case MPSiteTypeGeneratedBasic:
case MPElementTypeGeneratedShort: case MPSiteTypeGeneratedShort:
case MPElementTypeGeneratedPIN: case MPSiteTypeGeneratedPIN:
case MPElementTypeGeneratedName: case MPSiteTypeGeneratedName:
case MPSiteTypeGeneratedPhrase:
break; break;
case MPElementTypeStoredPersonal: { case MPSiteTypeStoredPersonal: {
[self savePassword:clearContent toElement:element usingKey:elementKey]; [self savePassword:clearContent toSite:element usingKey:elementKey];
break; break;
} }
case MPElementTypeStoredDevicePrivate: case MPSiteTypeStoredDevicePrivate:
break; break;
} }
} }
- (NSString *)exportPasswordForElement:(MPElementEntity *)element usingKey:(MPKey *)elementKey { - (NSString *)exportPasswordForSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey {
NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." ); NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." );
if (!(element.type & MPElementFeatureExportContent)) if (!(element.type & MPSiteFeatureExportContent))
return nil; return nil;
NSString *result = nil; NSString *result = nil;
switch (element.type) { switch (element.type) {
case MPElementTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
case MPElementTypeGeneratedLong: case MPSiteTypeGeneratedLong:
case MPElementTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
case MPElementTypeGeneratedBasic: case MPSiteTypeGeneratedBasic:
case MPElementTypeGeneratedShort: case MPSiteTypeGeneratedShort:
case MPElementTypeGeneratedPIN: case MPSiteTypeGeneratedPIN:
case MPElementTypeGeneratedName: { case MPSiteTypeGeneratedName:
case MPSiteTypeGeneratedPhrase: {
result = nil; result = nil;
break; break;
} }
case MPElementTypeStoredPersonal: { case MPSiteTypeStoredPersonal: {
if (![element isKindOfClass:[MPElementStoredEntity class]]) { if (![element isKindOfClass:[MPSiteStoredEntity class]]) {
wrn( @"Element with stored type %lu is not an MPElementStoredEntity, but a %@.", wrn( @"Element with stored type %lu is not an MPSiteStoredEntity, but a %@.",
(long)element.type, [element class] ); (long)element.type, [element class] );
break; break;
} }
result = [((MPElementStoredEntity *)element).contentObject encodeBase64]; result = [((MPSiteStoredEntity *)element).contentObject encodeBase64];
break; break;
} }
case MPElementTypeStoredDevicePrivate: { case MPSiteTypeStoredDevicePrivate: {
result = nil; result = nil;
break; break;
} }
@ -710,7 +724,7 @@
return [[NSString alloc] initWithBytes:decryptedContent.bytes length:decryptedContent.length encoding:NSUTF8StringEncoding]; return [[NSString alloc] initWithBytes:decryptedContent.bytes length:decryptedContent.length encoding:NSUTF8StringEncoding];
} }
- (BOOL)timeToCrack:(out TimeToCrack *)timeToCrack passwordOfType:(MPElementType)type byAttacker:(MPAttacker)attacker { - (BOOL)timeToCrack:(out TimeToCrack *)timeToCrack passwordOfType:(MPSiteType)type byAttacker:(MPAttacker)attacker {
if (!type) if (!type)
return NO; return NO;

View File

@ -25,14 +25,14 @@
return 1; return 1;
} }
- (BOOL)migrateElement:(MPElementEntity *)element explicit:(BOOL)explicit { - (BOOL)migrateSite:(MPSiteEntity *)element explicit:(BOOL)explicit {
if (element.version != [self version] - 1) if (element.version != [self version] - 1)
// Only migrate from previous version. // Only migrate from previous version.
return NO; return NO;
if (!explicit) { if (!explicit) {
if (element.type & MPElementTypeClassGenerated) { if (element.type & MPSiteTypeClassGenerated) {
// This migration requires explicit permission for types of the generated class. // This migration requires explicit permission for types of the generated class.
element.requiresExplicitMigration = YES; element.requiresExplicitMigration = YES;
return NO; return NO;
@ -45,8 +45,8 @@
return YES; return YES;
} }
- (NSString *)generateContentForSiteNamed:(NSString *)name ofType:(MPElementType)type withCounter:(NSUInteger)counter - (NSString *)generateContentForSiteNamed:(NSString *)name ofType:(MPSiteType)type withCounter:(NSUInteger)counter
variant:(MPElementVariant)variant usingKey:(MPKey *)key { variant:(MPSiteVariant)variant usingKey:(MPKey *)key {
// Determine the seed whose bytes will be used for calculating a password // Determine the seed whose bytes will be used for calculating a password
uint32_t ncounter = htonl( counter ), nnameLength = htonl( name.length ); uint32_t ncounter = htonl( counter ), nnameLength = htonl( name.length );

View File

@ -176,10 +176,10 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
(long)[user.elements count] )]; (long)[user.elements count] )];
#endif #endif
for (MPElementEntity *element in user.elements) { for (MPSiteEntity *element in user.elements) {
if (element.type & MPElementTypeClassStored) { if (element.type & MPSiteTypeClassStored) {
NSString *content; NSString *content;
while (!(content = [element.algorithm storedPasswordForElement:(MPElementStoredEntity *)element usingKey:recoverKey])) { while (!(content = [element.algorithm storedPasswordForSite:(MPElementStoredEntity *)element usingKey:recoverKey])) {
// Failed to decrypt element with the current recoveryKey. Ask user for a new one to use. // Failed to decrypt element with the current recoveryKey. Ask user for a new one to use.
__block NSString *masterPassword = nil; __block NSString *masterPassword = nil;
@ -216,7 +216,7 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
break; break;
if (![recoverKey isEqualToKey:newKey]) if (![recoverKey isEqualToKey:newKey])
[element.algorithm savePassword:content toElement:element usingKey:newKey]; [element.algorithm savePassword:content toSite:element usingKey:newKey];
} }
} }

View File

@ -29,8 +29,8 @@ typedef NS_ENUM( NSUInteger, MPImportResult ) {
- (MPFixableResult)findAndFixInconsistenciesSaveInContext:(NSManagedObjectContext *)context; - (MPFixableResult)findAndFixInconsistenciesSaveInContext:(NSManagedObjectContext *)context;
/** @param completion The block to execute after adding the element, executed from the main thread with the new element in the main MOC. */ /** @param completion The block to execute after adding the element, executed from the main thread with the new element in the main MOC. */
- (void)addElementNamed:(NSString *)siteName completion:(void ( ^ )(MPElementEntity *element, NSManagedObjectContext *context))completion; - (void)addSiteNamed:(NSString *)siteName completion:(void ( ^ )(MPSiteEntity *element, NSManagedObjectContext *context))completion;
- (MPElementEntity *)changeElement:(MPElementEntity *)element saveInContext:(NSManagedObjectContext *)context toType:(MPElementType)type; - (MPSiteEntity *)changeSite:(MPSiteEntity *)site saveInContext:(NSManagedObjectContext *)context toType:(MPSiteType)type;
- (MPImportResult)importSites:(NSString *)importedSitesString - (MPImportResult)importSites:(NSString *)importedSitesString
askImportPassword:(NSString *(^)(NSString *userName))importPassword askImportPassword:(NSString *(^)(NSString *userName))importPassword
askUserPassword:(NSString *(^)(NSString *userName, NSUInteger importCount, NSUInteger deleteCount))userPassword; askUserPassword:(NSString *(^)(NSString *userName, NSUInteger importCount, NSUInteger deleteCount))userPassword;

View File

@ -333,7 +333,7 @@ PearlAssociatedObjectProperty( NSManagedObjectContext*, MainManagedObjectContext
#pragma mark - Utilities #pragma mark - Utilities
- (void)addElementNamed:(NSString *)siteName completion:(void ( ^ )(MPElementEntity *element, NSManagedObjectContext *context))completion { - (void)addSiteNamed:(NSString *)siteName completion:(void ( ^ )(MPSiteEntity *site, NSManagedObjectContext *context))completion {
if (![siteName length]) { if (![siteName length]) {
completion( nil, nil ); completion( nil, nil );
@ -348,61 +348,61 @@ PearlAssociatedObjectProperty( NSManagedObjectContext*, MainManagedObjectContext
return; return;
} }
MPElementType type = activeUser.defaultType; MPSiteType type = activeUser.defaultType;
NSString *typeEntityName = [MPAlgorithmDefault classNameOfType:type]; NSString *typeEntityName = [MPAlgorithmDefault classNameOfType:type];
MPElementEntity *element = [NSEntityDescription insertNewObjectForEntityForName:typeEntityName inManagedObjectContext:context]; MPSiteEntity *site = [NSEntityDescription insertNewObjectForEntityForName:typeEntityName inManagedObjectContext:context];
element.name = siteName; site.name = siteName;
element.user = activeUser; site.user = activeUser;
element.type = type; site.type = type;
element.lastUsed = [NSDate date]; site.lastUsed = [NSDate date];
element.version = MPAlgorithmDefaultVersion; site.version = MPAlgorithmDefaultVersion;
NSError *error = nil; NSError *error = nil;
if (element.objectID.isTemporaryID && ![context obtainPermanentIDsForObjects:@[ element ] error:&error]) if (site.objectID.isTemporaryID && ![context obtainPermanentIDsForObjects:@[ site ] error:&error])
err( @"Failed to obtain a permanent object ID after creating new element: %@", error ); err( @"Failed to obtain a permanent object ID after creating new site: %@", error );
[context saveToStore]; [context saveToStore];
completion( element, context ); completion( site, context );
}]; }];
} }
- (MPElementEntity *)changeElement:(MPElementEntity *)element saveInContext:(NSManagedObjectContext *)context toType:(MPElementType)type { - (MPSiteEntity *)changeSite:(MPSiteEntity *)site saveInContext:(NSManagedObjectContext *)context toType:(MPSiteType)type {
if (element.type == type) if (site.type == type)
return element; return site;
if ([element.algorithm classOfType:type] == element.typeClass) { if ([site.algorithm classOfType:type] == site.typeClass) {
element.type = type; site.type = type;
[context saveToStore]; [context saveToStore];
} }
else { else {
// Type requires a different class of element. Recreate the element. // Type requires a different class of site. Recreate the site.
NSString *typeEntityName = [element.algorithm classNameOfType:type]; NSString *typeEntityName = [site.algorithm classNameOfType:type];
MPElementEntity *newElement = [NSEntityDescription insertNewObjectForEntityForName:typeEntityName inManagedObjectContext:context]; MPSiteEntity *newSite = [NSEntityDescription insertNewObjectForEntityForName:typeEntityName inManagedObjectContext:context];
newElement.type = type; newSite.type = type;
newElement.name = element.name; newSite.name = site.name;
newElement.user = element.user; newSite.user = site.user;
newElement.uses = element.uses; newSite.uses = site.uses;
newElement.lastUsed = element.lastUsed; newSite.lastUsed = site.lastUsed;
newElement.version = element.version; newSite.version = site.version;
newElement.loginName = element.loginName; newSite.loginName = site.loginName;
NSError *error = nil; NSError *error = nil;
if (![context obtainPermanentIDsForObjects:@[ newElement ] error:&error]) if (![context obtainPermanentIDsForObjects:@[ newSite ] error:&error])
err( @"Failed to obtain a permanent object ID after changing object type: %@", error ); err( @"Failed to obtain a permanent object ID after changing object type: %@", error );
[context deleteObject:element]; [context deleteObject:site];
[context saveToStore]; [context saveToStore];
[[NSNotificationCenter defaultCenter] postNotificationName:MPElementUpdatedNotification object:element.objectID]; [[NSNotificationCenter defaultCenter] postNotificationName:MPSiteUpdatedNotification object:site.objectID];
element = newElement; site = newSite;
} }
[[NSNotificationCenter defaultCenter] postNotificationName:MPElementUpdatedNotification object:element.objectID]; [[NSNotificationCenter defaultCenter] postNotificationName:MPSiteUpdatedNotification object:site.objectID];
return element; return site;
} }
- (MPImportResult)importSites:(NSString *)importedSitesString - (MPImportResult)importSites:(NSString *)importedSitesString
@ -467,9 +467,9 @@ PearlAssociatedObjectProperty( NSManagedObjectContext*, MainManagedObjectContext
NSData *importKeyID = nil; NSData *importKeyID = nil;
BOOL headerStarted = NO, headerEnded = NO, clearText = NO; BOOL headerStarted = NO, headerEnded = NO, clearText = NO;
NSArray *importedSiteLines = [importedSitesString componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; NSArray *importedSiteLines = [importedSitesString componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]];
NSMutableSet *elementsToDelete = [NSMutableSet set]; NSMutableSet *sitesToDelete = [NSMutableSet set];
NSMutableArray *importedSiteElements = [NSMutableArray arrayWithCapacity:[importedSiteLines count]]; NSMutableArray *importedSiteSites = [NSMutableArray arrayWithCapacity:[importedSiteLines count]];
NSFetchRequest *elementFetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPElementEntity class] )]; NSFetchRequest *siteFetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
for (NSString *importedSiteLine in importedSiteLines) { for (NSString *importedSiteLine in importedSiteLines) {
if ([importedSiteLine hasPrefix:@"#"]) { if ([importedSiteLine hasPrefix:@"#"]) {
// Comment or header // Comment or header
@ -491,10 +491,10 @@ PearlAssociatedObjectProperty( NSManagedObjectContext*, MainManagedObjectContext
err( @"Invalid header format in line: %@", importedSiteLine ); err( @"Invalid header format in line: %@", importedSiteLine );
return MPImportResultMalformedInput; return MPImportResultMalformedInput;
} }
NSTextCheckingResult *headerElements = [[headerPattern matchesInString:importedSiteLine options:(NSMatchingOptions)0 NSTextCheckingResult *headerSites = [[headerPattern matchesInString:importedSiteLine options:(NSMatchingOptions)0
range:NSMakeRange( 0, [importedSiteLine length] )] lastObject]; range:NSMakeRange( 0, [importedSiteLine length] )] lastObject];
NSString *headerName = [importedSiteLine substringWithRange:[headerElements rangeAtIndex:1]]; NSString *headerName = [importedSiteLine substringWithRange:[headerSites rangeAtIndex:1]];
NSString *headerValue = [importedSiteLine substringWithRange:[headerElements rangeAtIndex:2]]; NSString *headerValue = [importedSiteLine substringWithRange:[headerSites rangeAtIndex:2]];
if ([headerName isEqualToString:@"User Name"]) { if ([headerName isEqualToString:@"User Name"]) {
importUserName = headerValue; importUserName = headerValue;
@ -586,27 +586,27 @@ PearlAssociatedObjectProperty( NSManagedObjectContext*, MainManagedObjectContext
// Find existing site. // Find existing site.
if (user) { if (user) {
elementFetchRequest.predicate = [NSPredicate predicateWithFormat:@"name == %@ AND user == %@", siteName, user]; siteFetchRequest.predicate = [NSPredicate predicateWithFormat:@"name == %@ AND user == %@", siteName, user];
NSArray *existingSites = [context executeFetchRequest:elementFetchRequest error:&error]; NSArray *existingSites = [context executeFetchRequest:siteFetchRequest error:&error];
if (!existingSites) { if (!existingSites) {
err( @"Lookup of existing sites failed for site: %@, user: %@, error: %@", siteName, user.userID, error ); err( @"Lookup of existing sites failed for site: %@, user: %@, error: %@", siteName, user.userID, error );
return MPImportResultInternalError; return MPImportResultInternalError;
} }
if ([existingSites count]) { if ([existingSites count]) {
dbg( @"Existing sites: %@", existingSites ); dbg( @"Existing sites: %@", existingSites );
[elementsToDelete addObjectsFromArray:existingSites]; [sitesToDelete addObjectsFromArray:existingSites];
} }
} }
[importedSiteElements addObject:@[ lastUsed, uses, type, version, counter, loginName, siteName, exportContent ]]; [importedSiteSites addObject:@[ lastUsed, uses, type, version, counter, loginName, siteName, exportContent ]];
dbg( @"Will import site: lastUsed=%@, uses=%@, type=%@, version=%@, counter=%@, loginName=%@, siteName=%@, exportContent=%@", dbg( @"Will import site: lastUsed=%@, uses=%@, type=%@, version=%@, counter=%@, loginName=%@, siteName=%@, exportContent=%@",
lastUsed, uses, type, version, counter, loginName, siteName, exportContent ); lastUsed, uses, type, version, counter, loginName, siteName, exportContent );
} }
// Ask for confirmation to import these sites and the master password of the user. // Ask for confirmation to import these sites and the master password of the user.
inf( @"Importing %lu sites, deleting %lu sites, for user: %@", (unsigned long)[importedSiteElements count], inf( @"Importing %lu sites, deleting %lu sites, for user: %@", (unsigned long)[importedSiteSites count],
(unsigned long)[elementsToDelete count], [MPUserEntity idFor:importUserName] ); (unsigned long)[sitesToDelete count], [MPUserEntity idFor:importUserName] );
NSString *userMasterPassword = askUserPassword( user? user.name: importUserName, [importedSiteElements count], NSString *userMasterPassword = askUserPassword( user? user.name: importUserName, [importedSiteSites count],
[elementsToDelete count] ); [sitesToDelete count] );
if (!userMasterPassword) { if (!userMasterPassword) {
inf( @"Import cancelled." ); inf( @"Import cancelled." );
return MPImportResultCancelled; return MPImportResultCancelled;
@ -622,8 +622,8 @@ PearlAssociatedObjectProperty( NSManagedObjectContext*, MainManagedObjectContext
// Delete existing sites. // Delete existing sites.
if (elementsToDelete.count) if (sitesToDelete.count)
[elementsToDelete enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { [sitesToDelete enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
inf( @"Deleting site: %@, it will be replaced by an imported site.", [obj name] ); inf( @"Deleting site: %@, it will be replaced by an imported site.", [obj name] );
[context deleteObject:obj]; [context deleteObject:obj];
}]; }];
@ -644,10 +644,10 @@ PearlAssociatedObjectProperty( NSManagedObjectContext*, MainManagedObjectContext
} }
// Import new sites. // Import new sites.
for (NSArray *siteElements in importedSiteElements) { for (NSArray *siteElements in importedSiteSites) {
NSDate *lastUsed = [[NSDateFormatter rfc3339DateFormatter] dateFromString:siteElements[0]]; NSDate *lastUsed = [[NSDateFormatter rfc3339DateFormatter] dateFromString:siteElements[0]];
NSUInteger uses = (unsigned)[siteElements[1] integerValue]; NSUInteger uses = (unsigned)[siteElements[1] integerValue];
MPElementType type = (MPElementType)[siteElements[2] integerValue]; MPSiteType type = (MPSiteType)[siteElements[2] integerValue];
NSUInteger version = (unsigned)[siteElements[3] integerValue]; NSUInteger version = (unsigned)[siteElements[3] integerValue];
NSUInteger counter = [siteElements[4] length]? (unsigned)[siteElements[4] integerValue]: NSNotFound; NSUInteger counter = [siteElements[4] length]? (unsigned)[siteElements[4] integerValue]: NSNotFound;
NSString *loginName = [siteElements[5] length]? siteElements[5]: nil; NSString *loginName = [siteElements[5] length]? siteElements[5]: nil;
@ -656,7 +656,7 @@ PearlAssociatedObjectProperty( NSManagedObjectContext*, MainManagedObjectContext
// Create new site. // Create new site.
NSString *typeEntityName = [MPAlgorithmForVersion( version ) classNameOfType:type]; NSString *typeEntityName = [MPAlgorithmForVersion( version ) classNameOfType:type];
MPElementEntity *element = [NSEntityDescription insertNewObjectForEntityForName:typeEntityName inManagedObjectContext:context]; MPSiteEntity *element = [NSEntityDescription insertNewObjectForEntityForName:typeEntityName inManagedObjectContext:context];
element.name = siteName; element.name = siteName;
element.loginName = loginName; element.loginName = loginName;
element.user = user; element.user = user;
@ -666,9 +666,9 @@ PearlAssociatedObjectProperty( NSManagedObjectContext*, MainManagedObjectContext
element.version = version; element.version = version;
if ([exportContent length]) { if ([exportContent length]) {
if (clearText) if (clearText)
[element.algorithm importClearTextPassword:exportContent intoElement:element usingKey:userKey]; [element.algorithm importClearTextPassword:exportContent intoSite:element usingKey:userKey];
else else
[element.algorithm importProtectedPassword:exportContent protectedByKey:importKey intoElement:element usingKey:userKey]; [element.algorithm importProtectedPassword:exportContent protectedByKey:importKey intoSite:element usingKey:userKey];
} }
if ([element isKindOfClass:[MPElementGeneratedEntity class]] && counter != NSNotFound) if ([element isKindOfClass:[MPElementGeneratedEntity class]] && counter != NSNotFound)
((MPElementGeneratedEntity *)element).counter = counter; ((MPElementGeneratedEntity *)element).counter = counter;
@ -719,10 +719,10 @@ PearlAssociatedObjectProperty( NSManagedObjectContext*, MainManagedObjectContext
[export appendFormat:@"# used used type name\t name\tpassword\n"]; [export appendFormat:@"# used used type name\t name\tpassword\n"];
// Sites. // Sites.
for (MPElementEntity *element in activeUser.elements) { for (MPSiteEntity *element in activeUser.elements) {
NSDate *lastUsed = element.lastUsed; NSDate *lastUsed = element.lastUsed;
NSUInteger uses = element.uses; NSUInteger uses = element.uses;
MPElementType type = element.type; MPSiteType type = element.type;
NSUInteger version = element.version; NSUInteger version = element.version;
NSUInteger counter = 0; NSUInteger counter = 0;
NSString *loginName = element.loginName; NSString *loginName = element.loginName;
@ -735,11 +735,11 @@ PearlAssociatedObjectProperty( NSManagedObjectContext*, MainManagedObjectContext
// Determine the content to export. // Determine the content to export.
if (!(type & MPElementFeatureDevicePrivate)) { if (!(type & MPSiteFeatureDevicePrivate)) {
if (revealPasswords) if (revealPasswords)
content = [element.algorithm resolvePasswordForElement:element usingKey:self.key]; content = [element.algorithm resolvePasswordForSite:element usingKey:self.key];
else if (type & MPElementFeatureExportContent) else if (type & MPSiteFeatureExportContent)
content = [element.algorithm exportPasswordForElement:element usingKey:self.key]; content = [element.algorithm exportPasswordForSite:element usingKey:self.key];
} }
[export appendFormat:@"%@ %8ld %8s %25s\t%25s\t%@\n", [export appendFormat:@"%@ %8ld %8s %25s\t%25s\t%@\n",

View File

@ -1,27 +0,0 @@
//
// MPElementEntity.h
// MasterPassword-iOS
//
// Created by Maarten Billemont on 2014-09-14.
// Copyright (c) 2014 Lyndir. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class MPUserEntity;
@interface MPElementEntity : NSManagedObject
//@property (nonatomic, retain) id content; // Hide here, reveal in MPElementStoredEntity
@property (nonatomic, retain) NSDate * lastUsed;
@property (nonatomic, retain) NSString * loginName;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSNumber * requiresExplicitMigration_;
@property (nonatomic, retain) NSNumber * type_;
@property (nonatomic, retain) NSNumber * uses_;
@property (nonatomic, retain) NSNumber * version_;
@property (nonatomic, retain) NSNumber * loginGenerated_;
@property (nonatomic, retain) MPUserEntity *user;
@end

View File

@ -1,26 +0,0 @@
//
// MPElementEntity.m
// MasterPassword-iOS
//
// Created by Maarten Billemont on 2014-09-14.
// Copyright (c) 2014 Lyndir. All rights reserved.
//
#import "MPElementEntity.h"
#import "MPUserEntity.h"
@implementation MPElementEntity
//@dynamic content;
@dynamic lastUsed;
@dynamic loginName;
@dynamic name;
@dynamic requiresExplicitMigration_;
@dynamic type_;
@dynamic uses_;
@dynamic version_;
@dynamic loginGenerated_;
@dynamic user;
@end

View File

@ -1,18 +0,0 @@
//
// MPElementGeneratedEntity.h
// MasterPassword-iOS
//
// Created by Maarten Billemont on 2014-09-14.
// Copyright (c) 2014 Lyndir. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import "MPElementEntity.h"
@interface MPElementGeneratedEntity : MPElementEntity
@property (nonatomic, retain) NSNumber * counter_;
@end

View File

@ -1,16 +0,0 @@
//
// MPElementGeneratedEntity.m
// MasterPassword-iOS
//
// Created by Maarten Billemont on 2014-09-14.
// Copyright (c) 2014 Lyndir. All rights reserved.
//
#import "MPElementGeneratedEntity.h"
@implementation MPElementGeneratedEntity
@dynamic counter_;
@end

View File

@ -1,18 +0,0 @@
//
// MPElementStoredEntity.h
// MasterPassword-iOS
//
// Created by Maarten Billemont on 2014-09-14.
// Copyright (c) 2014 Lyndir. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import "MPElementEntity.h"
@interface MPElementStoredEntity : MPElementEntity
@property (nonatomic, retain) NSData * contentObject;
@end

View File

@ -1,16 +0,0 @@
//
// MPElementStoredEntity.m
// MasterPassword-iOS
//
// Created by Maarten Billemont on 2014-09-14.
// Copyright (c) 2014 Lyndir. All rights reserved.
//
#import "MPElementStoredEntity.h"
@implementation MPElementStoredEntity
@dynamic contentObject;
@end

View File

@ -1,5 +1,5 @@
// //
// MPElementEntities.h // MPEntities.h
// MasterPassword-iOS // MasterPassword-iOS
// //
// Created by Maarten Billemont on 31/05/12. // Created by Maarten Billemont on 31/05/12.
@ -7,9 +7,9 @@
// //
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "MPElementEntity.h" #import "MPSiteEntity.h"
#import "MPElementStoredEntity.h" #import "MPSiteStoredEntity.h"
#import "MPElementGeneratedEntity.h" #import "MPSiteGeneratedEntity.h"
#import "MPUserEntity.h" #import "MPUserEntity.h"
#import "MPAlgorithm.h" #import "MPAlgorithm.h"
#import "MPFixable.h" #import "MPFixable.h"
@ -22,10 +22,10 @@
@end @end
@interface MPElementEntity(MP)<MPFixable> @interface MPSiteEntity(MP)<MPFixable>
@property(assign) BOOL loginGenerated; @property(assign) BOOL loginGenerated;
@property(assign) MPElementType type; @property(assign) MPSiteType type;
@property(readonly) NSString *typeName; @property(readonly) NSString *typeName;
@property(readonly) NSString *typeShortName; @property(readonly) NSString *typeShortName;
@property(readonly) NSString *typeClassName; @property(readonly) NSString *typeClassName;
@ -44,7 +44,7 @@
@end @end
@interface MPElementGeneratedEntity(MP) @interface MPSiteGeneratedEntity(MP)
@property(assign) NSUInteger counter; @property(assign) NSUInteger counter;
@ -54,7 +54,7 @@
@property(assign) NSUInteger avatar; @property(assign) NSUInteger avatar;
@property(assign) BOOL saveKey; @property(assign) BOOL saveKey;
@property(assign) MPElementType defaultType; @property(assign) MPSiteType defaultType;
@property(readonly) NSString *userID; @property(readonly) NSString *userID;
+ (NSString *)idFor:(NSString *)userName; + (NSString *)idFor:(NSString *)userName;

View File

@ -1,5 +1,5 @@
// //
// MPElementEntities.m // MPEntities.m
// MasterPassword-iOS // MasterPassword-iOS
// //
// Created by Maarten Billemont on 31/05/12. // Created by Maarten Billemont on 31/05/12.
@ -34,16 +34,16 @@
@end @end
@implementation MPElementEntity(MP) @implementation MPSiteEntity(MP)
- (MPFixableResult)findAndFixInconsistenciesInContext:(NSManagedObjectContext *)context { - (MPFixableResult)findAndFixInconsistenciesInContext:(NSManagedObjectContext *)context {
return MPFixableResultNoProblems; return MPFixableResultNoProblems;
} }
- (MPElementType)type { - (MPSiteType)type {
return (MPElementType)[self.type_ unsignedIntegerValue]; return (MPSiteType)[self.type_ unsignedIntegerValue];
} }
- (void)setLoginGenerated:(BOOL)aLoginGenerated { - (void)setLoginGenerated:(BOOL)aLoginGenerated {
@ -56,7 +56,7 @@
return [self.loginGenerated_ boolValue]; return [self.loginGenerated_ boolValue];
} }
- (void)setType:(MPElementType)aType { - (void)setType:(MPSiteType)aType {
self.type_ = @(aType); self.type_ = @(aType);
} }
@ -138,11 +138,11 @@
- (BOOL)migrateExplicitly:(BOOL)explicit { - (BOOL)migrateExplicitly:(BOOL)explicit {
while (self.version < MPAlgorithmDefaultVersion) while (self.version < MPAlgorithmDefaultVersion)
if ([MPAlgorithmForVersion( self.version + 1 ) migrateElement:self explicit:explicit]) if ([MPAlgorithmForVersion( self.version + 1 ) migrateSite:self explicit:explicit])
inf( @"%@ migration to version: %ld succeeded for element: %@", inf( @"%@ migration to version: %ld succeeded for site: %@",
explicit? @"Explicit": @"Automatic", (long)self.version + 1, self ); explicit? @"Explicit": @"Automatic", (long)self.version + 1, self );
else { else {
wrn( @"%@ migration to version: %ld failed for element: %@", wrn( @"%@ migration to version: %ld failed for site: %@",
explicit? @"Explicit": @"Automatic", (long)self.version + 1, self ); explicit? @"Explicit": @"Automatic", (long)self.version + 1, self );
return NO; return NO;
} }
@ -152,33 +152,33 @@
- (NSString *)resolveLoginUsingKey:(MPKey *)key { - (NSString *)resolveLoginUsingKey:(MPKey *)key {
return [self.algorithm resolveLoginForElement:self usingKey:key]; return [self.algorithm resolveLoginForSite:self usingKey:key];
} }
- (NSString *)resolvePasswordUsingKey:(MPKey *)key { - (NSString *)resolvePasswordUsingKey:(MPKey *)key {
return [self.algorithm resolvePasswordForElement:self usingKey:key]; return [self.algorithm resolvePasswordForSite:self usingKey:key];
} }
- (void)resolveLoginUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result { - (void)resolveLoginUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result {
[self.algorithm resolveLoginForElement:self usingKey:key result:result]; [self.algorithm resolveLoginForSite:self usingKey:key result:result];
} }
- (void)resolvePasswordUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result { - (void)resolvePasswordUsingKey:(MPKey *)key result:(void ( ^ )(NSString *))result {
[self.algorithm resolvePasswordForElement:self usingKey:key result:result]; [self.algorithm resolvePasswordForSite:self usingKey:key result:result];
} }
@end @end
@implementation MPElementGeneratedEntity(MP) @implementation MPSiteGeneratedEntity(MP)
- (MPFixableResult)findAndFixInconsistenciesInContext:(NSManagedObjectContext *)context { - (MPFixableResult)findAndFixInconsistenciesInContext:(NSManagedObjectContext *)context {
MPFixableResult result = [super findAndFixInconsistenciesInContext:context]; MPFixableResult result = [super findAndFixInconsistenciesInContext:context];
if (!self.type || self.type == (MPElementType)NSNotFound || ![[self.algorithm allTypes] containsObject:self.type_]) if (!self.type || self.type == (MPSiteType)NSNotFound || ![[self.algorithm allTypes] containsObject:self.type_])
// Invalid self.type // Invalid self.type
result = MPApplyFix( result, ^MPFixableResult { result = MPApplyFix( result, ^MPFixableResult {
wrn( @"Invalid type for: %@ of %@, type: %ld. Will use %ld instead.", wrn( @"Invalid type for: %@ of %@, type: %ld. Will use %ld instead.",
@ -186,18 +186,18 @@
self.type = self.user.defaultType; self.type = self.user.defaultType;
return MPFixableResultProblemsFixed; return MPFixableResultProblemsFixed;
} ); } );
if (!self.type || self.type == (MPElementType)NSNotFound || ![[self.algorithm allTypes] containsObject:self.type_]) if (!self.type || self.type == (MPSiteType)NSNotFound || ![[self.algorithm allTypes] containsObject:self.type_])
// Invalid self.user.defaultType // Invalid self.user.defaultType
result = MPApplyFix( result, ^MPFixableResult { result = MPApplyFix( result, ^MPFixableResult {
wrn( @"Invalid type for: %@ of %@, type: %ld. Will use %ld instead.", wrn( @"Invalid type for: %@ of %@, type: %ld. Will use %ld instead.",
self.name, self.user.name, (long)self.type, (long)MPElementTypeGeneratedLong ); self.name, self.user.name, (long)self.type, (long)MPSiteTypeGeneratedLong );
self.type = MPElementTypeGeneratedLong; self.type = MPSiteTypeGeneratedLong;
return MPFixableResultProblemsFixed; return MPFixableResultProblemsFixed;
} ); } );
if (![self isKindOfClass:[self.algorithm classOfType:self.type]]) if (![self isKindOfClass:[self.algorithm classOfType:self.type]])
// Mismatch between self.type and self.class // Mismatch between self.type and self.class
result = MPApplyFix( result, ^MPFixableResult { result = MPApplyFix( result, ^MPFixableResult {
for (MPElementType newType = self.type; self.type != (newType = [self.algorithm nextType:newType]);) for (MPSiteType newType = self.type; self.type != (newType = [self.algorithm nextType:newType]);)
if ([self isKindOfClass:[self.algorithm classOfType:newType]]) { if ([self isKindOfClass:[self.algorithm classOfType:newType]]) {
wrn( @"Mismatching type for: %@ of %@, type: %lu, class: %@. Will use %ld instead.", wrn( @"Mismatching type for: %@ of %@, type: %lu, class: %@. Will use %ld instead.",
self.name, self.user.name, (long)self.type, self.class, (long)newType ); self.name, self.user.name, (long)self.type, self.class, (long)newType );
@ -225,7 +225,7 @@
@end @end
@implementation MPElementStoredEntity(MP) @implementation MPSiteStoredEntity(MP)
- (MPFixableResult)findAndFixInconsistenciesInContext:(NSManagedObjectContext *)context { - (MPFixableResult)findAndFixInconsistenciesInContext:(NSManagedObjectContext *)context {
@ -236,7 +236,7 @@
MPKey *key = [MPAppDelegate_Shared get].key; MPKey *key = [MPAppDelegate_Shared get].key;
if (key && [[MPAppDelegate_Shared get] activeUserInContext:context] == self.user) { if (key && [[MPAppDelegate_Shared get] activeUserInContext:context] == self.user) {
wrn( @"Content object not encrypted for: %@ of %@. Will re-encrypt.", self.name, self.user.name ); wrn( @"Content object not encrypted for: %@ of %@. Will re-encrypt.", self.name, self.user.name );
[self.algorithm savePassword:[self.contentObject description] toElement:self usingKey:key]; [self.algorithm savePassword:[self.contentObject description] toSite:self usingKey:key];
return MPFixableResultProblemsFixed; return MPFixableResultProblemsFixed;
} }
@ -271,12 +271,12 @@
self.saveKey_ = @(aSaveKey); self.saveKey_ = @(aSaveKey);
} }
- (MPElementType)defaultType { - (MPSiteType)defaultType {
return (MPElementType)[self.defaultType_ unsignedIntegerValue]?: MPElementTypeGeneratedLong; return (MPSiteType)[self.defaultType_ unsignedIntegerValue]?: MPSiteTypeGeneratedLong;
} }
- (void)setDefaultType:(MPElementType)aDefaultType { - (void)setDefaultType:(MPSiteType)aDefaultType {
self.defaultType_ = @(aDefaultType); self.defaultType_ = @(aDefaultType);
} }

View File

@ -8,38 +8,39 @@
#import "MPKey.h" #import "MPKey.h"
typedef NS_ENUM(NSUInteger, MPElementTypeClass) { typedef NS_ENUM( NSUInteger, MPSiteTypeClass ) {
/** Generate the password. */ /** Generate the password. */
MPElementTypeClassGenerated = 1 << 4, MPSiteTypeClassGenerated = 1 << 4,
/** Store the password. */ /** Store the password. */
MPElementTypeClassStored = 1 << 5, MPSiteTypeClassStored = 1 << 5,
}; };
typedef NS_ENUM(NSUInteger, MPElementVariant) { typedef NS_ENUM( NSUInteger, MPSiteVariant ) {
/** Generate the password. */ /** Generate the password. */
MPElementVariantPassword, MPSiteVariantPassword,
/** Generate the login name. */ /** Generate the login name. */
MPElementVariantLogin, MPSiteVariantLogin,
}; };
typedef NS_ENUM(NSUInteger, MPElementFeature) { typedef NS_ENUM( NSUInteger, MPSiteFeature ) {
/** Export the key-protected content data. */ /** Export the key-protected content data. */
MPElementFeatureExportContent = 1 << 10, MPSiteFeatureExportContent = 1 << 10,
/** Never export content. */ /** Never export content. */
MPElementFeatureDevicePrivate = 1 << 11, MPSiteFeatureDevicePrivate = 1 << 11,
}; };
typedef NS_ENUM(NSUInteger, MPElementType) { typedef NS_ENUM(NSUInteger, MPSiteType) {
MPElementTypeGeneratedMaximum = 0x0 | MPElementTypeClassGenerated | 0x0, MPSiteTypeGeneratedMaximum = 0x0 | MPSiteTypeClassGenerated | 0x0,
MPElementTypeGeneratedLong = 0x1 | MPElementTypeClassGenerated | 0x0, MPSiteTypeGeneratedLong = 0x1 | MPSiteTypeClassGenerated | 0x0,
MPElementTypeGeneratedMedium = 0x2 | MPElementTypeClassGenerated | 0x0, MPSiteTypeGeneratedMedium = 0x2 | MPSiteTypeClassGenerated | 0x0,
MPElementTypeGeneratedBasic = 0x4 | MPElementTypeClassGenerated | 0x0, MPSiteTypeGeneratedBasic = 0x4 | MPSiteTypeClassGenerated | 0x0,
MPElementTypeGeneratedShort = 0x3 | MPElementTypeClassGenerated | 0x0, MPSiteTypeGeneratedShort = 0x3 | MPSiteTypeClassGenerated | 0x0,
MPElementTypeGeneratedPIN = 0x5 | MPElementTypeClassGenerated | 0x0, MPSiteTypeGeneratedPIN = 0x5 | MPSiteTypeClassGenerated | 0x0,
MPElementTypeGeneratedName = 0xF | MPElementTypeClassGenerated | 0x0, MPSiteTypeGeneratedName = 0xE | MPSiteTypeClassGenerated | 0x0,
MPSiteTypeGeneratedPhrase = 0xF | MPSiteTypeClassGenerated | 0x0,
MPElementTypeStoredPersonal = 0x0 | MPElementTypeClassStored | MPElementFeatureExportContent, MPSiteTypeStoredPersonal = 0x0 | MPSiteTypeClassStored | MPSiteFeatureExportContent,
MPElementTypeStoredDevicePrivate = 0x1 | MPElementTypeClassStored | MPElementFeatureDevicePrivate, MPSiteTypeStoredDevicePrivate = 0x1 | MPSiteTypeClassStored | MPSiteFeatureDevicePrivate,
}; };
#define MPErrorDomain @"MPErrorDomain" #define MPErrorDomain @"MPErrorDomain"
@ -52,7 +53,7 @@ typedef NS_ENUM(NSUInteger, MPElementType) {
#define MPCheckpointEditPassword @"MPCheckpointEditPassword" #define MPCheckpointEditPassword @"MPCheckpointEditPassword"
#define MPCheckpointEditLoginName @"MPCheckpointEditLoginName" #define MPCheckpointEditLoginName @"MPCheckpointEditLoginName"
#define MPCheckpointUseType @"MPCheckpointUseType" #define MPCheckpointUseType @"MPCheckpointUseType"
#define MPCheckpointDeleteElement @"MPCheckpointDeleteElement" #define MPCheckpointDeleteSite @"MPCheckpointDeleteSite"
#define MPCheckpointShowGuide @"MPCheckpointShowGuide" #define MPCheckpointShowGuide @"MPCheckpointShowGuide"
#define MPCheckpointShowSetup @"MPCheckpointShowSetup" #define MPCheckpointShowSetup @"MPCheckpointShowSetup"
#define MPCheckpointChangeMP @"MPCheckpointChangeMP" #define MPCheckpointChangeMP @"MPCheckpointChangeMP"
@ -76,7 +77,7 @@ typedef NS_ENUM(NSUInteger, MPElementType) {
#define MPSignedInNotification @"MPSignedInNotification" #define MPSignedInNotification @"MPSignedInNotification"
#define MPSignedOutNotification @"MPSignedOutNotification" #define MPSignedOutNotification @"MPSignedOutNotification"
#define MPKeyForgottenNotification @"MPKeyForgottenNotification" #define MPKeyForgottenNotification @"MPKeyForgottenNotification"
#define MPElementUpdatedNotification @"MPElementUpdatedNotification" #define MPSiteUpdatedNotification @"MPSiteUpdatedNotification"
#define MPCheckConfigNotification @"MPCheckConfigNotification" #define MPCheckConfigNotification @"MPCheckConfigNotification"
#define MPSitesImportedNotification @"MPSitesImportedNotification" #define MPSitesImportedNotification @"MPSitesImportedNotification"
#define MPFoundInconsistenciesNotification @"MPFoundInconsistenciesNotification" #define MPFoundInconsistenciesNotification @"MPFoundInconsistenciesNotification"
@ -85,6 +86,7 @@ typedef NS_ENUM(NSUInteger, MPElementType) {
#define MPInconsistenciesFixResultUserKey @"MPInconsistenciesFixResultUserKey" #define MPInconsistenciesFixResultUserKey @"MPInconsistenciesFixResultUserKey"
#define MPProductGenerateLogins @"com.lyndir.masterpassword.products.generatelogins" #define MPProductGenerateLogins @"com.lyndir.masterpassword.products.generatelogins"
#define MPProductAdvancedExport @"com.lyndir.masterpassword.products.advancedexport"
static void MPCheckpoint(NSString *checkpoint, NSDictionary *attributes) { static void MPCheckpoint(NSString *checkpoint, NSDictionary *attributes) {

View File

@ -2,14 +2,14 @@
// MPUserEntity.h // MPUserEntity.h
// MasterPassword-iOS // MasterPassword-iOS
// //
// Created by Maarten Billemont on 2014-09-14. // Created by Maarten Billemont on 2014-09-21.
// Copyright (c) 2014 Lyndir. All rights reserved. // Copyright (c) 2014 Lyndir. All rights reserved.
// //
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <CoreData/CoreData.h> #import <CoreData/CoreData.h>
@class MPElementEntity; @class MPSiteEntity;
@interface MPUserEntity : NSManagedObject @interface MPUserEntity : NSManagedObject
@ -24,8 +24,8 @@
@interface MPUserEntity (CoreDataGeneratedAccessors) @interface MPUserEntity (CoreDataGeneratedAccessors)
- (void)addElementsObject:(MPElementEntity *)value; - (void)addElementsObject:(MPSiteEntity *)value;
- (void)removeElementsObject:(MPElementEntity *)value; - (void)removeElementsObject:(MPSiteEntity *)value;
- (void)addElements:(NSSet *)values; - (void)addElements:(NSSet *)values;
- (void)removeElements:(NSSet *)values; - (void)removeElements:(NSSet *)values;

View File

@ -2,12 +2,12 @@
// MPUserEntity.m // MPUserEntity.m
// MasterPassword-iOS // MasterPassword-iOS
// //
// Created by Maarten Billemont on 2014-09-14. // Created by Maarten Billemont on 2014-09-21.
// Copyright (c) 2014 Lyndir. All rights reserved. // Copyright (c) 2014 Lyndir. All rights reserved.
// //
#import "MPUserEntity.h" #import "MPUserEntity.h"
#import "MPElementEntity.h" #import "MPSiteEntity.h"
@implementation MPUserEntity @implementation MPUserEntity

View File

@ -17,12 +17,12 @@
// //
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@class MPElementEntity; @class MPSiteEntity;
@interface MPElementModel : NSObject @interface MPElementModel : NSObject
@property (nonatomic) NSString *siteName; @property (nonatomic) NSString *siteName;
@property (nonatomic) MPElementType type; @property (nonatomic) MPSiteType type;
@property (nonatomic) NSString *typeName; @property (nonatomic) NSString *typeName;
@property (nonatomic) NSString *content; @property (nonatomic) NSString *content;
@property (nonatomic) NSString *contentDisplay; @property (nonatomic) NSString *contentDisplay;
@ -34,8 +34,8 @@
@property (nonatomic) BOOL generated; @property (nonatomic) BOOL generated;
@property (nonatomic) BOOL stored; @property (nonatomic) BOOL stored;
- (id)initWithEntity:(MPElementEntity *)entity; - (id)initWithEntity:(MPSiteEntity *)entity;
- (MPElementEntity *)entityInContext:(NSManagedObjectContext *)moc; - (MPSiteEntity *)entityInContext:(NSManagedObjectContext *)moc;
- (void)updateContent; - (void)updateContent;
@end @end

View File

@ -17,7 +17,7 @@
// //
#import "MPElementModel.h" #import "MPElementModel.h"
#import "MPElementEntity.h" #import "MPSiteEntity.h"
#import "MPEntities.h" #import "MPEntities.h"
#import "MPAppDelegate_Shared.h" #import "MPAppDelegate_Shared.h"
#import "MPAppDelegate_Store.h" #import "MPAppDelegate_Store.h"
@ -28,7 +28,7 @@
BOOL _initialized; BOOL _initialized;
} }
- (id)initWithEntity:(MPElementEntity *)entity { - (id)initWithEntity:(MPSiteEntity *)entity {
if (!(self = [super init])) if (!(self = [super init]))
return nil; return nil;
@ -39,7 +39,7 @@
return self; return self;
} }
- (void)setEntity:(MPElementEntity *)entity { - (void)setEntity:(MPSiteEntity *)entity {
if ([_entityOID isEqual:entity.objectID]) if ([_entityOID isEqual:entity.objectID])
return; return;
@ -58,13 +58,13 @@
[self updateContent:entity]; [self updateContent:entity];
} }
- (MPElementEntity *)entityInContext:(NSManagedObjectContext *)moc { - (MPSiteEntity *)entityInContext:(NSManagedObjectContext *)moc {
if (!_entityOID) if (!_entityOID)
return nil; return nil;
NSError *error; NSError *error;
MPElementEntity *entity = (MPElementEntity *)[moc existingObjectWithID:_entityOID error:&error]; MPSiteEntity *entity = (MPSiteEntity *)[moc existingObjectWithID:_entityOID error:&error];
if (!entity) if (!entity)
err( @"Couldn't retrieve active element: %@", error ); err( @"Couldn't retrieve active element: %@", error );
@ -82,7 +82,7 @@
return; return;
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPElementEntity *entity = [self entityInContext:context]; MPSiteEntity *entity = [self entityInContext:context];
if ([entity isKindOfClass:[MPElementGeneratedEntity class]]) { if ([entity isKindOfClass:[MPElementGeneratedEntity class]]) {
((MPElementGeneratedEntity *)entity).counter = counter; ((MPElementGeneratedEntity *)entity).counter = counter;
[context saveToStore]; [context saveToStore];
@ -94,22 +94,22 @@
- (BOOL)generated { - (BOOL)generated {
return self.type & MPElementTypeClassGenerated; return self.type & MPSiteTypeClassGenerated;
} }
- (BOOL)stored { - (BOOL)stored {
return self.type & MPElementTypeClassStored; return self.type & MPSiteTypeClassStored;
} }
- (void)updateContent { - (void)updateContent {
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
[self updateContent:[MPElementEntity existingObjectWithID:_entityOID inContext:context]]; [self updateContent:[MPSiteEntity existingObjectWithID:_entityOID inContext:context]];
}]; }];
} }
- (void)updateContent:(MPElementEntity *)entity { - (void)updateContent:(MPSiteEntity *)entity {
static NSRegularExpression *re_anyChar; static NSRegularExpression *re_anyChar;
static dispatch_once_t once = 0; static dispatch_once_t once = 0;

View File

@ -229,7 +229,8 @@
switch (returnCode) { switch (returnCode) {
case NSAlertFirstButtonReturn: { case NSAlertFirstButtonReturn: {
// "Create" button. // "Create" button.
[[MPMacAppDelegate get] addElementNamed:[self.siteField stringValue] completion:^(MPElementEntity *element, NSManagedObjectContext *context) { [[MPMacAppDelegate get]
addSiteNamed:[self.siteField stringValue] completion:^(MPSiteEntity *element, NSManagedObjectContext *context) {
if (element) if (element)
PearlMainQueue( ^{ [self updateElements]; } ); PearlMainQueue( ^{ [self updateElements]; } );
}]; }];
@ -243,10 +244,10 @@
switch (returnCode) { switch (returnCode) {
case NSAlertFirstButtonReturn: { case NSAlertFirstButtonReturn: {
// "Save" button. // "Save" button.
MPElementType type = (MPElementType)[self.passwordTypesMatrix.selectedCell tag]; MPSiteType type = (MPSiteType)[self.passwordTypesMatrix.selectedCell tag];
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPElementEntity *entity = [[MPMacAppDelegate get] changeElement:[self.selectedElement entityInContext:context] MPSiteEntity *entity = [[MPMacAppDelegate get] changeSite:[self.selectedElement entityInContext:context]
saveInContext:context toType:type]; saveInContext:context toType:type];
if ([entity isKindOfClass:[MPElementStoredEntity class]] && ![(MPElementStoredEntity *)entity contentObject].length) if ([entity isKindOfClass:[MPElementStoredEntity class]] && ![(MPElementStoredEntity *)entity contentObject].length)
PearlMainQueue( ^{ PearlMainQueue( ^{
[self changePassword:nil]; [self changePassword:nil];
@ -264,7 +265,7 @@
// "Save" button. // "Save" button.
NSString *loginName = [(NSSecureTextField *)alert.accessoryView stringValue]; NSString *loginName = [(NSSecureTextField *)alert.accessoryView stringValue];
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPElementEntity *entity = [self.selectedElement entityInContext:context]; MPSiteEntity *entity = [self.selectedElement entityInContext:context];
entity.loginName = loginName; entity.loginName = loginName;
[context saveToStore]; [context saveToStore];
}]; }];
@ -280,8 +281,8 @@
// "Save" button. // "Save" button.
NSString *password = [(NSSecureTextField *)alert.accessoryView stringValue]; NSString *password = [(NSSecureTextField *)alert.accessoryView stringValue];
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPElementEntity *entity = [self.selectedElement entityInContext:context]; MPSiteEntity *entity = [self.selectedElement entityInContext:context];
[entity.algorithm savePassword:password toElement:entity usingKey:[MPMacAppDelegate get].key]; [entity.algorithm savePassword:password toSite:entity usingKey:[MPMacAppDelegate get].key];
[context saveToStore]; [context saveToStore];
}]; }];
break; break;
@ -397,12 +398,12 @@
- (IBAction)changeType:(id)sender { - (IBAction)changeType:(id)sender {
MPElementModel *element = self.selectedElement; MPElementModel *element = self.selectedElement;
NSArray *types = [element.algorithm allTypesStartingWith:MPElementTypeGeneratedPIN]; NSArray *types = [element.algorithm allTypesStartingWith:MPSiteTypeGeneratedPIN];
[self.passwordTypesMatrix renewRows:(NSInteger)[types count] columns:1]; [self.passwordTypesMatrix renewRows:(NSInteger)[types count] columns:1];
for (NSUInteger t = 0; t < [types count]; ++t) { for (NSUInteger t = 0; t < [types count]; ++t) {
MPElementType type = [types[t] unsignedIntegerValue]; MPSiteType type = [types[t] unsignedIntegerValue];
NSString *title = [element.algorithm nameOfType:type]; NSString *title = [element.algorithm nameOfType:type];
if (type & MPElementTypeClassGenerated) if (type & MPSiteTypeClassGenerated)
title = [element.algorithm generatePasswordForSiteNamed:element.siteName ofType:type title = [element.algorithm generatePasswordForSiteNamed:element.siteName ofType:type
withCounter:element.counter usingKey:[MPMacAppDelegate get].key]; withCounter:element.counter usingKey:[MPMacAppDelegate get].key];
@ -514,7 +515,7 @@
NSString *query = [self query]; NSString *query = [self query];
[profiler finishJob:@"query"]; [profiler finishJob:@"query"];
[MPMacAppDelegate managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *context) { [MPMacAppDelegate managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *context) {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPElementEntity class] )]; NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
fetchRequest.sortDescriptors = [NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"lastUsed" ascending:NO]]; fetchRequest.sortDescriptors = [NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"lastUsed" ascending:NO]];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(%@ == '' OR name BEGINSWITH[cd] %@) AND user == %@", fetchRequest.predicate = [NSPredicate predicateWithFormat:@"(%@ == '' OR name BEGINSWITH[cd] %@) AND user == %@",
query, query, [[MPMacAppDelegate get] activeUserInContext:context]]; query, query, [[MPMacAppDelegate get] activeUserInContext:context]];
@ -529,7 +530,7 @@
[profiler finishJob:@"do fetch"]; [profiler finishJob:@"do fetch"];
NSMutableArray *newElements = [NSMutableArray arrayWithCapacity:[siteResults count]]; NSMutableArray *newElements = [NSMutableArray arrayWithCapacity:[siteResults count]];
for (MPElementEntity *element in siteResults) for (MPSiteEntity *element in siteResults)
[newElements addObject:[[MPElementModel alloc] initWithEntity:element]]; [newElements addObject:[[MPElementModel alloc] initWithEntity:element]];
[profiler finishJob:@"make models"]; [profiler finishJob:@"make models"];
self.elements = newElements; self.elements = newElements;

View File

@ -60,9 +60,6 @@
DA5E5CFA1724A667003798D8 /* MPAppDelegate_Shared.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CA01724A667003798D8 /* MPAppDelegate_Shared.m */; }; DA5E5CFA1724A667003798D8 /* MPAppDelegate_Shared.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CA01724A667003798D8 /* MPAppDelegate_Shared.m */; };
DA5E5CFB1724A667003798D8 /* MPAppDelegate_Store.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CA21724A667003798D8 /* MPAppDelegate_Store.m */; }; DA5E5CFB1724A667003798D8 /* MPAppDelegate_Store.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CA21724A667003798D8 /* MPAppDelegate_Store.m */; };
DA5E5CFC1724A667003798D8 /* MPConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CA41724A667003798D8 /* MPConfig.m */; }; DA5E5CFC1724A667003798D8 /* MPConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CA41724A667003798D8 /* MPConfig.m */; };
DA5E5CFD1724A667003798D8 /* MPElementEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CA61724A667003798D8 /* MPElementEntity.m */; };
DA5E5CFE1724A667003798D8 /* MPElementGeneratedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CA81724A667003798D8 /* MPElementGeneratedEntity.m */; };
DA5E5CFF1724A667003798D8 /* MPElementStoredEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CAA1724A667003798D8 /* MPElementStoredEntity.m */; };
DA5E5D001724A667003798D8 /* MPEntities.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CAC1724A667003798D8 /* MPEntities.m */; }; DA5E5D001724A667003798D8 /* MPEntities.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CAC1724A667003798D8 /* MPEntities.m */; };
DA5E5D011724A667003798D8 /* MPKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CAE1724A667003798D8 /* MPKey.m */; }; DA5E5D011724A667003798D8 /* MPKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CAE1724A667003798D8 /* MPKey.m */; };
DA5E5D021724A667003798D8 /* MPUserEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CB11724A667003798D8 /* MPUserEntity.m */; }; DA5E5D021724A667003798D8 /* MPUserEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA5E5CB11724A667003798D8 /* MPUserEntity.m */; };
@ -78,6 +75,10 @@
DA8ED895192906920099B726 /* PearlTween.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8ED891192906920099B726 /* PearlTween.m */; }; DA8ED895192906920099B726 /* PearlTween.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8ED891192906920099B726 /* PearlTween.m */; };
DA8ED896192906920099B726 /* PearlTween.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8ED892192906920099B726 /* PearlTween.h */; }; DA8ED896192906920099B726 /* PearlTween.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8ED892192906920099B726 /* PearlTween.h */; };
DA8ED897192906920099B726 /* map-macro.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8ED894192906920099B726 /* map-macro.h */; }; DA8ED897192906920099B726 /* map-macro.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8ED894192906920099B726 /* map-macro.h */; };
DA9521BD19CEA3FD002E3AD5 /* MPSiteStoredEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9521B519CEA3FD002E3AD5 /* MPSiteStoredEntity.m */; };
DA9521BE19CEA3FD002E3AD5 /* MPSiteQuestion.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9521B719CEA3FD002E3AD5 /* MPSiteQuestion.m */; };
DA9521BF19CEA3FD002E3AD5 /* MPSiteGeneratedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9521B919CEA3FD002E3AD5 /* MPSiteGeneratedEntity.m */; };
DA9521C019CEA3FD002E3AD5 /* MPSiteEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9521BB19CEA3FD002E3AD5 /* MPSiteEntity.m */; };
DAAA81B0195A8D1300FA30D9 /* gradient.png in Resources */ = {isa = PBXBuildFile; fileRef = DAAA81AF195A8D1300FA30D9 /* gradient.png */; }; DAAA81B0195A8D1300FA30D9 /* gradient.png in Resources */ = {isa = PBXBuildFile; fileRef = DAAA81AF195A8D1300FA30D9 /* gradient.png */; };
DABC6C02175D8C85000C15D4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; }; DABC6C02175D8C85000C15D4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA5BFA4A147E415C00F98B1E /* Foundation.framework */; };
DABC6C15175D8CE1000C15D4 /* RHStatusItemView.m in Sources */ = {isa = PBXBuildFile; fileRef = DABC6C14175D8CE1000C15D4 /* RHStatusItemView.m */; }; DABC6C15175D8CE1000C15D4 /* RHStatusItemView.m in Sources */ = {isa = PBXBuildFile; fileRef = DABC6C14175D8CE1000C15D4 /* RHStatusItemView.m */; };
@ -302,12 +303,6 @@
DA5E5CA21724A667003798D8 /* MPAppDelegate_Store.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_Store.m; sourceTree = "<group>"; }; DA5E5CA21724A667003798D8 /* MPAppDelegate_Store.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_Store.m; sourceTree = "<group>"; };
DA5E5CA31724A667003798D8 /* MPConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPConfig.h; sourceTree = "<group>"; }; DA5E5CA31724A667003798D8 /* MPConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPConfig.h; sourceTree = "<group>"; };
DA5E5CA41724A667003798D8 /* MPConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPConfig.m; sourceTree = "<group>"; }; DA5E5CA41724A667003798D8 /* MPConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPConfig.m; sourceTree = "<group>"; };
DA5E5CA51724A667003798D8 /* MPElementEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementEntity.h; sourceTree = "<group>"; };
DA5E5CA61724A667003798D8 /* MPElementEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementEntity.m; sourceTree = "<group>"; };
DA5E5CA71724A667003798D8 /* MPElementGeneratedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementGeneratedEntity.h; sourceTree = "<group>"; };
DA5E5CA81724A667003798D8 /* MPElementGeneratedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementGeneratedEntity.m; sourceTree = "<group>"; };
DA5E5CA91724A667003798D8 /* MPElementStoredEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementStoredEntity.h; sourceTree = "<group>"; };
DA5E5CAA1724A667003798D8 /* MPElementStoredEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementStoredEntity.m; sourceTree = "<group>"; };
DA5E5CAB1724A667003798D8 /* MPEntities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEntities.h; sourceTree = "<group>"; }; DA5E5CAB1724A667003798D8 /* MPEntities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEntities.h; sourceTree = "<group>"; };
DA5E5CAC1724A667003798D8 /* MPEntities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPEntities.m; sourceTree = "<group>"; }; DA5E5CAC1724A667003798D8 /* MPEntities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPEntities.m; sourceTree = "<group>"; };
DA5E5CAD1724A667003798D8 /* MPKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPKey.h; sourceTree = "<group>"; }; DA5E5CAD1724A667003798D8 /* MPKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPKey.h; sourceTree = "<group>"; };
@ -734,6 +729,14 @@
DA8ED891192906920099B726 /* PearlTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlTween.m; sourceTree = "<group>"; }; DA8ED891192906920099B726 /* PearlTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlTween.m; sourceTree = "<group>"; };
DA8ED892192906920099B726 /* PearlTween.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlTween.h; sourceTree = "<group>"; }; DA8ED892192906920099B726 /* PearlTween.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlTween.h; sourceTree = "<group>"; };
DA8ED894192906920099B726 /* map-macro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "map-macro.h"; sourceTree = "<group>"; }; DA8ED894192906920099B726 /* map-macro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "map-macro.h"; sourceTree = "<group>"; };
DA9521B519CEA3FD002E3AD5 /* MPSiteStoredEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSiteStoredEntity.m; sourceTree = "<group>"; };
DA9521B619CEA3FD002E3AD5 /* MPSiteStoredEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteStoredEntity.h; sourceTree = "<group>"; };
DA9521B719CEA3FD002E3AD5 /* MPSiteQuestion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSiteQuestion.m; sourceTree = "<group>"; };
DA9521B819CEA3FD002E3AD5 /* MPSiteQuestion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteQuestion.h; sourceTree = "<group>"; };
DA9521B919CEA3FD002E3AD5 /* MPSiteGeneratedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSiteGeneratedEntity.m; sourceTree = "<group>"; };
DA9521BA19CEA3FD002E3AD5 /* MPSiteGeneratedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteGeneratedEntity.h; sourceTree = "<group>"; };
DA9521BB19CEA3FD002E3AD5 /* MPSiteEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSiteEntity.m; sourceTree = "<group>"; };
DA9521BC19CEA3FD002E3AD5 /* MPSiteEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteEntity.h; sourceTree = "<group>"; };
DAAA81AF195A8D1300FA30D9 /* gradient.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = gradient.png; sourceTree = "<group>"; }; DAAA81AF195A8D1300FA30D9 /* gradient.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = gradient.png; sourceTree = "<group>"; };
DABB981515100B4000B05417 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; DABB981515100B4000B05417 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
DABC6C01175D8C85000C15D4 /* libRHStatusItemView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRHStatusItemView.a; sourceTree = BUILT_PRODUCTS_DIR; }; DABC6C01175D8C85000C15D4 /* libRHStatusItemView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRHStatusItemView.a; sourceTree = BUILT_PRODUCTS_DIR; };
@ -995,6 +998,14 @@
DA5E5C961724A667003798D8 /* ObjC */ = { DA5E5C961724A667003798D8 /* ObjC */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DA9521B519CEA3FD002E3AD5 /* MPSiteStoredEntity.m */,
DA9521B619CEA3FD002E3AD5 /* MPSiteStoredEntity.h */,
DA9521B719CEA3FD002E3AD5 /* MPSiteQuestion.m */,
DA9521B819CEA3FD002E3AD5 /* MPSiteQuestion.h */,
DA9521B919CEA3FD002E3AD5 /* MPSiteGeneratedEntity.m */,
DA9521BA19CEA3FD002E3AD5 /* MPSiteGeneratedEntity.h */,
DA9521BB19CEA3FD002E3AD5 /* MPSiteEntity.m */,
DA9521BC19CEA3FD002E3AD5 /* MPSiteEntity.h */,
DA3B8454190FC89700246EEA /* MPFixable.m */, DA3B8454190FC89700246EEA /* MPFixable.m */,
DA3B8455190FC89700246EEA /* MPFixable.h */, DA3B8455190FC89700246EEA /* MPFixable.h */,
DA5E5CB21724A667003798D8 /* Mac */, DA5E5CB21724A667003798D8 /* Mac */,
@ -1012,12 +1023,6 @@
DA5E5CA21724A667003798D8 /* MPAppDelegate_Store.m */, DA5E5CA21724A667003798D8 /* MPAppDelegate_Store.m */,
DA5E5CA31724A667003798D8 /* MPConfig.h */, DA5E5CA31724A667003798D8 /* MPConfig.h */,
DA5E5CA41724A667003798D8 /* MPConfig.m */, DA5E5CA41724A667003798D8 /* MPConfig.m */,
DA5E5CA51724A667003798D8 /* MPElementEntity.h */,
DA5E5CA61724A667003798D8 /* MPElementEntity.m */,
DA5E5CA71724A667003798D8 /* MPElementGeneratedEntity.h */,
DA5E5CA81724A667003798D8 /* MPElementGeneratedEntity.m */,
DA5E5CA91724A667003798D8 /* MPElementStoredEntity.h */,
DA5E5CAA1724A667003798D8 /* MPElementStoredEntity.m */,
DA5E5CAB1724A667003798D8 /* MPEntities.h */, DA5E5CAB1724A667003798D8 /* MPEntities.h */,
DA5E5CAC1724A667003798D8 /* MPEntities.m */, DA5E5CAC1724A667003798D8 /* MPEntities.m */,
DA5E5CAD1724A667003798D8 /* MPKey.h */, DA5E5CAD1724A667003798D8 /* MPKey.h */,
@ -2137,22 +2142,23 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
DA9521BF19CEA3FD002E3AD5 /* MPSiteGeneratedEntity.m in Sources */,
DA5E5CF61724A667003798D8 /* MPAlgorithm.m in Sources */, DA5E5CF61724A667003798D8 /* MPAlgorithm.m in Sources */,
DA5E5CF71724A667003798D8 /* MPAlgorithmV0.m in Sources */, DA5E5CF71724A667003798D8 /* MPAlgorithmV0.m in Sources */,
DA5E5CF81724A667003798D8 /* MPAlgorithmV1.m in Sources */, DA5E5CF81724A667003798D8 /* MPAlgorithmV1.m in Sources */,
DA9521BE19CEA3FD002E3AD5 /* MPSiteQuestion.m in Sources */,
DA5E5CF91724A667003798D8 /* MPAppDelegate_Key.m in Sources */, DA5E5CF91724A667003798D8 /* MPAppDelegate_Key.m in Sources */,
DA5E5CFA1724A667003798D8 /* MPAppDelegate_Shared.m in Sources */, DA5E5CFA1724A667003798D8 /* MPAppDelegate_Shared.m in Sources */,
DA5E5CFB1724A667003798D8 /* MPAppDelegate_Store.m in Sources */, DA5E5CFB1724A667003798D8 /* MPAppDelegate_Store.m in Sources */,
DA5E5CFC1724A667003798D8 /* MPConfig.m in Sources */, DA5E5CFC1724A667003798D8 /* MPConfig.m in Sources */,
DA5E5CFD1724A667003798D8 /* MPElementEntity.m in Sources */,
DA5E5CFE1724A667003798D8 /* MPElementGeneratedEntity.m in Sources */,
DA5E5CFF1724A667003798D8 /* MPElementStoredEntity.m in Sources */,
DA29992C19C6A89900AF7DF1 /* MasterPassword.xcdatamodeld in Sources */, DA29992C19C6A89900AF7DF1 /* MasterPassword.xcdatamodeld in Sources */,
DA3B8456190FC89700246EEA /* MPFixable.m in Sources */, DA3B8456190FC89700246EEA /* MPFixable.m in Sources */,
DA5E5D001724A667003798D8 /* MPEntities.m in Sources */, DA5E5D001724A667003798D8 /* MPEntities.m in Sources */,
DA5E5D011724A667003798D8 /* MPKey.m in Sources */, DA5E5D011724A667003798D8 /* MPKey.m in Sources */,
DA5E5D021724A667003798D8 /* MPUserEntity.m in Sources */, DA5E5D021724A667003798D8 /* MPUserEntity.m in Sources */,
DA9521BD19CEA3FD002E3AD5 /* MPSiteStoredEntity.m in Sources */,
DA5E5D031724A667003798D8 /* MPMacAppDelegate.m in Sources */, DA5E5D031724A667003798D8 /* MPMacAppDelegate.m in Sources */,
DA9521C019CEA3FD002E3AD5 /* MPSiteEntity.m in Sources */,
DA5E5D041724A667003798D8 /* MPMacConfig.m in Sources */, DA5E5D041724A667003798D8 /* MPMacConfig.m in Sources */,
DA5E5D0C1724A667003798D8 /* main.m in Sources */, DA5E5D0C1724A667003798D8 /* main.m in Sources */,
93D39C5789EFA607CF788082 /* MPElementModel.m in Sources */, 93D39C5789EFA607CF788082 /* MPElementModel.m in Sources */,

View File

@ -1,19 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model name="" userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" <model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="6244" systemVersion="13E28" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic">
lastSavedToolsVersion="1171" systemVersion="11E53" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic"> <entity name="MPElementEntity" representedClassName="MPSiteEntity" isAbstract="YES" elementID="58EE245C-6827-4C11-BB7E-5722F2426EC2" syncable="YES">
<entity name="MPElementEntity" representedClassName="MPElementEntity" isAbstract="YES" syncable="YES">
<attribute name="content" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/> <attribute name="content" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/>
<attribute name="lastUsed" attributeType="Date" syncable="YES"/> <attribute name="lastUsed" attributeType="Date" syncable="YES"/>
<attribute name="name" attributeType="String" minValueString="1" indexed="YES" syncable="YES"/> <attribute name="name" attributeType="String" minValueString="1" indexed="YES" syncable="YES"/>
<attribute name="type_" attributeType="Integer 16" defaultValueString="17" syncable="YES"/> <attribute name="type_" attributeType="Integer 16" defaultValueString="17" syncable="YES"/>
<attribute name="uses_" attributeType="Integer 16" defaultValueString="0" syncable="YES"/> <attribute name="uses_" attributeType="Integer 16" defaultValueString="0" syncable="YES"/>
<relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" <relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" inverseEntity="MPUserEntity" syncable="YES"/>
inverseEntity="MPUserEntity" syncable="YES"/>
</entity> </entity>
<entity name="MPElementGeneratedEntity" representedClassName="MPElementGeneratedEntity" parentEntity="MPElementEntity" syncable="YES"> <entity name="MPElementGeneratedEntity" representedClassName="MPSiteGeneratedEntity" parentEntity="MPElementEntity" elementID="789304EA-070D-4982-8C20-54EECFC20CB6" syncable="YES">
<attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/> <attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/>
</entity> </entity>
<entity name="MPElementStoredEntity" representedClassName="MPElementStoredEntity" parentEntity="MPElementEntity" syncable="YES"> <entity name="MPElementStoredEntity" representedClassName="MPSiteStoredEntity" parentEntity="MPElementEntity" elementID="BEEF1688-0CCD-4699-A86A-4D860FE2CEB8" syncable="YES">
<attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/> <attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/>
</entity> </entity>
<entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES"> <entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES">
@ -22,9 +20,10 @@
<attribute name="keyID" optional="YES" attributeType="Binary" syncable="YES"/> <attribute name="keyID" optional="YES" attributeType="Binary" syncable="YES"/>
<attribute name="lastUsed" optional="YES" attributeType="Date" syncable="YES"/> <attribute name="lastUsed" optional="YES" attributeType="Date" syncable="YES"/>
<attribute name="name" attributeType="String" syncable="YES"/> <attribute name="name" attributeType="String" syncable="YES"/>
<attribute name="saveKey_" attributeType="Boolean" defaultValueString="NO"/> <attribute name="saveKey_" attributeType="Boolean" defaultValueString="NO">
<relationship name="elements" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPElementEntity" <userInfo/>
inverseName="user" inverseEntity="MPElementEntity" syncable="YES"/> </attribute>
<relationship name="elements" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPElementEntity" inverseName="user" inverseEntity="MPElementEntity" syncable="YES"/>
</entity> </entity>
<elements> <elements>
<element name="MPElementEntity" positionX="160" positionY="192" width="128" height="135"/> <element name="MPElementEntity" positionX="160" positionY="192" width="128" height="135"/>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model name="" userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" <model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="6244" systemVersion="13E28" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic">
lastSavedToolsVersion="2057" systemVersion="12C60" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic"> <entity name="MPElementEntity" representedClassName="MPSiteEntity" isAbstract="YES" elementID="58EE245C-6827-4C11-BB7E-5722F2426EC2" syncable="YES">
<entity name="MPElementEntity" representedClassName="MPElementEntity" isAbstract="YES" syncable="YES">
<attribute name="content" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/> <attribute name="content" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/>
<attribute name="lastUsed" attributeType="Date" indexed="YES" syncable="YES"/> <attribute name="lastUsed" attributeType="Date" indexed="YES" syncable="YES"/>
<attribute name="name" attributeType="String" minValueString="1" indexed="YES" syncable="YES"/> <attribute name="name" attributeType="String" minValueString="1" indexed="YES" syncable="YES"/>
@ -12,13 +11,12 @@
<attribute name="userName" optional="YES" attributeType="String" syncable="YES"/> <attribute name="userName" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="uses_" attributeType="Integer 16" defaultValueString="0" indexed="YES" syncable="YES"/> <attribute name="uses_" attributeType="Integer 16" defaultValueString="0" indexed="YES" syncable="YES"/>
<attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" syncable="YES"/> <attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" syncable="YES"/>
<relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" <relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" inverseEntity="MPUserEntity" syncable="YES"/>
inverseEntity="MPUserEntity" syncable="YES"/>
</entity> </entity>
<entity name="MPElementGeneratedEntity" representedClassName="MPElementGeneratedEntity" parentEntity="MPElementEntity" syncable="YES"> <entity name="MPElementGeneratedEntity" representedClassName="MPSiteGeneratedEntity" parentEntity="MPElementEntity" elementID="789304EA-070D-4982-8C20-54EECFC20CB6" syncable="YES">
<attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/> <attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/>
</entity> </entity>
<entity name="MPElementStoredEntity" representedClassName="MPElementStoredEntity" parentEntity="MPElementEntity" syncable="YES"> <entity name="MPElementStoredEntity" representedClassName="MPSiteStoredEntity" parentEntity="MPElementEntity" elementID="BEEF1688-0CCD-4699-A86A-4D860FE2CEB8" syncable="YES">
<attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/> <attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/>
</entity> </entity>
<entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES"> <entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES">
@ -31,8 +29,7 @@
<attribute name="saveKey_" attributeType="Boolean" defaultValueString="NO"> <attribute name="saveKey_" attributeType="Boolean" defaultValueString="NO">
<userInfo/> <userInfo/>
</attribute> </attribute>
<relationship name="elements" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPElementEntity" <relationship name="elements" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPElementEntity" inverseName="user" inverseEntity="MPElementEntity" syncable="YES"/>
inverseName="user" inverseEntity="MPElementEntity" syncable="YES"/>
</entity> </entity>
<elements> <elements>
<element name="MPElementEntity" positionX="0" positionY="0" width="128" height="180"/> <element name="MPElementEntity" positionX="0" positionY="0" width="128" height="180"/>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model name="" userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" <model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="6244" systemVersion="13E28" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic">
lastSavedToolsVersion="1810" systemVersion="12B19" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic"> <entity name="MPElementEntity" representedClassName="MPSiteEntity" isAbstract="YES" elementID="58EE245C-6827-4C11-BB7E-5722F2426EC2" syncable="YES">
<entity name="MPElementEntity" representedClassName="MPElementEntity" isAbstract="YES" syncable="YES">
<attribute name="content" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/> <attribute name="content" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/>
<attribute name="lastUsed" attributeType="Date" indexed="YES" syncable="YES"/> <attribute name="lastUsed" attributeType="Date" indexed="YES" syncable="YES"/>
<attribute name="loginName" optional="YES" attributeType="String" elementID="A1B9F981-D33C-4BFE-9F94-C9D3E1F78E51" syncable="YES"/> <attribute name="loginName" optional="YES" attributeType="String" elementID="A1B9F981-D33C-4BFE-9F94-C9D3E1F78E51" syncable="YES"/>
@ -12,13 +11,12 @@
<attribute name="type_" attributeType="Integer 16" defaultValueString="17" syncable="YES"/> <attribute name="type_" attributeType="Integer 16" defaultValueString="17" syncable="YES"/>
<attribute name="uses_" attributeType="Integer 16" defaultValueString="0" indexed="YES" syncable="YES"/> <attribute name="uses_" attributeType="Integer 16" defaultValueString="0" indexed="YES" syncable="YES"/>
<attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" syncable="YES"/> <attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" syncable="YES"/>
<relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" <relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" inverseEntity="MPUserEntity" syncable="YES"/>
inverseEntity="MPUserEntity" syncable="YES"/>
</entity> </entity>
<entity name="MPElementGeneratedEntity" representedClassName="MPElementGeneratedEntity" parentEntity="MPElementEntity" syncable="YES"> <entity name="MPElementGeneratedEntity" representedClassName="MPSiteGeneratedEntity" parentEntity="MPElementEntity" elementID="789304EA-070D-4982-8C20-54EECFC20CB6" syncable="YES">
<attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/> <attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/>
</entity> </entity>
<entity name="MPElementStoredEntity" representedClassName="MPElementStoredEntity" parentEntity="MPElementEntity" syncable="YES"> <entity name="MPElementStoredEntity" representedClassName="MPSiteStoredEntity" parentEntity="MPElementEntity" elementID="BEEF1688-0CCD-4699-A86A-4D860FE2CEB8" syncable="YES">
<attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/> <attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/>
</entity> </entity>
<entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES"> <entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES">
@ -31,8 +29,7 @@
<attribute name="saveKey_" attributeType="Boolean" defaultValueString="NO"> <attribute name="saveKey_" attributeType="Boolean" defaultValueString="NO">
<userInfo/> <userInfo/>
</attribute> </attribute>
<relationship name="elements" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPElementEntity" <relationship name="elements" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPElementEntity" inverseName="user" inverseEntity="MPElementEntity" syncable="YES"/>
inverseName="user" inverseEntity="MPElementEntity" syncable="YES"/>
</entity> </entity>
<elements> <elements>
<element name="MPElementEntity" positionX="-0" positionY="-286" width="128" height="178"/> <element name="MPElementEntity" positionX="-0" positionY="-286" width="128" height="178"/>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model name="" userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" <model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="6244" systemVersion="13E28" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic">
lastSavedToolsVersion="2057" systemVersion="12C60" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic"> <entity name="MPElementEntity" representedClassName="MPSiteEntity" isAbstract="YES" elementID="58EE245C-6827-4C11-BB7E-5722F2426EC2" syncable="YES">
<entity name="MPElementEntity" representedClassName="MPElementEntity" isAbstract="YES" syncable="YES">
<attribute name="content" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/> <attribute name="content" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/>
<attribute name="lastUsed" attributeType="Date" indexed="YES" syncable="YES"/> <attribute name="lastUsed" attributeType="Date" indexed="YES" syncable="YES"/>
<attribute name="loginName" optional="YES" attributeType="String" elementID="A1B9F981-D33C-4BFE-9F94-C9D3E1F78E51" syncable="YES"/> <attribute name="loginName" optional="YES" attributeType="String" elementID="A1B9F981-D33C-4BFE-9F94-C9D3E1F78E51" syncable="YES"/>
@ -12,13 +11,12 @@
<attribute name="type_" attributeType="Integer 16" defaultValueString="17" syncable="YES"/> <attribute name="type_" attributeType="Integer 16" defaultValueString="17" syncable="YES"/>
<attribute name="uses_" attributeType="Integer 16" defaultValueString="0" indexed="YES" syncable="YES"/> <attribute name="uses_" attributeType="Integer 16" defaultValueString="0" indexed="YES" syncable="YES"/>
<attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" syncable="YES"/> <attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" syncable="YES"/>
<relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" <relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" inverseEntity="MPUserEntity" syncable="YES"/>
inverseEntity="MPUserEntity" syncable="YES"/>
</entity> </entity>
<entity name="MPElementGeneratedEntity" representedClassName="MPElementGeneratedEntity" parentEntity="MPElementEntity" syncable="YES"> <entity name="MPElementGeneratedEntity" representedClassName="MPSiteGeneratedEntity" parentEntity="MPElementEntity" elementID="789304EA-070D-4982-8C20-54EECFC20CB6" syncable="YES">
<attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/> <attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/>
</entity> </entity>
<entity name="MPElementStoredEntity" representedClassName="MPElementStoredEntity" parentEntity="MPElementEntity" syncable="YES"> <entity name="MPElementStoredEntity" representedClassName="MPSiteStoredEntity" parentEntity="MPElementEntity" elementID="BEEF1688-0CCD-4699-A86A-4D860FE2CEB8" syncable="YES">
<attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/> <attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/>
</entity> </entity>
<entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES"> <entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES">
@ -30,8 +28,7 @@
<attribute name="saveKey_" attributeType="Boolean" defaultValueString="NO"> <attribute name="saveKey_" attributeType="Boolean" defaultValueString="NO">
<userInfo/> <userInfo/>
</attribute> </attribute>
<relationship name="elements" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPElementEntity" <relationship name="elements" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPElementEntity" inverseName="user" inverseEntity="MPElementEntity" syncable="YES"/>
inverseName="user" inverseEntity="MPElementEntity" syncable="YES"/>
</entity> </entity>
<elements> <elements>
<element name="MPElementEntity" positionX="-0" positionY="-286" width="128" height="178"/> <element name="MPElementEntity" positionX="-0" positionY="-286" width="128" height="178"/>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="6244" systemVersion="13E28" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic"> <model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="6244" systemVersion="13E28" minimumToolsVersion="Automatic" macOSVersion="Automatic" iOSVersion="Automatic">
<entity name="MPElementEntity" representedClassName="MPElementEntity" isAbstract="YES" syncable="YES"> <entity name="MPSiteEntity" representedClassName="MPSiteEntity" isAbstract="YES" elementID="58EE245C-6827-4C11-BB7E-5722F2426EC2" syncable="YES">
<attribute name="content" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/> <attribute name="content" optional="YES" transient="YES" attributeType="Transformable" syncable="YES"/>
<attribute name="lastUsed" attributeType="Date" indexed="YES" syncable="YES"/> <attribute name="lastUsed" attributeType="Date" indexed="YES" syncable="YES"/>
<attribute name="loginGenerated_" attributeType="Boolean" defaultValueString="NO" syncable="YES"/> <attribute name="loginGenerated_" attributeType="Boolean" defaultValueString="NO" syncable="YES"/>
@ -12,12 +12,17 @@
<attribute name="type_" attributeType="Integer 16" defaultValueString="17" syncable="YES"/> <attribute name="type_" attributeType="Integer 16" defaultValueString="17" syncable="YES"/>
<attribute name="uses_" attributeType="Integer 16" defaultValueString="0" indexed="YES" syncable="YES"/> <attribute name="uses_" attributeType="Integer 16" defaultValueString="0" indexed="YES" syncable="YES"/>
<attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" syncable="YES"/> <attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" syncable="YES"/>
<relationship name="questions" optional="YES" toMany="YES" deletionRule="Cascade" ordered="YES" destinationEntity="MPSiteQuestion" inverseName="site" inverseEntity="MPSiteQuestion" syncable="YES"/>
<relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" inverseEntity="MPUserEntity" syncable="YES"/> <relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" inverseEntity="MPUserEntity" syncable="YES"/>
</entity> </entity>
<entity name="MPElementGeneratedEntity" representedClassName="MPElementGeneratedEntity" parentEntity="MPElementEntity" syncable="YES"> <entity name="MPSiteGeneratedEntity" representedClassName="MPSiteGeneratedEntity" parentEntity="MPSiteEntity" elementID="789304EA-070D-4982-8C20-54EECFC20CB6" syncable="YES">
<attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/> <attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/>
</entity> </entity>
<entity name="MPElementStoredEntity" representedClassName="MPElementStoredEntity" parentEntity="MPElementEntity" syncable="YES"> <entity name="MPSiteQuestion" representedClassName="MPSiteQuestion" syncable="YES">
<attribute name="keyword" attributeType="String" syncable="YES"/>
<relationship name="site" maxCount="1" deletionRule="Nullify" destinationEntity="MPSiteEntity" inverseName="questions" inverseEntity="MPSiteEntity" syncable="YES"/>
</entity>
<entity name="MPSiteStoredEntity" representedClassName="MPSiteStoredEntity" parentEntity="MPSiteEntity" elementID="BEEF1688-0CCD-4699-A86A-4D860FE2CEB8" syncable="YES">
<attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/> <attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/>
</entity> </entity>
<entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES"> <entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES">
@ -29,12 +34,13 @@
<attribute name="saveKey_" attributeType="Boolean" defaultValueString="NO"> <attribute name="saveKey_" attributeType="Boolean" defaultValueString="NO">
<userInfo/> <userInfo/>
</attribute> </attribute>
<relationship name="elements" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPElementEntity" inverseName="user" inverseEntity="MPElementEntity" syncable="YES"/> <relationship name="elements" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="MPSiteEntity" inverseName="user" inverseEntity="MPSiteEntity" syncable="YES"/>
</entity> </entity>
<elements> <elements>
<element name="MPElementEntity" positionX="-0" positionY="-286" width="128" height="193"/> <element name="MPSiteEntity" positionX="-0" positionY="-286" width="128" height="208"/>
<element name="MPElementGeneratedEntity" positionX="216" positionY="-288" width="128" height="58"/> <element name="MPSiteGeneratedEntity" positionX="216" positionY="-288" width="128" height="58"/>
<element name="MPElementStoredEntity" positionX="214" positionY="-171" width="128" height="58"/> <element name="MPSiteQuestion" positionX="-2" positionY="-9" width="128" height="73"/>
<element name="MPSiteStoredEntity" positionX="214" positionY="-171" width="128" height="58"/>
<element name="MPUserEntity" positionX="-218" positionY="-288" width="128" height="148"/> <element name="MPUserEntity" positionX="-218" positionY="-288" width="128" height="148"/>
</elements> </elements>
</model> </model>

View File

@ -126,7 +126,7 @@
- (void)updatePassword { - (void)updatePassword {
NSString *siteName = self.siteField.text; NSString *siteName = self.siteField.text;
MPElementType siteType = [self siteType]; MPSiteType siteType = [self siteType];
NSUInteger siteCounter = (NSUInteger)self.counterStepper.value; NSUInteger siteCounter = (NSUInteger)self.counterStepper.value;
self.counterLabel.text = strf( @"%lu", (unsigned long)siteCounter ); self.counterLabel.text = strf( @"%lu", (unsigned long)siteCounter );
@ -145,21 +145,21 @@
}]; }];
} }
- (enum MPElementType)siteType { - (enum MPSiteType)siteType {
switch (self.typeControl.selectedSegmentIndex) { switch (self.typeControl.selectedSegmentIndex) {
case 0: case 0:
return MPElementTypeGeneratedMaximum; return MPSiteTypeGeneratedMaximum;
case 1: case 1:
return MPElementTypeGeneratedLong; return MPSiteTypeGeneratedLong;
case 2: case 2:
return MPElementTypeGeneratedMedium; return MPSiteTypeGeneratedMedium;
case 3: case 3:
return MPElementTypeGeneratedBasic; return MPSiteTypeGeneratedBasic;
case 4: case 4:
return MPElementTypeGeneratedShort; return MPSiteTypeGeneratedShort;
case 5: case 5:
return MPElementTypeGeneratedPIN; return MPSiteTypeGeneratedPIN;
default: default:
Throw(@"Unsupported type index: %ld", (long)self.typeControl.selectedSegmentIndex); Throw(@"Unsupported type index: %ld", (long)self.typeControl.selectedSegmentIndex);
} }

View File

@ -27,7 +27,7 @@ typedef NS_ENUM ( NSUInteger, MPPasswordCellMode ) {
@interface MPPasswordCell : MPCell <UIScrollViewDelegate, UITextFieldDelegate> @interface MPPasswordCell : MPCell <UIScrollViewDelegate, UITextFieldDelegate>
- (void)setElement:(MPElementEntity *)element animated:(BOOL)animated; - (void)setElement:(MPSiteEntity *)element animated:(BOOL)animated;
- (void)setTransientSite:(NSString *)siteName animated:(BOOL)animated; - (void)setTransientSite:(NSString *)siteName animated:(BOOL)animated;
- (void)setMode:(MPPasswordCellMode)mode animated:(BOOL)animated; - (void)setMode:(MPPasswordCellMode)mode animated:(BOOL)animated;

View File

@ -155,7 +155,7 @@
[self updateAnimated:animated]; [self updateAnimated:animated];
} }
- (void)setElement:(MPElementEntity *)element animated:(BOOL)animated { - (void)setElement:(MPSiteEntity *)element animated:(BOOL)animated {
_elementOID = [element objectID]; _elementOID = [element objectID];
[self updateAnimated:animated]; [self updateAnimated:animated];
@ -195,7 +195,7 @@
NSString *password = self.passwordField.text; NSString *password = self.passwordField.text;
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
TimeToCrack timeToCrack; TimeToCrack timeToCrack;
MPElementEntity *element = [self elementInContext:context]; MPSiteEntity *element = [self elementInContext:context];
id<MPAlgorithm> algorithm = element.algorithm?: MPAlgorithmDefault; id<MPAlgorithm> algorithm = element.algorithm?: MPAlgorithmDefault;
MPAttacker attackHardware = [[MPConfig get].siteAttacker unsignedIntegerValue]; MPAttacker attackHardware = [[MPConfig get].siteAttacker unsignedIntegerValue];
if ([algorithm timeToCrack:&timeToCrack passwordOfType:[self elementInContext:context].type byAttacker:attackHardware] || if ([algorithm timeToCrack:&timeToCrack passwordOfType:[self elementInContext:context].type byAttacker:attackHardware] ||
@ -214,12 +214,12 @@
NSString *text = textField.text; NSString *text = textField.text;
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPElementEntity *element = [self elementInContext:context]; MPSiteEntity *element = [self elementInContext:context];
if (!element) if (!element)
return; return;
if (textField == self.passwordField) { if (textField == self.passwordField) {
if ([element.algorithm savePassword:text toElement:element usingKey:[MPiOSAppDelegate get].key]) if ([element.algorithm savePassword:text toSite:element usingKey:[MPiOSAppDelegate get].key])
[PearlOverlay showTemporaryOverlayWithTitle:@"Password Updated" dismissAfter:2]; [PearlOverlay showTemporaryOverlayWithTitle:@"Password Updated" dismissAfter:2];
} }
else if (textField == self.loginNameField && else if (textField == self.loginNameField &&
@ -243,7 +243,7 @@
- (IBAction)doDelete:(UIButton *)sender { - (IBAction)doDelete:(UIButton *)sender {
MPElementEntity *element = [self elementInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]]; MPSiteEntity *element = [self elementInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
if (!element) if (!element)
return; return;
@ -265,10 +265,10 @@
[PearlSheet showSheetWithTitle:@"Change Password Type" viewStyle:UIActionSheetStyleAutomatic [PearlSheet showSheetWithTitle:@"Change Password Type" viewStyle:UIActionSheetStyleAutomatic
initSheet:^(UIActionSheet *sheet) { initSheet:^(UIActionSheet *sheet) {
MPElementEntity MPSiteEntity
*mainElement = [self elementInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]]; *mainElement = [self elementInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
for (NSNumber *typeNumber in [MPAlgorithmDefault allTypes]) { for (NSNumber *typeNumber in [MPAlgorithmDefault allTypes]) {
MPElementType type = [typeNumber unsignedIntegerValue]; MPSiteType type = [typeNumber unsignedIntegerValue];
NSString *typeName = [MPAlgorithmDefault nameOfType:type]; NSString *typeName = [MPAlgorithmDefault nameOfType:type];
if (type == mainElement.type) if (type == mainElement.type)
[sheet addButtonWithTitle:strf( @"● %@", typeName )]; [sheet addButtonWithTitle:strf( @"● %@", typeName )];
@ -279,11 +279,11 @@
if (buttonIndex == [sheet cancelButtonIndex]) if (buttonIndex == [sheet cancelButtonIndex])
return; return;
MPElementType type = [[MPAlgorithmDefault allTypes][buttonIndex] unsignedIntegerValue]?: MPElementTypeGeneratedLong; MPSiteType type = [[MPAlgorithmDefault allTypes][buttonIndex] unsignedIntegerValue]?: MPSiteTypeGeneratedLong;
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPElementEntity *element = [self elementInContext:context]; MPSiteEntity *element = [self elementInContext:context];
element = [[MPiOSAppDelegate get] changeElement:element saveInContext:context toType:type]; element = [[MPiOSAppDelegate get] changeSite:element saveInContext:context toType:type];
[self setElement:element animated:YES]; [self setElement:element animated:YES];
}]; }];
} cancelTitle:@"Cancel" destructiveTitle:nil otherTitles:nil]; } cancelTitle:@"Cancel" destructiveTitle:nil otherTitles:nil];
@ -294,7 +294,7 @@
self.loginNameField.enabled = YES; self.loginNameField.enabled = YES;
self.passwordField.enabled = YES; self.passwordField.enabled = YES;
if ([self elementInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]].type & MPElementTypeClassStored) if ([self elementInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]].type & MPSiteTypeClassStored)
[self.passwordField becomeFirstResponder]; [self.passwordField becomeFirstResponder];
else else
[self.loginNameField becomeFirstResponder]; [self.loginNameField becomeFirstResponder];
@ -331,7 +331,7 @@
- (IBAction)doIncrementCounter:(UIButton *)sender { - (IBAction)doIncrementCounter:(UIButton *)sender {
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPElementEntity *element = [self elementInContext:context]; MPSiteEntity *element = [self elementInContext:context];
if (!element || ![element isKindOfClass:[MPElementGeneratedEntity class]]) if (!element || ![element isKindOfClass:[MPElementGeneratedEntity class]])
return; return;
@ -363,7 +363,7 @@
return; return;
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPElementEntity *element = [self elementInContext:context]; MPSiteEntity *element = [self elementInContext:context];
if (!element || ![element isKindOfClass:[MPElementGeneratedEntity class]]) if (!element || ![element isKindOfClass:[MPElementGeneratedEntity class]])
return; return;
@ -393,7 +393,7 @@
} }
[[MPiOSAppDelegate get] [[MPiOSAppDelegate get]
addElementNamed:self.transientSite completion:^(MPElementEntity *element, NSManagedObjectContext *context) { addSiteNamed:self.transientSite completion:^(MPSiteEntity *element, NSManagedObjectContext *context) {
[self copyContentOfElement:element saveInContext:context]; [self copyContentOfElement:element saveInContext:context];
PearlMainQueueAfter( .3f, ^{ PearlMainQueueAfter( .3f, ^{
@ -424,7 +424,7 @@
}]; }];
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPElementEntity *element = [self elementInContext:context]; MPSiteEntity *element = [self elementInContext:context];
if (![self copyLoginOfElement:element saveInContext:context]) { if (![self copyLoginOfElement:element saveInContext:context]) {
element.loginGenerated = YES; element.loginGenerated = YES;
[context saveToStore]; [context saveToStore];
@ -462,7 +462,7 @@
} }
[UIView animateWithDuration:animated? .3f: 0 animations:^{ [UIView animateWithDuration:animated? .3f: 0 animations:^{
MPElementEntity *mainElement = [self elementInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]]; MPSiteEntity *mainElement = [self elementInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
// UI // UI
self.upgradeButton.alpha = mainElement.requiresExplicitMigration? 1: 0; self.upgradeButton.alpha = mainElement.requiresExplicitMigration? 1: 0;
@ -470,7 +470,7 @@
self.loginNameContainer.alpha = settingsMode || mainElement.loginGenerated || [mainElement.loginName length]? 0.7f: 0; self.loginNameContainer.alpha = settingsMode || mainElement.loginGenerated || [mainElement.loginName length]? 0.7f: 0;
self.loginNameField.textColor = [UIColor colorWithHexString:mainElement.loginGenerated? @"5E636D": @"6D5E63"]; self.loginNameField.textColor = [UIColor colorWithHexString:mainElement.loginGenerated? @"5E636D": @"6D5E63"];
self.modeButton.alpha = self.transientSite? 0: settingsMode? 0.5f: 0.1f; self.modeButton.alpha = self.transientSite? 0: settingsMode? 0.5f: 0.1f;
self.counterLabel.alpha = self.counterButton.alpha = mainElement.type & MPElementTypeClassGenerated? 0.5f: 0; self.counterLabel.alpha = self.counterButton.alpha = mainElement.type & MPSiteTypeClassGenerated? 0.5f: 0;
self.modeButton.selected = settingsMode; self.modeButton.selected = settingsMode;
self.strengthLabel.gone = !settingsMode; self.strengthLabel.gone = !settingsMode;
self.modeScrollView.scrollEnabled = !self.transientSite; self.modeScrollView.scrollEnabled = !self.transientSite;
@ -491,17 +491,17 @@
// Site Password // Site Password
self.passwordField.secureTextEntry = [[MPiOSConfig get].hidePasswords boolValue]; self.passwordField.secureTextEntry = [[MPiOSConfig get].hidePasswords boolValue];
self.passwordField.attributedPlaceholder = stra( self.passwordField.attributedPlaceholder = stra(
mainElement.type & MPElementTypeClassStored? strl( @"No password" ): mainElement.type & MPSiteTypeClassStored? strl( @"No password" ):
mainElement.type & MPElementTypeClassGenerated? strl( @"..." ): @"", @{ mainElement.type & MPSiteTypeClassGenerated? strl( @"..." ): @"", @{
NSForegroundColorAttributeName : [UIColor whiteColor] NSForegroundColorAttributeName : [UIColor whiteColor]
} ); } );
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPElementEntity *element = [self elementInContext:context]; MPSiteEntity *element = [self elementInContext:context];
MPKey *key = [MPiOSAppDelegate get].key; MPKey *key = [MPiOSAppDelegate get].key;
NSString *password, *loginName = [element resolveLoginUsingKey:key]; NSString *password, *loginName = [element resolveLoginUsingKey:key];
if (self.transientSite) if (self.transientSite)
password = [MPAlgorithmDefault generatePasswordForSiteNamed:self.transientSite ofType: password = [MPAlgorithmDefault generatePasswordForSiteNamed:self.transientSite ofType:
[[MPiOSAppDelegate get] activeUserInContext:context].defaultType?: MPElementTypeGeneratedLong [[MPiOSAppDelegate get] activeUserInContext:context].defaultType?: MPSiteTypeGeneratedLong
withCounter:1 usingKey:key]; withCounter:1 usingKey:key];
else if (element) else if (element)
password = [element resolvePasswordUsingKey:key]; password = [element resolvePasswordUsingKey:key];
@ -549,7 +549,7 @@
}]; }];
} }
- (BOOL)copyContentOfElement:(MPElementEntity *)element saveInContext:(NSManagedObjectContext *)context { - (BOOL)copyContentOfElement:(MPSiteEntity *)element saveInContext:(NSManagedObjectContext *)context {
inf( @"Copying password for: %@", element.name ); inf( @"Copying password for: %@", element.name );
NSString *password = [element resolvePasswordUsingKey:[MPAppDelegate_Shared get].key]; NSString *password = [element resolvePasswordUsingKey:[MPAppDelegate_Shared get].key];
@ -566,10 +566,10 @@
return YES; return YES;
} }
- (BOOL)copyLoginOfElement:(MPElementEntity *)element saveInContext:(NSManagedObjectContext *)context { - (BOOL)copyLoginOfElement:(MPSiteEntity *)element saveInContext:(NSManagedObjectContext *)context {
inf( @"Copying login for: %@", element.name ); inf( @"Copying login for: %@", element.name );
NSString *loginName = [element.algorithm resolveLoginForElement:element usingKey:[MPiOSAppDelegate get].key]; NSString *loginName = [element.algorithm resolveLoginForSite:element usingKey:[MPiOSAppDelegate get].key];
if (![loginName length]) if (![loginName length])
return NO; return NO;
@ -583,9 +583,9 @@
return YES; return YES;
} }
- (MPElementEntity *)elementInContext:(NSManagedObjectContext *)context { - (MPSiteEntity *)elementInContext:(NSManagedObjectContext *)context {
return [MPElementEntity existingObjectWithID:_elementOID inContext:context]; return [MPSiteEntity existingObjectWithID:_elementOID inContext:context];
} }
@end @end

View File

@ -16,7 +16,7 @@
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved. // Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
// //
@class MPElementEntity; @class MPSiteEntity;
@class MPCoachmark; @class MPCoachmark;
@interface MPPasswordsViewController : UIViewController<UISearchBarDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout> @interface MPPasswordsViewController : UIViewController<UISearchBarDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>

View File

@ -423,7 +423,7 @@ referenceSizeForHeaderInSection:(NSInteger)section {
if (!_fetchedResultsController) { if (!_fetchedResultsController) {
_showTransientItem = NO; _showTransientItem = NO;
[MPiOSAppDelegate managedObjectContextForMainThreadPerformBlockAndWait:^(NSManagedObjectContext *mainContext) { [MPiOSAppDelegate managedObjectContextForMainThreadPerformBlockAndWait:^(NSManagedObjectContext *mainContext) {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPElementEntity class] )]; NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
fetchRequest.sortDescriptors = @[ fetchRequest.sortDescriptors = @[
[[NSSortDescriptor alloc] initWithKey:NSStringFromSelector( @selector( lastUsed ) ) ascending:NO] [[NSSortDescriptor alloc] initWithKey:NSStringFromSelector( @selector( lastUsed ) ) ascending:NO]
]; ];

View File

@ -102,7 +102,7 @@
self.generatedTypeControl.selectedSegmentIndex = -1; self.generatedTypeControl.selectedSegmentIndex = -1;
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPElementType defaultType = [[MPiOSAppDelegate get] activeUserInContext:context].defaultType = [self typeForSelectedSegment]; MPSiteType defaultType = [[MPiOSAppDelegate get] activeUserInContext:context].defaultType = [self typeForSelectedSegment];
[context saveToStore]; [context saveToStore];
PearlMainQueue( ^{ PearlMainQueue( ^{
@ -179,31 +179,31 @@
return nil; return nil;
} }
- (enum MPElementType)typeForSelectedSegment { - (enum MPSiteType)typeForSelectedSegment {
NSInteger selectedGeneratedIndex = self.generatedTypeControl.selectedSegmentIndex; NSInteger selectedGeneratedIndex = self.generatedTypeControl.selectedSegmentIndex;
NSInteger selectedStoredIndex = self.storedTypeControl.selectedSegmentIndex; NSInteger selectedStoredIndex = self.storedTypeControl.selectedSegmentIndex;
switch (selectedGeneratedIndex) { switch (selectedGeneratedIndex) {
case 0: case 0:
return MPElementTypeGeneratedMaximum; return MPSiteTypeGeneratedMaximum;
case 1: case 1:
return MPElementTypeGeneratedLong; return MPSiteTypeGeneratedLong;
case 2: case 2:
return MPElementTypeGeneratedMedium; return MPSiteTypeGeneratedMedium;
case 3: case 3:
return MPElementTypeGeneratedBasic; return MPSiteTypeGeneratedBasic;
case 4: case 4:
return MPElementTypeGeneratedShort; return MPSiteTypeGeneratedShort;
case 5: case 5:
return MPElementTypeGeneratedPIN; return MPSiteTypeGeneratedPIN;
default: default:
switch (selectedStoredIndex) { switch (selectedStoredIndex) {
case 0: case 0:
return MPElementTypeStoredPersonal; return MPSiteTypeStoredPersonal;
case 1: case 1:
return MPElementTypeStoredDevicePrivate; return MPSiteTypeStoredDevicePrivate;
default: default:
Throw( @"unsupported selected type index: generated=%ld, stored=%ld", (long)selectedGeneratedIndex, Throw( @"unsupported selected type index: generated=%ld, stored=%ld", (long)selectedGeneratedIndex,
(long)selectedStoredIndex ); (long)selectedStoredIndex );
@ -211,32 +211,32 @@
} }
} }
- (NSInteger)generatedSegmentIndexForType:(MPElementType)type { - (NSInteger)generatedSegmentIndexForType:(MPSiteType)type {
switch (type) { switch (type) {
case MPElementTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
return 0; return 0;
case MPElementTypeGeneratedLong: case MPSiteTypeGeneratedLong:
return 1; return 1;
case MPElementTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
return 2; return 2;
case MPElementTypeGeneratedBasic: case MPSiteTypeGeneratedBasic:
return 3; return 3;
case MPElementTypeGeneratedShort: case MPSiteTypeGeneratedShort:
return 4; return 4;
case MPElementTypeGeneratedPIN: case MPSiteTypeGeneratedPIN:
return 5; return 5;
default: default:
return -1; return -1;
} }
} }
- (NSInteger)storedSegmentIndexForType:(MPElementType)type { - (NSInteger)storedSegmentIndexForType:(MPSiteType)type {
switch (type) { switch (type) {
case MPElementTypeStoredPersonal: case MPSiteTypeStoredPersonal:
return 0; return 0;
case MPElementTypeStoredDevicePrivate: case MPSiteTypeStoredDevicePrivate:
return 1; return 1;
default: default:
return -1; return -1;

View File

@ -134,6 +134,8 @@
if ([productIdentifier isEqualToString:MPProductGenerateLogins]) if ([productIdentifier isEqualToString:MPProductGenerateLogins])
return self.generateLoginCell; return self.generateLoginCell;
if ([productIdentifier isEqualToString:MPProductAdvancedExport])
return self.advancedExportCell;
return nil; return nil;
} }
@ -145,19 +147,24 @@
[hideCells addObjectsFromArray:self.allCellsBySection[0]]; [hideCells addObjectsFromArray:self.allCellsBySection[0]];
for (SKProduct *product in products) { for (SKProduct *product in products) {
[self showCell:self.generateLoginCell ifProduct:product hasProductIdentifier:MPProductGenerateLogins showingCells:showCells]; [self showCellForProductWithIdentifier:MPProductGenerateLogins ifProduct:product showingCells:showCells];
[self showCellForProductWithIdentifier:MPProductAdvancedExport ifProduct:product showingCells:showCells];
} }
[hideCells removeObjectsInArray:showCells]; [hideCells removeObjectsInArray:showCells];
[self updateCellsHiding:hideCells showing:showCells animation:UITableViewRowAnimationAutomatic]; if ([self.tableView numberOfRowsInSection:0])
[self updateCellsHiding:hideCells showing:showCells animation:UITableViewRowAnimationAutomatic];
else
[self updateCellsHiding:hideCells showing:showCells animation:UITableViewRowAnimationNone];
} }
- (void)showCell:(MPStoreProductCell *)cell ifProduct:(SKProduct *)product hasProductIdentifier:(NSString *)productIdentifier - (void)showCellForProductWithIdentifier:(NSString *)productIdentifier ifProduct:(SKProduct *)product
showingCells:(NSMutableArray *)showCells { showingCells:(NSMutableArray *)showCells {
if (![product.productIdentifier isEqualToString:productIdentifier]) if (![product.productIdentifier isEqualToString:productIdentifier])
return; return;
MPStoreProductCell *cell = [self cellForProductIdentifier:productIdentifier];
[showCells addObject:cell]; [showCells addObject:cell];
self.currencyFormatter.locale = product.priceLocale; self.currencyFormatter.locale = product.priceLocale;

View File

@ -13,11 +13,11 @@
@protocol MPTypeDelegate<NSObject> @protocol MPTypeDelegate<NSObject>
@required @required
- (void)didSelectType:(MPElementType)type; - (void)didSelectType:(MPSiteType)type;
- (MPElementType)selectedType; - (MPSiteType)selectedType;
@optional @optional
- (MPElementEntity *)selectedElement; - (MPSiteEntity *)selectedElement;
@end @end

View File

@ -12,7 +12,7 @@
@interface MPTypeViewController() @interface MPTypeViewController()
- (MPElementType)typeAtIndexPath:(NSIndexPath *)indexPath; - (MPSiteType)typeAtIndexPath:(NSIndexPath *)indexPath;
@end @end
@ -63,15 +63,15 @@
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
MPElementEntity *selectedElement = nil; MPSiteEntity *selectedElement = nil;
if ([self.delegate respondsToSelector:@selector(selectedElement)]) if ([self.delegate respondsToSelector:@selector(selectedElement)])
selectedElement = [self.delegate selectedElement]; selectedElement = [self.delegate selectedElement];
MPElementType cellType = [self typeAtIndexPath:indexPath]; MPSiteType cellType = [self typeAtIndexPath:indexPath];
MPElementType selectedType = selectedElement? selectedElement.type: [self.delegate selectedType]; MPSiteType selectedType = selectedElement? selectedElement.type: [self.delegate selectedType];
cell.selected = (selectedType == cellType); cell.selected = (selectedType == cellType);
if (cellType != (MPElementType)NSNotFound && cellType & MPElementTypeClassGenerated) { if (cellType != (MPSiteType)NSNotFound && cellType & MPSiteTypeClassGenerated) {
[(UITextField *)[cell viewWithTag:2] setText:@"..."]; [(UITextField *)[cell viewWithTag:2] setText:@"..."];
NSString *name = selectedElement.name; NSString *name = selectedElement.name;
@ -96,8 +96,8 @@
NSAssert(self.navigationController.topViewController == self, @"Not the currently active navigation item."); NSAssert(self.navigationController.topViewController == self, @"Not the currently active navigation item.");
MPElementType type = [self typeAtIndexPath:indexPath]; MPSiteType type = [self typeAtIndexPath:indexPath];
if (type == (MPElementType)NSNotFound) if (type == (MPSiteType)NSNotFound)
// Selected a non-type row. // Selected a non-type row.
return; return;
@ -105,28 +105,28 @@
[self.navigationController popViewControllerAnimated:YES]; [self.navigationController popViewControllerAnimated:YES];
} }
- (MPElementType)typeAtIndexPath:(NSIndexPath *)indexPath { - (MPSiteType)typeAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.section) { switch (indexPath.section) {
case 0: { case 0: {
// Generated // Generated
switch (indexPath.row) { switch (indexPath.row) {
case 0: case 0:
return (MPElementType)NSNotFound; return (MPSiteType)NSNotFound;
case 1: case 1:
return MPElementTypeGeneratedMaximum; return MPSiteTypeGeneratedMaximum;
case 2: case 2:
return MPElementTypeGeneratedLong; return MPSiteTypeGeneratedLong;
case 3: case 3:
return MPElementTypeGeneratedMedium; return MPSiteTypeGeneratedMedium;
case 4: case 4:
return MPElementTypeGeneratedBasic; return MPSiteTypeGeneratedBasic;
case 5: case 5:
return MPElementTypeGeneratedShort; return MPSiteTypeGeneratedShort;
case 6: case 6:
return MPElementTypeGeneratedPIN; return MPSiteTypeGeneratedPIN;
case 7: case 7:
return (MPElementType)NSNotFound; return (MPSiteType)NSNotFound;
default: { default: {
Throw(@"Unsupported row: %ld, when selecting generated element type.", (long)indexPath.row); Throw(@"Unsupported row: %ld, when selecting generated element type.", (long)indexPath.row);
@ -138,13 +138,13 @@
// Stored // Stored
switch (indexPath.row) { switch (indexPath.row) {
case 0: case 0:
return (MPElementType)NSNotFound; return (MPSiteType)NSNotFound;
case 1: case 1:
return MPElementTypeStoredPersonal; return MPSiteTypeStoredPersonal;
case 2: case 2:
return MPElementTypeStoredDevicePrivate; return MPSiteTypeStoredDevicePrivate;
case 3: case 3:
return (MPElementType)NSNotFound; return (MPSiteType)NSNotFound;
default: { default: {
Throw(@"Unsupported row: %ld, when selecting stored element type.", (long)indexPath.row); Throw(@"Unsupported row: %ld, when selecting stored element type.", (long)indexPath.row);

View File

@ -7,6 +7,7 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
93D390C1B93F9D3AE37DD0A5 /* MPAnswersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39C426E03358384018E85 /* MPAnswersViewController.m */; };
93D391ECBD9BD2C64115B5DD /* PearlSizedTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39156E806BB78E04F78B9 /* PearlSizedTextView.m */; }; 93D391ECBD9BD2C64115B5DD /* PearlSizedTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39156E806BB78E04F78B9 /* PearlSizedTextView.m */; };
93D391ED37C9F687FA51EAA1 /* MPEmergencySegue.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3937712BF1B67623E5764 /* MPEmergencySegue.m */; }; 93D391ED37C9F687FA51EAA1 /* MPEmergencySegue.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D3937712BF1B67623E5764 /* MPEmergencySegue.m */; };
93D3922A53E41A54832E90D9 /* PearlOverlay.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D390FADEB325D8D54A957D /* PearlOverlay.m */; }; 93D3922A53E41A54832E90D9 /* PearlOverlay.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D390FADEB325D8D54A957D /* PearlOverlay.m */; };
@ -157,6 +158,11 @@
DA854C8318D4CFBF00106317 /* avatar-add@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA854C8118D4CFBF00106317 /* avatar-add@2x.png */; }; DA854C8318D4CFBF00106317 /* avatar-add@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DA854C8118D4CFBF00106317 /* avatar-add@2x.png */; };
DA854C8418D4CFBF00106317 /* avatar-add.png in Resources */ = {isa = PBXBuildFile; fileRef = DA854C8218D4CFBF00106317 /* avatar-add.png */; }; DA854C8418D4CFBF00106317 /* avatar-add.png in Resources */ = {isa = PBXBuildFile; fileRef = DA854C8218D4CFBF00106317 /* avatar-add.png */; };
DA945C8717E3F3FD0053236B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA945C8617E3F3FD0053236B /* Images.xcassets */; }; DA945C8717E3F3FD0053236B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DA945C8617E3F3FD0053236B /* Images.xcassets */; };
DA9521A819CEA3DE002E3AD5 /* MPSiteEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9521A719CEA3DE002E3AD5 /* MPSiteEntity.m */; };
DA9521AB19CEA3DE002E3AD5 /* MPSiteQuestion.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9521AA19CEA3DE002E3AD5 /* MPSiteQuestion.m */; };
DA9521AE19CEA3DE002E3AD5 /* MPSiteStoredEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9521AD19CEA3DE002E3AD5 /* MPSiteStoredEntity.m */; };
DA9521B119CEA3DE002E3AD5 /* MPUserEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9521B019CEA3DE002E3AD5 /* MPUserEntity.m */; };
DA9521B419CEA3DE002E3AD5 /* MPSiteGeneratedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9521B319CEA3DE002E3AD5 /* MPSiteGeneratedEntity.m */; };
DA95D5F214DF0B2C008D1B94 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA95D5F014DF0B1E008D1B94 /* MessageUI.framework */; }; DA95D5F214DF0B2C008D1B94 /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA95D5F014DF0B1E008D1B94 /* MessageUI.framework */; };
DAA141201922FF020032B392 /* PearlTween.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA1411C1922FF020032B392 /* PearlTween.m */; }; DAA141201922FF020032B392 /* PearlTween.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA1411C1922FF020032B392 /* PearlTween.m */; };
DAA141211922FF020032B392 /* PearlTween.h in Headers */ = {isa = PBXBuildFile; fileRef = DAA1411D1922FF020032B392 /* PearlTween.h */; }; DAA141211922FF020032B392 /* PearlTween.h in Headers */ = {isa = PBXBuildFile; fileRef = DAA1411D1922FF020032B392 /* PearlTween.h */; };
@ -275,13 +281,14 @@
DACE2F6D19BA6A2A0010F92E /* PearlMutableStaticTableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = DACE2F6919BA6A2A0010F92E /* PearlMutableStaticTableViewController.h */; }; DACE2F6D19BA6A2A0010F92E /* PearlMutableStaticTableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = DACE2F6919BA6A2A0010F92E /* PearlMutableStaticTableViewController.h */; };
DACE2F6E19BA6A2A0010F92E /* UIView+FontScale.h in Headers */ = {isa = PBXBuildFile; fileRef = DACE2F6A19BA6A2A0010F92E /* UIView+FontScale.h */; }; DACE2F6E19BA6A2A0010F92E /* UIView+FontScale.h in Headers */ = {isa = PBXBuildFile; fileRef = DACE2F6A19BA6A2A0010F92E /* UIView+FontScale.h */; };
DAD312C21552A22700A3F9ED /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DAD312C01552A20800A3F9ED /* libsqlite3.dylib */; }; DAD312C21552A22700A3F9ED /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DAD312C01552A20800A3F9ED /* libsqlite3.dylib */; };
DADB4EC719C66FB60065A78D /* MPUserEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DADB4EC619C66FB60065A78D /* MPUserEntity.m */; };
DADB4ECA19C66FB60065A78D /* MPElementEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DADB4EC919C66FB60065A78D /* MPElementEntity.m */; };
DADB4ECD19C66FB60065A78D /* MPElementGeneratedEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DADB4ECC19C66FB60065A78D /* MPElementGeneratedEntity.m */; };
DADB4ED019C66FB70065A78D /* MPElementStoredEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = DADB4ECF19C66FB70065A78D /* MPElementStoredEntity.m */; };
DAE1EF2217E942DE00BC0086 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DAE1EF2417E942DE00BC0086 /* Localizable.strings */; }; DAE1EF2217E942DE00BC0086 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DAE1EF2417E942DE00BC0086 /* Localizable.strings */; };
DAE2725919C93B80007C5262 /* libInAppSettingsKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAFC5655172C573B00CB5CC5 /* libInAppSettingsKit.a */; }; DAE2725919C93B80007C5262 /* libInAppSettingsKit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DAFC5655172C573B00CB5CC5 /* libInAppSettingsKit.a */; };
DAE2725A19C93B8E007C5262 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA70EC7F1811B13C00F65DB2 /* StoreKit.framework */; }; DAE2725A19C93B8E007C5262 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA70EC7F1811B13C00F65DB2 /* StoreKit.framework */; };
DAE2725E19CA98A5007C5262 /* thumb_advanced_export.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE2725B19CA98A5007C5262 /* thumb_advanced_export.png */; };
DAE2725F19CA98A5007C5262 /* thumb_advanced_export@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE2725C19CA98A5007C5262 /* thumb_advanced_export@2x.png */; };
DAE2726019CA98A5007C5262 /* thumb_advanced_export@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = DAE2725D19CA98A5007C5262 /* thumb_advanced_export@3x.png */; };
DAE2726319CE9CB3007C5262 /* UITableViewCell+PearlDeque.m in Sources */ = {isa = PBXBuildFile; fileRef = DAE2726119CE9CB3007C5262 /* UITableViewCell+PearlDeque.m */; };
DAE2726419CE9CB3007C5262 /* UITableViewCell+PearlDeque.h in Headers */ = {isa = PBXBuildFile; fileRef = DAE2726219CE9CB3007C5262 /* UITableViewCell+PearlDeque.h */; };
DAEBC45314F6364500987BF6 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAEBC45214F6364500987BF6 /* QuartzCore.framework */; }; DAEBC45314F6364500987BF6 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAEBC45214F6364500987BF6 /* QuartzCore.framework */; };
DAEC85B518E3DD9A007FC0DF /* UIView+Touches.m in Sources */ = {isa = PBXBuildFile; fileRef = DAEC85B118E3DD9A007FC0DF /* UIView+Touches.m */; }; DAEC85B518E3DD9A007FC0DF /* UIView+Touches.m in Sources */ = {isa = PBXBuildFile; fileRef = DAEC85B118E3DD9A007FC0DF /* UIView+Touches.m */; };
DAEC85B618E3DD9A007FC0DF /* PearlUINavigationBar.m in Sources */ = {isa = PBXBuildFile; fileRef = DAEC85B218E3DD9A007FC0DF /* PearlUINavigationBar.m */; }; DAEC85B618E3DD9A007FC0DF /* PearlUINavigationBar.m in Sources */ = {isa = PBXBuildFile; fileRef = DAEC85B218E3DD9A007FC0DF /* PearlUINavigationBar.m */; };
@ -438,12 +445,14 @@
93D39B1D8177A86C5B9EDDE3 /* PearlUICollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlUICollectionView.h; sourceTree = "<group>"; }; 93D39B1D8177A86C5B9EDDE3 /* PearlUICollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlUICollectionView.h; sourceTree = "<group>"; };
93D39B381350802A194BF332 /* MPAvatarCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAvatarCell.m; sourceTree = "<group>"; }; 93D39B381350802A194BF332 /* MPAvatarCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAvatarCell.m; sourceTree = "<group>"; };
93D39BAA71DE51B4D8A1286C /* MPCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPCell.m; sourceTree = "<group>"; }; 93D39BAA71DE51B4D8A1286C /* MPCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPCell.m; sourceTree = "<group>"; };
93D39C426E03358384018E85 /* MPAnswersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAnswersViewController.m; sourceTree = "<group>"; };
93D39C44361BE57AF0B3071F /* MPPasswordsSegue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordsSegue.h; sourceTree = "<group>"; }; 93D39C44361BE57AF0B3071F /* MPPasswordsSegue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordsSegue.h; sourceTree = "<group>"; };
93D39C86E984EC65DA5ACB1D /* MPAppSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppSettingsViewController.h; sourceTree = "<group>"; }; 93D39C86E984EC65DA5ACB1D /* MPAppSettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppSettingsViewController.h; sourceTree = "<group>"; };
93D39CC01630D0421205C4C4 /* MPNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPNavigationController.m; sourceTree = "<group>"; }; 93D39CC01630D0421205C4C4 /* MPNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPNavigationController.m; sourceTree = "<group>"; };
93D39CDD434AFD6E1B0DA359 /* MPEmergencyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEmergencyViewController.h; sourceTree = "<group>"; }; 93D39CDD434AFD6E1B0DA359 /* MPEmergencyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEmergencyViewController.h; sourceTree = "<group>"; };
93D39CECA10BCCB0BA581BF1 /* MPAppDelegate_InApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppDelegate_InApp.h; sourceTree = "<group>"; }; 93D39CECA10BCCB0BA581BF1 /* MPAppDelegate_InApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAppDelegate_InApp.h; sourceTree = "<group>"; };
93D39CF8ADF4542CDC4CD385 /* MPCombinedViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCombinedViewController.h; sourceTree = "<group>"; }; 93D39CF8ADF4542CDC4CD385 /* MPCombinedViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPCombinedViewController.h; sourceTree = "<group>"; };
93D39D6604447D7708039155 /* MPAnswersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAnswersViewController.h; sourceTree = "<group>"; };
93D39D8A953779B35403AF6E /* PearlUICollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlUICollectionView.m; sourceTree = "<group>"; }; 93D39D8A953779B35403AF6E /* PearlUICollectionView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlUICollectionView.m; sourceTree = "<group>"; };
93D39DA27D768B53C8B1330C /* MPAvatarCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAvatarCell.h; sourceTree = "<group>"; }; 93D39DA27D768B53C8B1330C /* MPAvatarCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAvatarCell.h; sourceTree = "<group>"; };
93D39DE2CB351D4E3789462B /* UIScrollView+PearlAdjustInsets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+PearlAdjustInsets.h"; sourceTree = "<group>"; }; 93D39DE2CB351D4E3789462B /* UIScrollView+PearlAdjustInsets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIScrollView+PearlAdjustInsets.h"; sourceTree = "<group>"; };
@ -529,6 +538,16 @@
DA854C8118D4CFBF00106317 /* avatar-add@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-add@2x.png"; sourceTree = "<group>"; }; DA854C8118D4CFBF00106317 /* avatar-add@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-add@2x.png"; sourceTree = "<group>"; };
DA854C8218D4CFBF00106317 /* avatar-add.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-add.png"; sourceTree = "<group>"; }; DA854C8218D4CFBF00106317 /* avatar-add.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "avatar-add.png"; sourceTree = "<group>"; };
DA945C8617E3F3FD0053236B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; }; DA945C8617E3F3FD0053236B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
DA9521A619CEA3DE002E3AD5 /* MPSiteEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteEntity.h; sourceTree = "<group>"; };
DA9521A719CEA3DE002E3AD5 /* MPSiteEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSiteEntity.m; sourceTree = "<group>"; };
DA9521A919CEA3DE002E3AD5 /* MPSiteQuestion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteQuestion.h; sourceTree = "<group>"; };
DA9521AA19CEA3DE002E3AD5 /* MPSiteQuestion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSiteQuestion.m; sourceTree = "<group>"; };
DA9521AC19CEA3DE002E3AD5 /* MPSiteStoredEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteStoredEntity.h; sourceTree = "<group>"; };
DA9521AD19CEA3DE002E3AD5 /* MPSiteStoredEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSiteStoredEntity.m; sourceTree = "<group>"; };
DA9521AF19CEA3DE002E3AD5 /* MPUserEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPUserEntity.h; sourceTree = "<group>"; };
DA9521B019CEA3DE002E3AD5 /* MPUserEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPUserEntity.m; sourceTree = "<group>"; };
DA9521B219CEA3DE002E3AD5 /* MPSiteGeneratedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteGeneratedEntity.h; sourceTree = "<group>"; };
DA9521B319CEA3DE002E3AD5 /* MPSiteGeneratedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSiteGeneratedEntity.m; sourceTree = "<group>"; };
DA95D5F014DF0B1E008D1B94 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; DA95D5F014DF0B1E008D1B94 /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; };
DAA141191922FED80032B392 /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Crashlytics.framework; sourceTree = "<group>"; }; DAA141191922FED80032B392 /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Crashlytics.framework; sourceTree = "<group>"; };
DAA1411C1922FF020032B392 /* PearlTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlTween.m; sourceTree = "<group>"; }; DAA1411C1922FF020032B392 /* PearlTween.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PearlTween.m; sourceTree = "<group>"; };
@ -1174,19 +1193,11 @@
DABD3BAB1711E2DC00CF925C /* MPAppDelegate_Store.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_Store.m; sourceTree = "<group>"; }; DABD3BAB1711E2DC00CF925C /* MPAppDelegate_Store.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAppDelegate_Store.m; sourceTree = "<group>"; };
DABD3BAC1711E2DC00CF925C /* MPConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPConfig.h; sourceTree = "<group>"; }; DABD3BAC1711E2DC00CF925C /* MPConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPConfig.h; sourceTree = "<group>"; };
DABD3BAD1711E2DC00CF925C /* MPConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPConfig.m; sourceTree = "<group>"; }; DABD3BAD1711E2DC00CF925C /* MPConfig.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPConfig.m; sourceTree = "<group>"; };
DABD3BAE1711E2DC00CF925C /* MPElementEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementEntity.h; sourceTree = "<group>"; };
DABD3BAF1711E2DC00CF925C /* MPElementEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementEntity.m; sourceTree = "<group>"; };
DABD3BB01711E2DC00CF925C /* MPElementGeneratedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementGeneratedEntity.h; sourceTree = "<group>"; };
DABD3BB11711E2DC00CF925C /* MPElementGeneratedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementGeneratedEntity.m; sourceTree = "<group>"; };
DABD3BB21711E2DC00CF925C /* MPElementStoredEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementStoredEntity.h; sourceTree = "<group>"; };
DABD3BB31711E2DC00CF925C /* MPElementStoredEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementStoredEntity.m; sourceTree = "<group>"; };
DABD3BB41711E2DC00CF925C /* MPEntities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEntities.h; sourceTree = "<group>"; }; DABD3BB41711E2DC00CF925C /* MPEntities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPEntities.h; sourceTree = "<group>"; };
DABD3BB51711E2DC00CF925C /* MPEntities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPEntities.m; sourceTree = "<group>"; }; DABD3BB51711E2DC00CF925C /* MPEntities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPEntities.m; sourceTree = "<group>"; };
DABD3BB61711E2DC00CF925C /* MPKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPKey.h; sourceTree = "<group>"; }; DABD3BB61711E2DC00CF925C /* MPKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPKey.h; sourceTree = "<group>"; };
DABD3BB71711E2DC00CF925C /* MPKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPKey.m; sourceTree = "<group>"; }; DABD3BB71711E2DC00CF925C /* MPKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPKey.m; sourceTree = "<group>"; };
DABD3BB81711E2DC00CF925C /* MPTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPTypes.h; sourceTree = "<group>"; }; DABD3BB81711E2DC00CF925C /* MPTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPTypes.h; sourceTree = "<group>"; };
DABD3BB91711E2DC00CF925C /* MPUserEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPUserEntity.h; sourceTree = "<group>"; };
DABD3BBA1711E2DC00CF925C /* MPUserEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPUserEntity.m; sourceTree = "<group>"; };
DABD3BD11711E2DC00CF925C /* MasterPassword 1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 1.xcdatamodel"; sourceTree = "<group>"; }; DABD3BD11711E2DC00CF925C /* MasterPassword 1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 1.xcdatamodel"; sourceTree = "<group>"; };
DABD3BD21711E2DC00CF925C /* MasterPassword 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 2.xcdatamodel"; sourceTree = "<group>"; }; DABD3BD21711E2DC00CF925C /* MasterPassword 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 2.xcdatamodel"; sourceTree = "<group>"; };
DABD3BD31711E2DC00CF925C /* MasterPassword 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 3.xcdatamodel"; sourceTree = "<group>"; }; DABD3BD31711E2DC00CF925C /* MasterPassword 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "MasterPassword 3.xcdatamodel"; sourceTree = "<group>"; };
@ -1232,16 +1243,13 @@
DACE2F6919BA6A2A0010F92E /* PearlMutableStaticTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlMutableStaticTableViewController.h; sourceTree = "<group>"; }; DACE2F6919BA6A2A0010F92E /* PearlMutableStaticTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PearlMutableStaticTableViewController.h; sourceTree = "<group>"; };
DACE2F6A19BA6A2A0010F92E /* UIView+FontScale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+FontScale.h"; sourceTree = "<group>"; }; DACE2F6A19BA6A2A0010F92E /* UIView+FontScale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+FontScale.h"; sourceTree = "<group>"; };
DAD312C01552A20800A3F9ED /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; }; DAD312C01552A20800A3F9ED /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = usr/lib/libsqlite3.dylib; sourceTree = SDKROOT; };
DADB4EC519C66FB50065A78D /* MPUserEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPUserEntity.h; sourceTree = "<group>"; };
DADB4EC619C66FB60065A78D /* MPUserEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPUserEntity.m; sourceTree = "<group>"; };
DADB4EC819C66FB60065A78D /* MPElementEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementEntity.h; sourceTree = "<group>"; };
DADB4EC919C66FB60065A78D /* MPElementEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementEntity.m; sourceTree = "<group>"; };
DADB4ECB19C66FB60065A78D /* MPElementGeneratedEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementGeneratedEntity.h; sourceTree = "<group>"; };
DADB4ECC19C66FB60065A78D /* MPElementGeneratedEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementGeneratedEntity.m; sourceTree = "<group>"; };
DADB4ECE19C66FB60065A78D /* MPElementStoredEntity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementStoredEntity.h; sourceTree = "<group>"; };
DADB4ECF19C66FB70065A78D /* MPElementStoredEntity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementStoredEntity.m; sourceTree = "<group>"; };
DADBB55918DB0CFC00D099FE /* keyboard-dark@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "keyboard-dark@2x.png"; sourceTree = "<group>"; }; DADBB55918DB0CFC00D099FE /* keyboard-dark@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "keyboard-dark@2x.png"; sourceTree = "<group>"; };
DAE1EF2317E942DE00BC0086 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; }; DAE1EF2317E942DE00BC0086 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
DAE2725B19CA98A5007C5262 /* thumb_advanced_export.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = thumb_advanced_export.png; sourceTree = "<group>"; };
DAE2725C19CA98A5007C5262 /* thumb_advanced_export@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "thumb_advanced_export@2x.png"; sourceTree = "<group>"; };
DAE2725D19CA98A5007C5262 /* thumb_advanced_export@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "thumb_advanced_export@3x.png"; sourceTree = "<group>"; };
DAE2726119CE9CB3007C5262 /* UITableViewCell+PearlDeque.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITableViewCell+PearlDeque.m"; sourceTree = "<group>"; };
DAE2726219CE9CB3007C5262 /* UITableViewCell+PearlDeque.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITableViewCell+PearlDeque.h"; sourceTree = "<group>"; };
DAE8E65119867AB500416A0F /* libopensslcrypto-ios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libopensslcrypto-ios.a"; sourceTree = "<group>"; }; DAE8E65119867AB500416A0F /* libopensslcrypto-ios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libopensslcrypto-ios.a"; sourceTree = "<group>"; };
DAEBC45214F6364500987BF6 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; DAEBC45214F6364500987BF6 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
DAEC85B118E3DD9A007FC0DF /* UIView+Touches.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Touches.m"; sourceTree = "<group>"; }; DAEC85B118E3DD9A007FC0DF /* UIView+Touches.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Touches.m"; sourceTree = "<group>"; };
@ -1473,6 +1481,8 @@
DA5BFA45147E415C00F98B1E /* Products */, DA5BFA45147E415C00F98B1E /* Products */,
93D39149A5F1F9B174D6D061 /* MPStoreViewController.h */, 93D39149A5F1F9B174D6D061 /* MPStoreViewController.h */,
93D3957D76F71A652716EECC /* MPStoreViewController.m */, 93D3957D76F71A652716EECC /* MPStoreViewController.m */,
93D39C426E03358384018E85 /* MPAnswersViewController.m */,
93D39D6604447D7708039155 /* MPAnswersViewController.h */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
@ -1553,6 +1563,9 @@
DABD360D1711E29400CF925C /* Media */ = { DABD360D1711E29400CF925C /* Media */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DAE2725B19CA98A5007C5262 /* thumb_advanced_export.png */,
DAE2725C19CA98A5007C5262 /* thumb_advanced_export@2x.png */,
DAE2725D19CA98A5007C5262 /* thumb_advanced_export@3x.png */,
DA29993119C9132F00AF7DF1 /* thumb_generated_login@3x.png */, DA29993119C9132F00AF7DF1 /* thumb_generated_login@3x.png */,
DA29992D19C86F5700AF7DF1 /* thumb_generated_login@2x.png */, DA29992D19C86F5700AF7DF1 /* thumb_generated_login@2x.png */,
DA29992E19C86F5700AF7DF1 /* thumb_generated_login.png */, DA29992E19C86F5700AF7DF1 /* thumb_generated_login.png */,
@ -2257,14 +2270,6 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DABD3BD71711E2DC00CF925C /* iOS */, DABD3BD71711E2DC00CF925C /* iOS */,
DADB4ECE19C66FB60065A78D /* MPElementStoredEntity.h */,
DADB4ECF19C66FB70065A78D /* MPElementStoredEntity.m */,
DADB4ECB19C66FB60065A78D /* MPElementGeneratedEntity.h */,
DADB4ECC19C66FB60065A78D /* MPElementGeneratedEntity.m */,
DADB4EC819C66FB60065A78D /* MPElementEntity.h */,
DADB4EC919C66FB60065A78D /* MPElementEntity.m */,
DADB4EC519C66FB50065A78D /* MPUserEntity.h */,
DADB4EC619C66FB60065A78D /* MPUserEntity.m */,
DABD3BA01711E2DC00CF925C /* MPAlgorithm.h */, DABD3BA01711E2DC00CF925C /* MPAlgorithm.h */,
DABD3BA11711E2DC00CF925C /* MPAlgorithm.m */, DABD3BA11711E2DC00CF925C /* MPAlgorithm.m */,
DABD3BA21711E2DC00CF925C /* MPAlgorithmV0.h */, DABD3BA21711E2DC00CF925C /* MPAlgorithmV0.h */,
@ -2279,20 +2284,22 @@
DABD3BAB1711E2DC00CF925C /* MPAppDelegate_Store.m */, DABD3BAB1711E2DC00CF925C /* MPAppDelegate_Store.m */,
DABD3BAC1711E2DC00CF925C /* MPConfig.h */, DABD3BAC1711E2DC00CF925C /* MPConfig.h */,
DABD3BAD1711E2DC00CF925C /* MPConfig.m */, DABD3BAD1711E2DC00CF925C /* MPConfig.m */,
DABD3BAE1711E2DC00CF925C /* MPElementEntity.h */,
DABD3BAF1711E2DC00CF925C /* MPElementEntity.m */,
DABD3BB01711E2DC00CF925C /* MPElementGeneratedEntity.h */,
DABD3BB11711E2DC00CF925C /* MPElementGeneratedEntity.m */,
DABD3BB21711E2DC00CF925C /* MPElementStoredEntity.h */,
DABD3BB31711E2DC00CF925C /* MPElementStoredEntity.m */,
DABD3BB41711E2DC00CF925C /* MPEntities.h */, DABD3BB41711E2DC00CF925C /* MPEntities.h */,
DABD3BB51711E2DC00CF925C /* MPEntities.m */, DABD3BB51711E2DC00CF925C /* MPEntities.m */,
DABD3BB61711E2DC00CF925C /* MPKey.h */, DABD3BB61711E2DC00CF925C /* MPKey.h */,
DABD3BB71711E2DC00CF925C /* MPKey.m */, DABD3BB71711E2DC00CF925C /* MPKey.m */,
DABD3BB81711E2DC00CF925C /* MPTypes.h */, DABD3BB81711E2DC00CF925C /* MPTypes.h */,
DABD3BB91711E2DC00CF925C /* MPUserEntity.h */,
DABD3BBA1711E2DC00CF925C /* MPUserEntity.m */,
DABD3BD01711E2DC00CF925C /* MasterPassword.xcdatamodeld */, DABD3BD01711E2DC00CF925C /* MasterPassword.xcdatamodeld */,
DA9521AC19CEA3DE002E3AD5 /* MPSiteStoredEntity.h */,
DA9521AF19CEA3DE002E3AD5 /* MPUserEntity.h */,
DA9521B019CEA3DE002E3AD5 /* MPUserEntity.m */,
DA9521AD19CEA3DE002E3AD5 /* MPSiteStoredEntity.m */,
DA9521B219CEA3DE002E3AD5 /* MPSiteGeneratedEntity.h */,
DA9521B319CEA3DE002E3AD5 /* MPSiteGeneratedEntity.m */,
DA9521A919CEA3DE002E3AD5 /* MPSiteQuestion.h */,
DA9521AA19CEA3DE002E3AD5 /* MPSiteQuestion.m */,
DA9521A619CEA3DE002E3AD5 /* MPSiteEntity.h */,
DA9521A719CEA3DE002E3AD5 /* MPSiteEntity.m */,
93D399F244BB522A317811BB /* MPFixable.h */, 93D399F244BB522A317811BB /* MPFixable.h */,
93D39A813CA9D7E192261ED2 /* MPFixable.m */, 93D39A813CA9D7E192261ED2 /* MPFixable.m */,
93D394C78C7B879C9AD9152C /* MPAppDelegate_InApp.m */, 93D394C78C7B879C9AD9152C /* MPAppDelegate_InApp.m */,
@ -2589,6 +2596,8 @@
DAFE460715039823003ABA7C /* Pearl-UIKit */ = { DAFE460715039823003ABA7C /* Pearl-UIKit */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
DAE2726119CE9CB3007C5262 /* UITableViewCell+PearlDeque.m */,
DAE2726219CE9CB3007C5262 /* UITableViewCell+PearlDeque.h */,
DAEFB01C19BCBD9E00525079 /* UIView+LayoutGone.m */, DAEFB01C19BCBD9E00525079 /* UIView+LayoutGone.m */,
DAEFB01D19BCBD9E00525079 /* UIView+LayoutGone.h */, DAEFB01D19BCBD9E00525079 /* UIView+LayoutGone.h */,
DACE2F6719BA6A2A0010F92E /* UIView+FontScale.m */, DACE2F6719BA6A2A0010F92E /* UIView+FontScale.m */,
@ -2725,6 +2734,7 @@
DAFE4A3415039824003ABA7C /* PearlCryptUtils.h in Headers */, DAFE4A3415039824003ABA7C /* PearlCryptUtils.h in Headers */,
DAFE4A3615039824003ABA7C /* PearlKeyChain.h in Headers */, DAFE4A3615039824003ABA7C /* PearlKeyChain.h in Headers */,
DAFE4A3815039824003ABA7C /* PearlRSAKey.h in Headers */, DAFE4A3815039824003ABA7C /* PearlRSAKey.h in Headers */,
DAE2726419CE9CB3007C5262 /* UITableViewCell+PearlDeque.h in Headers */,
DAFE4A3A15039824003ABA7C /* PearlSCrypt.h in Headers */, DAFE4A3A15039824003ABA7C /* PearlSCrypt.h in Headers */,
DACE2F6E19BA6A2A0010F92E /* UIView+FontScale.h in Headers */, DACE2F6E19BA6A2A0010F92E /* UIView+FontScale.h in Headers */,
DAFE4A3C15039824003ABA7C /* Pearl-UIKit-Dependencies.h in Headers */, DAFE4A3C15039824003ABA7C /* Pearl-UIKit-Dependencies.h in Headers */,
@ -3071,6 +3081,7 @@
DA250A031956484D00AC23F1 /* image-7@2x.png in Resources */, DA250A031956484D00AC23F1 /* image-7@2x.png in Resources */,
DA25C5FA197CCAE00046CDCF /* icon_delete.png in Resources */, DA25C5FA197CCAE00046CDCF /* icon_delete.png in Resources */,
DA25C601197DBF260046CDCF /* icon_trash@2x.png in Resources */, DA25C601197DBF260046CDCF /* icon_trash@2x.png in Resources */,
DAE2725E19CA98A5007C5262 /* thumb_advanced_export.png in Resources */,
DABD39551711E29700CF925C /* avatar-6.png in Resources */, DABD39551711E29700CF925C /* avatar-6.png in Resources */,
DABD39561711E29700CF925C /* avatar-6@2x.png in Resources */, DABD39561711E29700CF925C /* avatar-6@2x.png in Resources */,
DABD39571711E29700CF925C /* avatar-7.png in Resources */, DABD39571711E29700CF925C /* avatar-7.png in Resources */,
@ -3092,6 +3103,7 @@
DABD39881711E29700CF925C /* SourceCodePro-ExtraLight.otf in Resources */, DABD39881711E29700CF925C /* SourceCodePro-ExtraLight.otf in Resources */,
DABD39A01711E29700CF925C /* icon_action.png in Resources */, DABD39A01711E29700CF925C /* icon_action.png in Resources */,
DABD39A11711E29700CF925C /* icon_action@2x.png in Resources */, DABD39A11711E29700CF925C /* icon_action@2x.png in Resources */,
DAE2726019CA98A5007C5262 /* thumb_advanced_export@3x.png in Resources */,
DABD39F21711E29700CF925C /* icon_cancel.png in Resources */, DABD39F21711E29700CF925C /* icon_cancel.png in Resources */,
DA25C5FB197CCAE00046CDCF /* icon_delete@2x.png in Resources */, DA25C5FB197CCAE00046CDCF /* icon_delete@2x.png in Resources */,
DA29993219C9132F00AF7DF1 /* thumb_generated_login@3x.png in Resources */, DA29993219C9132F00AF7DF1 /* thumb_generated_login@3x.png in Resources */,
@ -3106,6 +3118,7 @@
DABD3AA01711E29800CF925C /* icon_pause.png in Resources */, DABD3AA01711E29800CF925C /* icon_pause.png in Resources */,
DABD3AA11711E29800CF925C /* icon_pause@2x.png in Resources */, DABD3AA11711E29800CF925C /* icon_pause@2x.png in Resources */,
DABD3AAA1711E29800CF925C /* icon_person.png in Resources */, DABD3AAA1711E29800CF925C /* icon_person.png in Resources */,
DAE2725F19CA98A5007C5262 /* thumb_advanced_export@2x.png in Resources */,
DABD3AAB1711E29800CF925C /* icon_person@2x.png in Resources */, DABD3AAB1711E29800CF925C /* icon_person@2x.png in Resources */,
DABD3ABC1711E29800CF925C /* icon_play.png in Resources */, DABD3ABC1711E29800CF925C /* icon_play.png in Resources */,
DABD3ABD1711E29800CF925C /* icon_play@2x.png in Resources */, DABD3ABD1711E29800CF925C /* icon_play@2x.png in Resources */,
@ -3209,19 +3222,19 @@
DABD3C081711E2DC00CF925C /* MPKey.m in Sources */, DABD3C081711E2DC00CF925C /* MPKey.m in Sources */,
DABD3C141711E2DC00CF925C /* MasterPassword.xcdatamodeld in Sources */, DABD3C141711E2DC00CF925C /* MasterPassword.xcdatamodeld in Sources */,
DABD3C151711E2DC00CF925C /* MPiOSAppDelegate.m in Sources */, DABD3C151711E2DC00CF925C /* MPiOSAppDelegate.m in Sources */,
DA9521A819CEA3DE002E3AD5 /* MPSiteEntity.m in Sources */,
DABD3C1C1711E2DC00CF925C /* MPGuideViewController.m in Sources */, DABD3C1C1711E2DC00CF925C /* MPGuideViewController.m in Sources */,
DABD3C1E1711E2DC00CF925C /* MPPreferencesViewController.m in Sources */, DABD3C1E1711E2DC00CF925C /* MPPreferencesViewController.m in Sources */,
DABD3C1F1711E2DC00CF925C /* MPTypeViewController.m in Sources */, DABD3C1F1711E2DC00CF925C /* MPTypeViewController.m in Sources */,
DABD3C211711E2DC00CF925C /* MPiOSConfig.m in Sources */, DABD3C211711E2DC00CF925C /* MPiOSConfig.m in Sources */,
DABD3C271711E2DC00CF925C /* main.m in Sources */, DABD3C271711E2DC00CF925C /* main.m in Sources */,
DADB4EC719C66FB60065A78D /* MPUserEntity.m in Sources */,
93D39F8A9254177891F38705 /* MPSetupViewController.m in Sources */, 93D39F8A9254177891F38705 /* MPSetupViewController.m in Sources */,
DA9521AE19CEA3DE002E3AD5 /* MPSiteStoredEntity.m in Sources */,
DA095E75172F4CD8001C948B /* MPLogsViewController.m in Sources */, DA095E75172F4CD8001C948B /* MPLogsViewController.m in Sources */,
93D39D596A2E376D6F6F5DA1 /* MPCombinedViewController.m in Sources */, 93D39D596A2E376D6F6F5DA1 /* MPCombinedViewController.m in Sources */,
DADB4ECD19C66FB60065A78D /* MPElementGeneratedEntity.m in Sources */,
93D3957237D303DE2D38C267 /* MPAvatarCell.m in Sources */, 93D3957237D303DE2D38C267 /* MPAvatarCell.m in Sources */,
93D39B8F90F58A5D158DDBA3 /* MPPasswordsViewController.m in Sources */, 93D39B8F90F58A5D158DDBA3 /* MPPasswordsViewController.m in Sources */,
DADB4ED019C66FB70065A78D /* MPElementStoredEntity.m in Sources */, DA9521B419CEA3DE002E3AD5 /* MPSiteGeneratedEntity.m in Sources */,
93D3954FCE045A3CC7E804B7 /* MPUsersViewController.m in Sources */, 93D3954FCE045A3CC7E804B7 /* MPUsersViewController.m in Sources */,
93D39392DEDA376F93C6C718 /* MPCell.m in Sources */, 93D39392DEDA376F93C6C718 /* MPCell.m in Sources */,
93D39A5FF670957C0AF8298D /* MPPasswordCell.m in Sources */, 93D39A5FF670957C0AF8298D /* MPPasswordCell.m in Sources */,
@ -3231,9 +3244,9 @@
93D39673DDC085BE72C34D7C /* MPPopdownSegue.m in Sources */, 93D39673DDC085BE72C34D7C /* MPPopdownSegue.m in Sources */,
93D39BA1EA3CAAC8A220B4A6 /* MPAppSettingsViewController.m in Sources */, 93D39BA1EA3CAAC8A220B4A6 /* MPAppSettingsViewController.m in Sources */,
93D396D8B67DA6522CDBA142 /* MPCoachmarkViewController.m in Sources */, 93D396D8B67DA6522CDBA142 /* MPCoachmarkViewController.m in Sources */,
DADB4ECA19C66FB60065A78D /* MPElementEntity.m in Sources */,
93D39EAA4D064193074D3021 /* MPFixable.m in Sources */, 93D39EAA4D064193074D3021 /* MPFixable.m in Sources */,
93D394982CBD25D46692DD7C /* MPWebViewController.m in Sources */, 93D394982CBD25D46692DD7C /* MPWebViewController.m in Sources */,
DA9521B119CEA3DE002E3AD5 /* MPUserEntity.m in Sources */,
93D39D8F78978196D6ABDEDE /* MPNavigationController.m in Sources */, 93D39D8F78978196D6ABDEDE /* MPNavigationController.m in Sources */,
93D3939661CE37180AF7CD6A /* MPStoreViewController.m in Sources */, 93D3939661CE37180AF7CD6A /* MPStoreViewController.m in Sources */,
DA9521AB19CEA3DE002E3AD5 /* MPSiteQuestion.m in Sources */, DA9521AB19CEA3DE002E3AD5 /* MPSiteQuestion.m in Sources */,
@ -3290,6 +3303,7 @@
DAFE4A4715039824003ABA7C /* PearlLayout.m in Sources */, DAFE4A4715039824003ABA7C /* PearlLayout.m in Sources */,
DA250A19195665A100AC23F1 /* UICollectionReusableView+PearlDequeue.m in Sources */, DA250A19195665A100AC23F1 /* UICollectionReusableView+PearlDequeue.m in Sources */,
DAFE4A4915039824003ABA7C /* PearlLayoutView.m in Sources */, DAFE4A4915039824003ABA7C /* PearlLayoutView.m in Sources */,
DAE2726319CE9CB3007C5262 /* UITableViewCell+PearlDeque.m in Sources */,
DAFE4A4B15039824003ABA7C /* PearlMessageView.m in Sources */, DAFE4A4B15039824003ABA7C /* PearlMessageView.m in Sources */,
DACE2F6519BA6A0A0010F92E /* PearlProfiler.m in Sources */, DACE2F6519BA6A0A0010F92E /* PearlProfiler.m in Sources */,
DAFE4A4D15039824003ABA7C /* PearlRootViewController.m in Sources */, DAFE4A4D15039824003ABA7C /* PearlRootViewController.m in Sources */,

View File

@ -26,6 +26,9 @@
<string>Exo2.0-Bold</string> <string>Exo2.0-Bold</string>
<string>Exo2.0-Bold</string> <string>Exo2.0-Bold</string>
<string>Exo2.0-Bold</string> <string>Exo2.0-Bold</string>
<string>Exo2.0-Bold</string>
<string>Exo2.0-Bold</string>
<string>Exo2.0-Bold</string>
</mutableArray> </mutableArray>
<mutableArray key="Exo2.0-ExtraBold.otf"> <mutableArray key="Exo2.0-ExtraBold.otf">
<string>Exo2.0-ExtraBold</string> <string>Exo2.0-ExtraBold</string>
@ -64,6 +67,7 @@
<string>Exo2.0-Regular</string> <string>Exo2.0-Regular</string>
<string>Exo2.0-Regular</string> <string>Exo2.0-Regular</string>
<string>Exo2.0-Regular</string> <string>Exo2.0-Regular</string>
<string>Exo2.0-Regular</string>
</mutableArray> </mutableArray>
<mutableArray key="Exo2.0-Thin.otf"> <mutableArray key="Exo2.0-Thin.otf">
<string>Exo2.0-Thin</string> <string>Exo2.0-Thin</string>
@ -82,11 +86,15 @@
<string>Exo2.0-Thin</string> <string>Exo2.0-Thin</string>
<string>Exo2.0-Thin</string> <string>Exo2.0-Thin</string>
<string>Exo2.0-Thin</string> <string>Exo2.0-Thin</string>
<string>Exo2.0-Thin</string>
<string>Exo2.0-Thin</string>
</mutableArray> </mutableArray>
<mutableArray key="SourceCodePro-Black.otf"> <mutableArray key="SourceCodePro-Black.otf">
<string>SourceCodePro-Black</string> <string>SourceCodePro-Black</string>
<string>SourceCodePro-Black</string> <string>SourceCodePro-Black</string>
<string>SourceCodePro-Black</string> <string>SourceCodePro-Black</string>
<string>SourceCodePro-Black</string>
<string>SourceCodePro-Black</string>
</mutableArray> </mutableArray>
<mutableArray key="SourceCodePro-ExtraLight.otf"> <mutableArray key="SourceCodePro-ExtraLight.otf">
<string>SourceCodePro-ExtraLight</string> <string>SourceCodePro-ExtraLight</string>
@ -581,7 +589,7 @@
</tabBarController> </tabBarController>
<placeholder placeholderIdentifier="IBFirstResponder" id="4Z1-Y7-eUn" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="4Z1-Y7-eUn" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="1408.5" y="1319.5"/> <point key="canvasLocation" x="2016.5" y="1319.5"/>
</scene> </scene>
<!--Preferences--> <!--Preferences-->
<scene sceneID="w0h-au-0xw"> <scene sceneID="w0h-au-0xw">
@ -1035,7 +1043,7 @@
</tableViewController> </tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="fk3-aq-W8p" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="fk3-aq-W8p" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="2016.5" y="2175.5"/> <point key="canvasLocation" x="2624.5" y="2175.5"/>
</scene> </scene>
<!--Passwords View Controller--> <!--Passwords View Controller-->
<scene sceneID="I40-Es-1gK"> <scene sceneID="I40-Es-1gK">
@ -1575,6 +1583,7 @@
<outlet property="popdownToTopConstraint" destination="BdD-Kc-eHl" id="59Y-ap-Yn4"/> <outlet property="popdownToTopConstraint" destination="BdD-Kc-eHl" id="59Y-ap-Yn4"/>
<outlet property="popdownView" destination="XNM-XQ-rMe" id="FaW-4m-Fff"/> <outlet property="popdownView" destination="XNM-XQ-rMe" id="FaW-4m-Fff"/>
<segue destination="z9O-w0-6oR" kind="modal" identifier="guide" id="Ql4-wf-T8u"/> <segue destination="z9O-w0-6oR" kind="modal" identifier="guide" id="Ql4-wf-T8u"/>
<segue destination="koB-V2-GYf" kind="modal" identifier="answers" id="PbR-2r-Ebm"/>
</connections> </connections>
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="APh-u5-vFI" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="APh-u5-vFI" userLabel="First Responder" sceneMemberID="firstResponder"/>
@ -1864,7 +1873,7 @@
</navigationController> </navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="PQz-c8-3Ww" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="PQz-c8-3Ww" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="2016.5" y="1319.5"/> <point key="canvasLocation" x="2624.5" y="1319.5"/>
</scene> </scene>
<!--Settings--> <!--Settings-->
<scene sceneID="fmc-CS-nuo"> <scene sceneID="fmc-CS-nuo">
@ -1899,7 +1908,7 @@
</tableViewController> </tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="sDE-fE-FNc" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="sDE-fE-FNc" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="2656.5" y="1319.5"/> <point key="canvasLocation" x="3264.5" y="1319.5"/>
</scene> </scene>
<!--Usage--> <!--Usage-->
<scene sceneID="9SY-7D-CE9"> <scene sceneID="9SY-7D-CE9">
@ -2099,7 +2108,7 @@ Suspendisse potenti. Etiam ut nisi id augue tempor ultrices et sit amet sapien.
</viewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="SoG-sw-ghb" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="SoG-sw-ghb" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="1408.5" y="2175.5"/> <point key="canvasLocation" x="2016.5" y="2175.5"/>
</scene> </scene>
<!--Pearl Navigation Controller--> <!--Pearl Navigation Controller-->
<scene sceneID="rfj-6W-TSu"> <scene sceneID="rfj-6W-TSu">
@ -2550,7 +2559,7 @@ See </string>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="thumb_generated_login.png" translatesAutoresizingMaskIntoConstraints="NO" id="dPE-KG-tzV"> <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="thumb_advanced_export.png" translatesAutoresizingMaskIntoConstraints="NO" id="dPE-KG-tzV">
<rect key="frame" x="88" y="20" width="198" height="198"/> <rect key="frame" x="88" y="20" width="198" height="198"/>
</imageView> </imageView>
<activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="27T-E7-pLh"> <activityIndicatorView hidden="YES" opaque="NO" tag="2" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="27T-E7-pLh">
@ -2787,7 +2796,182 @@ See </string>
</tableViewController> </tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="WvF-bk-cgx" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="WvF-bk-cgx" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="2016.5" y="442.5"/> <point key="canvasLocation" x="2624.5" y="463.5"/>
</scene>
<!--Preferences-->
<scene sceneID="u8w-6D-Zhe">
<objects>
<tableViewController automaticallyAdjustsScrollViewInsets="NO" id="koB-V2-GYf" customClass="MPAnswersViewController" sceneMemberID="viewController">
<tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="vKY-AK-ugj" customClass="MPTableView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="0.12549020350000001" green="0.1411764771" blue="0.14901961389999999" alpha="1" colorSpace="calibratedRGB"/>
<inset key="scrollIndicatorInsets" minX="0.0" minY="64" maxX="0.0" maxY="49"/>
<color key="separatorColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="1" colorSpace="calibratedRGB"/>
<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="0.0" width="320" height="97"/>
<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="287" height="96"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="Answer for lyndir.com:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Tal-1I-HQw" userLabel="Title Label">
<rect key="frame" x="8" y="8" width="180" height="20.5"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="hok petwuvaqu xixo" textAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="GfC-j4-Qx7" userLabel="Answer Field">
<rect key="frame" x="8" y="48" width="359" height="43"/>
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="fontDescription" name="SourceCodePro-Black" family="Source Code Pro" pointSize="24"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="alphabet" keyboardAppearance="alert" returnKeyType="next"/>
<connections>
<action selector="textFieldDidChange:" destination="W2g-yv-V3V" eventType="editingChanged" id="fY9-xg-DPG"/>
<outlet property="delegate" destination="W2g-yv-V3V" id="TeI-f1-KlA"/>
</connections>
</textField>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Use this as the answer for each of the security questions on this site." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EUe-A5-H8h">
<rect key="frame" x="8" y="99" width="359" height="13.5"/>
<fontDescription key="fontDescription" name="Exo2.0-Thin" family="Exo 2.0" pointSize="11"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="EUe-A5-H8h" secondAttribute="trailing" constant="8" id="076-4e-NlP"/>
<constraint firstItem="GfC-j4-Qx7" firstAttribute="top" secondItem="Tal-1I-HQw" secondAttribute="bottom" constant="20" id="A4A-ds-Uc4"/>
<constraint firstAttribute="bottom" secondItem="EUe-A5-H8h" secondAttribute="bottom" constant="20" symbolic="YES" id="AKM-6g-fhT"/>
<constraint firstItem="GfC-j4-Qx7" firstAttribute="leading" secondItem="URA-cl-MJP" secondAttribute="leading" constant="8" id="JHy-eG-ckd"/>
<constraint firstAttribute="trailing" secondItem="GfC-j4-Qx7" secondAttribute="trailing" constant="8" id="NAP-0S-Vda"/>
<constraint firstItem="Tal-1I-HQw" firstAttribute="leading" secondItem="URA-cl-MJP" secondAttribute="leading" constant="8" id="Udh-0D-wR7"/>
<constraint firstItem="EUe-A5-H8h" firstAttribute="leading" secondItem="URA-cl-MJP" secondAttribute="leading" constant="8" id="pEG-lI-KQN"/>
<constraint firstItem="Tal-1I-HQw" firstAttribute="top" secondItem="URA-cl-MJP" secondAttribute="top" constant="8" id="x6h-mG-HZ4"/>
<constraint firstItem="EUe-A5-H8h" firstAttribute="top" secondItem="GfC-j4-Qx7" secondAttribute="bottom" constant="8" symbolic="YES" id="xLP-uA-9z2"/>
</constraints>
</tableViewCellContentView>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<connections>
<outlet property="answerField" destination="GfC-j4-Qx7" id="egp-cZ-E1x"/>
<outlet property="titleLabel" destination="Tal-1I-HQw" id="9s2-2n-cB4"/>
</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="0.0" width="320" height="97"/>
<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="287" height="96"/>
<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="326" height="27.5"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="12"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="bottom" secondItem="AAV-yg-dfK" secondAttribute="bottom" constant="8" id="LJV-LG-n0h"/>
<constraint firstAttribute="trailing" secondItem="AAV-yg-dfK" secondAttribute="trailing" constant="8" id="NBf-3q-dHH"/>
<constraint firstItem="AAV-yg-dfK" firstAttribute="leading" secondItem="BTm-Lm-V9p" secondAttribute="leading" constant="8" id="WpS-gx-b0s"/>
<constraint firstItem="AAV-yg-dfK" firstAttribute="top" secondItem="BTm-Lm-V9p" secondAttribute="top" constant="8" id="t5X-Jg-8Ai"/>
</constraints>
</tableViewCellContentView>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</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="0.0" width="320" height="97"/>
<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="287" height="96"/>
<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="320" height="27.5"/>
<fontDescription key="fontDescription" name="Exo2.0-Bold" family="Exo 2.0" pointSize="12"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="een-0g-CMy" firstAttribute="top" secondItem="4wX-xO-9QU" secondAttribute="top" constant="8" id="9ZQ-yN-0jZ"/>
<constraint firstAttribute="bottom" secondItem="een-0g-CMy" secondAttribute="bottom" constant="8" id="JTE-x8-fAk"/>
<constraint firstAttribute="trailing" secondItem="een-0g-CMy" secondAttribute="trailing" constant="8" id="LMQ-CT-XDx"/>
<constraint firstItem="een-0g-CMy" firstAttribute="leading" secondItem="4wX-xO-9QU" secondAttribute="leading" constant="8" id="w3c-zJ-Mbm"/>
</constraints>
</tableViewCellContentView>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
</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="0.0" width="320" height="97"/>
<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="287" height="96"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="mother" textAlignment="center" minimumFontSize="14" clearButtonMode="unlessEditing" translatesAutoresizingMaskIntoConstraints="NO" id="T2F-PD-Nw8" userLabel="Question Field">
<rect key="frame" x="8" y="19" width="359" height="30"/>
<color key="backgroundColor" red="0.37254901959999998" green="0.3921568627" blue="0.42745098040000001" alpha="0.5" colorSpace="calibratedRGB"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<fontDescription key="fontDescription" name="Exo2.0-Regular" family="Exo 2.0" pointSize="28"/>
<textInputTraits key="textInputTraits" keyboardType="namePhonePad" keyboardAppearance="alert" returnKeyType="done"/>
<connections>
<outlet property="delegate" destination="S8q-YF-Kt9" id="TtZ-rC-HTB"/>
</connections>
</textField>
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="pifm gup balvabi yiz" textAlignment="center" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="3xA-ez-efa" userLabel="Answer Field">
<rect key="frame" x="20" y="90.5" width="335" height="31"/>
<color key="textColor" red="0.40000000600000002" green="0.80000001190000003" blue="1" alpha="1" colorSpace="calibratedRGB"/>
<fontDescription key="fontDescription" name="SourceCodePro-Black" family="Source Code Pro" pointSize="24"/>
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="alphabet" keyboardAppearance="alert" returnKeyType="next"/>
<connections>
<action selector="textFieldDidChange:" destination="W2g-yv-V3V" eventType="editingChanged" id="nFl-TF-gF7"/>
<outlet property="delegate" destination="W2g-yv-V3V" id="U4z-82-k15"/>
</connections>
</textField>
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Enter the single most significant word in the question above." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qqg-Ny-7Po">
<rect key="frame" x="8" y="57" width="359" height="13.5"/>
<fontDescription key="fontDescription" name="Exo2.0-Thin" family="Exo 2.0" pointSize="11"/>
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstItem="3xA-ez-efa" firstAttribute="leading" secondItem="X5d-5g-uJa" secondAttribute="leading" constant="20" symbolic="YES" id="01X-Q1-hbE"/>
<constraint firstAttribute="bottom" secondItem="3xA-ez-efa" secondAttribute="bottom" constant="8" id="7lO-8k-3xJ"/>
<constraint firstItem="3xA-ez-efa" firstAttribute="top" secondItem="Qqg-Ny-7Po" secondAttribute="bottom" constant="20" id="MnT-on-L2d"/>
<constraint firstItem="Qqg-Ny-7Po" firstAttribute="top" secondItem="T2F-PD-Nw8" secondAttribute="bottom" constant="8" id="Xla-SS-lW7"/>
<constraint firstItem="T2F-PD-Nw8" firstAttribute="leading" secondItem="X5d-5g-uJa" secondAttribute="leading" constant="8" id="YAl-Zz-fp3"/>
<constraint firstAttribute="trailing" secondItem="3xA-ez-efa" secondAttribute="trailing" constant="20" symbolic="YES" id="YSK-xt-QtB"/>
<constraint firstAttribute="trailing" secondItem="Qqg-Ny-7Po" secondAttribute="trailing" constant="8" id="ZKi-Kb-iF2"/>
<constraint firstItem="Qqg-Ny-7Po" firstAttribute="leading" secondItem="X5d-5g-uJa" secondAttribute="leading" constant="8" id="o3h-oy-hyw"/>
<constraint firstAttribute="trailing" secondItem="T2F-PD-Nw8" secondAttribute="trailing" constant="8" id="tCL-PD-pms"/>
</constraints>
</tableViewCellContentView>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
<connections>
<outlet property="answerField" destination="3xA-ez-efa" id="xob-uu-1u7"/>
<outlet property="questionField" destination="T2F-PD-Nw8" id="Ekp-t8-Hli"/>
</connections>
</tableViewCell>
</prototypes>
<sections/>
<connections>
<outlet property="dataSource" destination="koB-V2-GYf" id="fwt-DL-nza"/>
<outlet property="delegate" destination="koB-V2-GYf" id="dJF-bd-2ux"/>
</connections>
</tableView>
<tabBarItem key="tabBarItem" title="Preferences" image="icon_person.png" id="GwN-2X-LQ6"/>
<nil key="simulatedStatusBarMetrics"/>
<nil key="simulatedBottomBarMetrics"/>
<connections>
<outlet property="showHelpCell" destination="5MB-qb-oPk" id="7Db-6P-bBY"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="kXh-18-fq5" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1408.5" y="2175.5"/>
</scene> </scene>
</scenes> </scenes>
<resources> <resources>
@ -2807,6 +2991,7 @@ See </string>
<image name="icon_up.png" width="32" height="32"/> <image name="icon_up.png" width="32" height="32"/>
<image name="identity.png" width="82" height="80"/> <image name="identity.png" width="82" height="80"/>
<image name="image-0.png" width="320" height="568"/> <image name="image-0.png" width="320" height="568"/>
<image name="thumb_advanced_export.png" width="198" height="198"/>
<image name="thumb_generated_login.png" width="198" height="198"/> <image name="thumb_generated_login.png" width="198" height="198"/>
<image name="tip_basic_black.png" width="210" height="60"/> <image name="tip_basic_black.png" width="210" height="60"/>
<image name="ui_spinner.png" width="75" height="75"/> <image name="ui_spinner.png" width="75" height="75"/>

View File

@ -2,7 +2,7 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>MPElementGeneratedEntity</key> <key>MPSiteGeneratedEntity</key>
<dict> <dict>
<key>Login Name</key> <key>Login Name</key>
<array> <array>