[
  {
    "path": "LXDAppMonitor/AppDelegate.h",
    "content": "//\n//  AppDelegate.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/3/29.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface AppDelegate : UIResponder <UIApplicationDelegate>\n\n@property (strong, nonatomic) UIWindow *window;\n\n\n@end\n\n"
  },
  {
    "path": "LXDAppMonitor/AppDelegate.m",
    "content": "//\n//  AppDelegate.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/3/29.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"AppDelegate.h\"\n\n@interface AppDelegate ()\n\n@end\n\n@implementation AppDelegate\n\n\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {\n    // Override point for customization after application launch.\n    return YES;\n}\n\n\n- (void)applicationWillResignActive:(UIApplication *)application {\n    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n}\n\n\n- (void)applicationDidEnterBackground:(UIApplication *)application {\n    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n}\n\n\n- (void)applicationWillEnterForeground:(UIApplication *)application {\n    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n}\n\n\n- (void)applicationDidBecomeActive:(UIApplication *)application {\n    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n}\n\n\n- (void)applicationWillTerminate:(UIApplication *)application {\n    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"29x29\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"40x40\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"60x60\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "LXDAppMonitor/Base.lproj/LaunchScreen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"11134\" systemVersion=\"15F34\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"11106\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <layoutGuides>\n                        <viewControllerLayoutGuide type=\"top\" id=\"Llm-lL-Icb\"/>\n                        <viewControllerLayoutGuide type=\"bottom\" id=\"xb3-aO-Qok\"/>\n                    </layoutGuides>\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "LXDAppMonitor/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"12118\" systemVersion=\"16E195\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" colorMatched=\"YES\" initialViewController=\"26j-vO-rMj\">\n    <device id=\"retina4_7\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"12086\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"tne-QT-ifu\">\n            <objects>\n                <viewController id=\"BYZ-38-t0r\" customClass=\"ViewController\" sceneMemberID=\"viewController\">\n                    <layoutGuides>\n                        <viewControllerLayoutGuide type=\"top\" id=\"y3c-jy-aDJ\"/>\n                        <viewControllerLayoutGuide type=\"bottom\" id=\"wfy-db-euE\"/>\n                    </layoutGuides>\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"8bC-Xf-vdC\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <tableView clipsSubviews=\"YES\" contentMode=\"scaleToFill\" alwaysBounceVertical=\"YES\" dataMode=\"prototypes\" style=\"plain\" separatorStyle=\"default\" rowHeight=\"44\" sectionHeaderHeight=\"28\" sectionFooterHeight=\"28\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"yKT-sX-L3a\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"64\" width=\"375\" height=\"603\"/>\n                                <color key=\"backgroundColor\" white=\"1\" alpha=\"1\" colorSpace=\"calibratedWhite\"/>\n                                <connections>\n                                    <outlet property=\"dataSource\" destination=\"BYZ-38-t0r\" id=\"xXJ-aP-7Fm\"/>\n                                    <outlet property=\"delegate\" destination=\"BYZ-38-t0r\" id=\"SLp-6w-g9Q\"/>\n                                </connections>\n                            </tableView>\n                        </subviews>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <constraints>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"yKT-sX-L3a\" secondAttribute=\"trailing\" id=\"9oD-re-m91\"/>\n                            <constraint firstItem=\"yKT-sX-L3a\" firstAttribute=\"top\" secondItem=\"y3c-jy-aDJ\" secondAttribute=\"bottom\" id=\"HfI-kO-cRn\"/>\n                            <constraint firstItem=\"wfy-db-euE\" firstAttribute=\"top\" secondItem=\"yKT-sX-L3a\" secondAttribute=\"bottom\" id=\"Wxh-oR-u4d\"/>\n                            <constraint firstItem=\"yKT-sX-L3a\" firstAttribute=\"leading\" secondItem=\"8bC-Xf-vdC\" secondAttribute=\"leading\" id=\"WyI-7q-nc4\"/>\n                        </constraints>\n                    </view>\n                    <navigationItem key=\"navigationItem\" id=\"2lN-jX-OIq\"/>\n                    <connections>\n                        <outlet property=\"tableView\" destination=\"yKT-sX-L3a\" id=\"bzE-GV-3ng\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"dkx-z0-nzr\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"972\" y=\"37.331334332833585\"/>\n        </scene>\n        <!--Navigation Controller-->\n        <scene sceneID=\"GKZ-Xf-T5R\">\n            <objects>\n                <navigationController automaticallyAdjustsScrollViewInsets=\"NO\" id=\"26j-vO-rMj\" sceneMemberID=\"viewController\">\n                    <toolbarItems/>\n                    <navigationBar key=\"navigationBar\" contentMode=\"scaleToFill\" id=\"FNU-Hg-DSS\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"44\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                    </navigationBar>\n                    <nil name=\"viewControllers\"/>\n                    <connections>\n                        <segue destination=\"BYZ-38-t0r\" kind=\"relationship\" relationship=\"rootViewController\" id=\"orZ-qB-aaB\"/>\n                    </connections>\n                </navigationController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"JPT-jC-UbT\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"216.80000000000001\" y=\"-645.42728635682158\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "LXDAppMonitor/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>NSAppTransportSecurity</key>\n\t<dict>\n\t\t<key>NSAllowsArbitraryLoads</key>\n\t\t<true/>\n\t</dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Crash/LXDCrashLogger.h",
    "content": "//\n//  LXDCrashLogger.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/27.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n/*!\n *  @brief  崩溃日志\n */\n@interface LXDCrashLogger : NSObject\n\n@property (nonatomic, readonly) NSString * name;\n@property (nonatomic, readonly) NSString * reason;\n@property (nonatomic, readonly) NSString * stackInfo;\n@property (nonatomic, readonly) NSString * crashTime;\n@property (nonatomic, readonly) NSString * topViewController;\n@property (nonatomic, readonly) NSString * applicationVersion;\n\n+ (instancetype)crashLoggerWithName: (NSString *)name\n                             reason: (NSString *)reason\n                          stackInfo: (NSString *)stackInfo\n                          crashTime: (NSDate *)crashTime\n                  topViewController: (NSString *)topViewController\n                 applicationVersion: (NSString *)applicationVersion;\n\n- (NSString *)loggerDescription;\n\n@end\n\n\n/*!\n *  @brief  日志服务管理\n */\n@interface LXDCrashLoggerServer : NSObject\n\n+ (instancetype)sharedServer;\n- (void)insertLogger: (LXDCrashLogger *)logger;\n- (void)fetchLastLogger: (void(^)(LXDCrashLogger * logger))fetchHandle;\n- (void)fetchLoggers: (void(^)(NSArray<LXDCrashLogger *> * loggers))fetchHandle;\n\n@end\n\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Crash/LXDCrashLogger.m",
    "content": "//\n//  LXDCrashLogger.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/27.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDCrashLogger.h\"\n#import \"LXDDispatchAsync.h\"\n\n\n#if __has_include(<sqlite3.h>)\n#import <sqlite3.h>\n#else\n#import \"sqlite3.h\"\n#endif\n\n\nstatic const NSUInteger kMaxLoggerNumber = 20;\nstatic NSString * const kLoggerDatabaseFileName = @\"crash_logger.sqlite\";\n\n\n@interface LXDCrashLogger ()\n\n@property (nonatomic, copy) NSString * name;\n@property (nonatomic, copy) NSString * reason;\n@property (nonatomic, copy) NSString * stackInfo;\n@property (nonatomic, copy) NSString * crashTime;\n@property (nonatomic, copy) NSString * topViewController;\n@property (nonatomic, copy) NSString * applicationVersion;\n\n@end\n\n\n@implementation LXDCrashLogger\n\n\nNSString * __lxd_convert_time(NSDate * date) {\n    static NSDateFormatter * lxd_date_formatter;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        lxd_date_formatter = [NSDateFormatter new];\n        lxd_date_formatter.dateFormat = @\"yyyy-HH-dd HH:mm:ss\";\n    });\n    return [lxd_date_formatter stringFromDate: date];\n}\n\n+ (instancetype)crashLoggerWithName: (NSString *)name\n                             reason: (NSString *)reason\n                          stackInfo: (NSString *)stackInfo\n                          crashTime: (NSDate *)crashTime\n                  topViewController: (NSString *)topViewController\n                 applicationVersion: (NSString *)applicationVersion {\n    LXDCrashLogger * crashLogger = [LXDCrashLogger new];\n    crashLogger.name = name ?: @\"\";\n    crashLogger.reason = reason ?: @\"\";\n    crashLogger.stackInfo = stackInfo ?: @\"\";\n    crashLogger.topViewController = topViewController ?: @\"\";\n    crashLogger.applicationVersion = applicationVersion ?: @\"\";\n    crashLogger.crashTime = __lxd_convert_time(crashTime);\n    return crashLogger;\n}\n\n- (NSString *)loggerDescription {\n    return [NSString stringWithFormat: @\"Error: %@\\nReson: %@\\n%@\\nTop viewcontroller: %@\\nCrash time: %@\\n\\nCall Stack: \\n%@\", _name, _reason, _applicationVersion, _topViewController, _crashTime, _stackInfo];\n}\n\n\n@end\n\n\n\n\n@interface LXDCrashLoggerServer ()\n\n@property (nonatomic, unsafe_unretained) sqlite3 * database;\n@property (nonatomic, unsafe_unretained) CFMutableDictionaryRef stmtCache;\n\n@end\n\n\n@implementation LXDCrashLoggerServer\n\n\n#pragma mark - Singleton\n+ (instancetype)sharedServer {\n    static LXDCrashLoggerServer * sharedServer;\n    static dispatch_once_t once;\n    dispatch_once(&once, ^{\n        sharedServer = [[super allocWithZone: NSDefaultMallocZone()] init];\n    });\n    return sharedServer;\n}\n\n+ (instancetype)allocWithZone: (struct _NSZone *)zone {\n    return [self sharedServer];\n}\n\n- (instancetype)init {\n    if (self = [super init]) {\n        if ([self _dbOpen]) {\n            [self _dbInitialize];\n            CFDictionaryKeyCallBacks keyCallbacks = kCFCopyStringDictionaryKeyCallBacks;\n            CFDictionaryValueCallBacks valueCallbacks = { 0 };\n            self.stmtCache = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &keyCallbacks, &valueCallbacks);\n        }\n    }\n    return self;\n}\n\n- (id)copy {\n    return [[self class] sharedServer];\n}\n\n- (void)dealloc {\n    if (!_database) {\n        sqlite3_close(_database);\n        CFRelease(_stmtCache);\n        _stmtCache = NULL;\n        _database = NULL;\n    }\n}\n\n\n#pragma mark - Public\n- (void)insertLogger: (LXDCrashLogger *)logger {\n    [self _insertCrashLogger: logger];\n}\n\n- (void)fetchLastLogger: (void(^)(LXDCrashLogger * logger))fetchHandle {\n    [self _syncExecute: ^{\n        [self fetchLastLogger: fetchHandle];\n    }];\n}\n\n- (void)fetchLoggers: (void(^)(NSArray<LXDCrashLogger *> *))fetchHandle {\n    [self _syncExecute: ^{\n        [self _fetchCrashLoggers: fetchHandle];\n    }];\n}\n\n\n#pragma mark - Private\n- (NSString *)_crashLoggerFilePath {\n    return [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent: kLoggerDatabaseFileName];\n}\n\n- (void)_syncExecute: (dispatch_block_t)block {\n    assert(block != nil);\n    if ([NSThread isMainThread]) {\n        LXDDispatchQueueAsyncBlockInUtility(block);\n    } else {\n        block();\n    }\n}\n\n- (void)_insertCrashLogger: (LXDCrashLogger *)crashLogger {\n    NSString * sql = @\"insert or replace into crash_logger (name, reason, stack_info, crash_time, top_view_controller, application_version) values (?1, ?2, ?3, ?4, ?5, ?6);\";\n    sqlite3_stmt * stmt = [self _dbPrepareStmt: sql];\n    if (!stmt) { return; }\n    \n    sqlite3_bind_text(stmt, 1, crashLogger.name.UTF8String, -1, NULL);\n    sqlite3_bind_text(stmt, 2, crashLogger.reason.UTF8String, -1, NULL);\n    sqlite3_bind_text(stmt, 3, crashLogger.stackInfo.UTF8String, -1, NULL);\n    sqlite3_bind_text(stmt, 4, crashLogger.crashTime.UTF8String, -1, NULL);\n    sqlite3_bind_text(stmt, 5, crashLogger.topViewController.UTF8String, -1, NULL);\n    sqlite3_bind_text(stmt, 6, crashLogger.applicationVersion.UTF8String, -1, NULL);\n    sqlite3_step(stmt);\n}\n\n- (void)_cleanExtraLoggers {\n    NSString * sql = @\"delete from crash_logger order by crash_time desc limit (select count(crash_time) from crash_logger) offset 20\";\n    sqlite3_stmt * stmt = [self _dbPrepareStmt: sql];\n    if (!stmt) { return; }\n    sqlite3_step(stmt);\n}\n\n- (void)_fetchLastLogger: (void(^)(LXDCrashLogger *))fetchHandle {\n    assert(fetchHandle != nil);\n    sqlite3_stmt * stmt = [self _fetchLoggerWithCount: 1];\n    if (!stmt) { return; }\n    \n    if (sqlite3_step(stmt) == SQLITE_ROW) {\n        dispatch_async(dispatch_get_main_queue(), ^{\n            fetchHandle([self _dbGetLoggerFromStmt: stmt]);\n        });\n    }\n}\n\n- (void)_fetchCrashLoggers: (void(^)(NSArray<LXDCrashLogger *> *))fetchHandle {\n    assert(fetchHandle != nil);\n    sqlite3_stmt * stmt = [self _fetchLoggerWithCount: 20];\n    if (!stmt) { return; }\n    \n    NSMutableArray * loggers = [NSMutableArray array];\n    while (sqlite3_step(stmt) == SQLITE_ROW) {\n        [loggers addObject: [self _dbGetLoggerFromStmt: stmt]];\n    }\n    dispatch_async(dispatch_get_main_queue(), ^{\n        fetchHandle(loggers);\n    });\n    if (loggers.count == 20) {\n        [self _cleanExtraLoggers];\n    }\n}\n\n- (sqlite3_stmt *)_fetchLoggerWithCount: (NSUInteger)count {\n    NSString * sql = @\"select * from crash_logger order by crash_time desc limit 0,?1;\";\n    sqlite3_stmt * stmt = [self _dbPrepareStmt: sql];\n    if (!stmt) { return NULL; }\n    sqlite3_bind_int64(stmt, 1, count);\n    return stmt;\n}\n\n- (LXDCrashLogger *)_dbGetLoggerFromStmt: (sqlite3_stmt *)stmt {\n    int idx = 0;\n    char * name = (char *)sqlite3_column_text(stmt, idx++);\n    char * reason = (char *)sqlite3_column_text(stmt, idx++);\n    char * stack_info = (char *)sqlite3_column_text(stmt, idx++);\n    char * crash_time = (char *)sqlite3_column_text(stmt, idx++);\n    char * top_view_controller = (char *)sqlite3_column_text(stmt, idx++);\n    char * application_version = (char *)sqlite3_column_text(stmt, idx++);\n    \n    LXDCrashLogger * logger = [LXDCrashLogger new];\n    logger.name = [NSString stringWithUTF8String: name];\n    logger.reason = [NSString stringWithUTF8String: reason];\n    logger.stackInfo = [NSString stringWithUTF8String: stack_info];\n    logger.crashTime = [NSString stringWithUTF8String: crash_time];\n    logger.applicationVersion = [NSString stringWithUTF8String: application_version];\n    logger.topViewController = [NSString stringWithUTF8String: top_view_controller];\n    return logger;\n}\n\n\n#pragma mark - Sqlite\n- (BOOL)_dbOpen {\n    if (_database) { return YES; }\n    int result = sqlite3_open([self _crashLoggerFilePath].UTF8String, &_database);\n    if (result == SQLITE_OK) {\n        return YES;\n    } else {\n        _database = NULL;\n        return NO;\n    }\n}\n\n- (BOOL)_dbInitialize {\n    NSString * sql = @\"pragma journal_mode = wal; pragma synchronous = normal; create table if not exists crash_logger (name text, reason text, stack_info text, crash_time text primary key, top_view_controller text, application_version text);\";\n    return [self _dbExecute: sql];\n}\n\n- (BOOL)_dbExecute: (NSString *)sql {\n    if (sql.length == 0) { return NO; }\n    if (![self _dbCheck]) { return NO; }\n    \n    char * error = NULL;\n    int result = sqlite3_exec(_database, sql.UTF8String, NULL, NULL, &error);\n    if (error) {\n        sqlite3_free(error);\n    }\n    return (result == SQLITE_OK);\n}\n\n- (BOOL)_dbCheck {\n    if (!_database) {\n        return ([self _dbOpen] && [self _dbInitialize]);\n    }\n    return YES;\n}\n\n- (sqlite3_stmt *)_dbPrepareStmt: (NSString *)sql {\n    if (![self _dbCheck] || sql.length == 0 || !_stmtCache) { return NULL; }\n    sqlite3_stmt * stmt = (sqlite3_stmt *)CFDictionaryGetValue(_stmtCache, (__bridge const void *)sql);\n    if (!stmt) {\n        int result = sqlite3_prepare_v2(_database, sql.UTF8String, -1, &stmt, NULL);\n        if (result != SQLITE_OK) {\n            return NULL;\n        }\n        CFDictionarySetValue(_stmtCache, (__bridge const void *)sql, stmt);\n    } else {\n        sqlite3_reset(stmt);\n    }\n    return stmt;\n}\n\n\n@end\n\n\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Crash/LXDCrashMonitor.h",
    "content": "//\n//  LXDCrashMonitor.h\n//  LXDAppFluencyMonitor\n//\n//  Created by linxinda on 2017/3/26.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n/*!\n *  @brief  崩溃监控\n */\n@interface LXDCrashMonitor : UIView\n\n+ (void)startMonitoring;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Crash/LXDCrashMonitor.m",
    "content": "//\n//  LXDCrashMonitor.m\n//  LXDAppFluencyMonitor\n//\n//  Created by linxinda on 2017/3/26.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDCrashMonitor.h\"\n#import \"LXDCrashLogger.h\"\n#import \"LXDBacktraceLogger.h\"\n#import \"UIApplication+LXDTool.h\"\n\n\nvoid (*other_exception_caught_handler)(NSException * exception) = NULL;\n\n\n@implementation LXDCrashMonitor\n\n\nstatic void __lxd_exception_caught(NSException * exception) {\n    NSDictionary * infoDict = [[NSBundle mainBundle] infoDictionary];\n    NSString * appInfo = [NSString stringWithFormat: @\"Device: %@\\nOS Version: %@\\nOS System: %@\", [UIDevice currentDevice].model, infoDict[@\"CFBundleShortVersionString\"], [[UIDevice currentDevice].systemName stringByAppendingString: [UIDevice currentDevice].systemVersion]];\n    \n    LXDCrashLogger * crashLogger = [LXDCrashLogger crashLoggerWithName: exception.name\n                                                                reason: exception.reason\n                                                             stackInfo: [LXDBacktraceLogger lxd_backtraceOfCurrentThread] crashTime: [NSDate date]\n                                                     topViewController: NSStringFromClass([[[UIApplication sharedApplication] findTopViewController] class])\n                                                    applicationVersion: appInfo];\n    [[LXDCrashLoggerServer sharedServer] insertLogger: crashLogger];\n    if (other_exception_caught_handler != NULL) {\n        (*other_exception_caught_handler)(exception);\n    }\n}\n\nCF_INLINE NSString * __signal_name(int signal) {\n    switch (signal) {\n            /// 非法指令\n        case SIGILL:\n            return @\"SIGILL\";\n            /// 计算错误\n        case SIGFPE:\n            return @\"SIGFPE\";\n            /// 总线错误\n        case SIGBUS:\n            return @\"SIGBUS\";\n            /// 无进程接手数据\n        case SIGPIPE:\n            return @\"SIGPIPE\";\n            /// 无效地址\n        case SIGSEGV:\n            return @\"SIGSEGV\";\n            /// abort信号\n        case SIGABRT:\n            return @\"SIGABRT\";\n        default:\n            return @\"Unknown\";\n    }\n}\n\nCF_INLINE NSString * __signal_reason(int signal) {\n    switch (signal) {\n            /// 非法指令\n        case SIGILL:\n            return @\"Invalid Command\";\n            /// 计算错误\n        case SIGFPE:\n            return @\"Math Type Error\";\n            /// 总线错误\n        case SIGBUS:\n            return @\"Bus Error\";\n            /// 无进程接手数据\n        case SIGPIPE:\n            return @\"No Data Receiver\";\n            /// 无效地址\n        case SIGSEGV:\n            return @\"Invalid Address\";\n            /// abort信号\n        case SIGABRT:\n            return @\"Abort Signal\";\n        default:\n            return @\"Unknown\";\n    }\n}\n\nstatic void __lxd_signal_handler(int signal) {\n    __lxd_exception_caught([NSException exceptionWithName: __signal_name(signal) reason: __signal_reason(signal) userInfo: nil]);\n    [LXDCrashMonitor _killApp];\n}\n\n\n#pragma mark - Public\n+ (void)startMonitoring {\n    other_exception_caught_handler = NSGetUncaughtExceptionHandler();\n    NSSetUncaughtExceptionHandler(__lxd_exception_caught);\n    signal(SIGILL, __lxd_signal_handler);\n    signal(SIGFPE, __lxd_signal_handler);\n    signal(SIGBUS, __lxd_signal_handler);\n    signal(SIGPIPE, __lxd_signal_handler);\n    signal(SIGSEGV, __lxd_signal_handler);\n    signal(SIGABRT, __lxd_signal_handler);\n}\n\n\n#pragma mark - Private\n+ (void)_killApp {\n    NSSetUncaughtExceptionHandler(NULL);\n    signal(SIGILL, SIG_DFL);\n    signal(SIGFPE, SIG_DFL);\n    signal(SIGBUS, SIG_DFL);\n    signal(SIGPIPE, SIG_DFL);\n    signal(SIGSEGV, SIG_DFL);\n    signal(SIGABRT, SIG_DFL);\n    kill(getpid(), SIGKILL);\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/FPS/LXDFPSDisplayer.h",
    "content": "//\n//  LXDFPSDisplayer.h\n//  LXDAppFluencyMonitor\n//\n//  Created by linxinda on 2017/3/25.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n/*!\n *  @brief  FPS显示器\n */\n@interface LXDFPSDisplayer : UIView\n\n- (void)updateFPS: (int)fps;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/FPS/LXDFPSDisplayer.m",
    "content": "//\n//  LXDFPSDisplayer.m\n//  LXDAppFluencyMonitor\n//\n//  Created by linxinda on 2017/3/25.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDFPSDisplayer.h\"\n#import \"LXDMonitorUI.h\"\n#import \"LXDDispatchAsync.h\"\n\n\n#define LXD_FPS_DISPLAYER_SIZE CGSizeMake(54, 20)\n\n\n@interface LXDFPSDisplayer ()\n\n@property (nonatomic, strong) LXDAsyncLabel * fpsDisplayer;\n\n@end\n\n\n@implementation LXDFPSDisplayer\n\n\n- (instancetype)init {\n    if (self = [super initWithFrame: CGRectMake((CGRectGetWidth([UIScreen mainScreen].bounds) - LXD_FPS_DISPLAYER_SIZE.width) / 2, 30, LXD_FPS_DISPLAYER_SIZE.width, LXD_FPS_DISPLAYER_SIZE.height)]) {\n        CAShapeLayer * bgLayer = [CAShapeLayer layer];\n        bgLayer.fillColor = [UIColor colorWithWhite: 0 alpha: 0.7].CGColor;\n        bgLayer.path = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(0, 0, LXD_FPS_DISPLAYER_SIZE.width, LXD_FPS_DISPLAYER_SIZE.height) cornerRadius: 5].CGPath;\n        [self.layer addSublayer: bgLayer];\n        \n        self.fpsDisplayer = [[LXDAsyncLabel alloc] initWithFrame: self.bounds];\n        self.fpsDisplayer.textColor = [UIColor whiteColor];\n        self.fpsDisplayer.textAlignment = NSTextAlignmentCenter;\n        self.fpsDisplayer.font = [UIFont fontWithName: @\"Menlo\" size: 14];\n        [self updateFPS: 60];\n        [self addSubview: self.fpsDisplayer];\n    }\n    return self;\n}\n\n- (void)updateFPS: (int)fps {\n    LXDDispatchQueueAsyncBlockInDefault(^{\n        NSMutableAttributedString * attributed = [[NSMutableAttributedString alloc] initWithString: [NSString stringWithFormat: @\"%d\", fps] attributes: @{ NSForegroundColorAttributeName: [UIColor colorWithHue: 0.27 * (fps / 60.0 - 0.2) saturation: 1 brightness: 0.9 alpha: 1], NSFontAttributeName: _fpsDisplayer.font }];\n        [attributed appendAttributedString: [[NSAttributedString alloc] initWithString: @\"FPS\" attributes: @{ NSFontAttributeName: _fpsDisplayer.font, NSForegroundColorAttributeName: [UIColor whiteColor] }]];\n        self.fpsDisplayer.attributedText = attributed;\n    });\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/FPS/LXDFPSMonitor.h",
    "content": "//\n//  LXDFPSMonitor.h\n//  LXDAppFluencyMonitor\n//\n//  Created by linxinda on 2017/3/24.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n\n#define FPS_MONITOR [LXDFPSMonitor sharedMonitor]\n/*!\n *  @brief  监听FPS\n */\n@interface LXDFPSMonitor : NSObject\n\n+ (instancetype)sharedMonitor;\n\n- (void)startMonitoring;\n- (void)stopMonitoring;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/FPS/LXDFPSMonitor.m",
    "content": "//\n//  LXDFPSMonitor.m\n//  LXDAppFluencyMonitor\n//\n//  Created by linxinda on 2017/3/24.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDFPSMonitor.h\"\n#import \"LXDMonitorUI.h\"\n#import \"LXDWeakProxy.h\"\n#import \"LXDFPSDisplayer.h\"\n#import \"LXDBacktraceLogger.h\"\n\n\n@interface LXDFPSMonitor ()\n\n@property (nonatomic, assign) NSUInteger count;\n@property (nonatomic, assign) BOOL isMonitoring;\n@property (nonatomic, assign) NSTimeInterval lastTime;\n@property (nonatomic, assign) LXDFPSDisplayer * displayer;\n@property (nonatomic, strong) CADisplayLink * displayLink;\n\n@end\n\n\n\n@implementation LXDFPSMonitor\n\n\n#pragma mark - Singleton override\n+ (instancetype)sharedMonitor {\n    static LXDFPSMonitor * sharedMonitor;\n    static dispatch_once_t once;\n    dispatch_once(&once, ^{\n        sharedMonitor = [[super allocWithZone: NSDefaultMallocZone()] init];\n    });\n    return sharedMonitor;\n}\n\n+ (instancetype)allocWithZone: (struct _NSZone *)zone {\n    return [self sharedMonitor];\n}\n\n- (void)dealloc {\n    [self stopMonitoring];\n}\n\n\n#pragma mark - Public\n- (void)startMonitoring {\n    if (_isMonitoring) { return; }\n    _isMonitoring = YES;\n    [self.displayer removeFromSuperview];\n    LXDFPSDisplayer * displayer = [[LXDFPSDisplayer alloc] init];\n    self.displayer = displayer;\n    [[LXDTopWindow topWindow] addSubview: self.displayer];\n    \n    self.displayLink = [CADisplayLink displayLinkWithTarget: [LXDWeakProxy proxyWithConsignor: self] selector: @selector(monitor:)];\n    [self.displayLink addToRunLoop: [NSRunLoop mainRunLoop] forMode: NSRunLoopCommonModes];\n    self.lastTime = self.displayLink.timestamp;\n    if ([self.displayLink respondsToSelector: @selector(setPreferredFramesPerSecond:)]) {\n        self.displayLink.preferredFramesPerSecond = 60;\n    } else {\n        self.displayLink.frameInterval = 1;\n    }\n}\n\n- (void)stopMonitoring {\n    if (!_isMonitoring) { return; }\n    _isMonitoring = NO;\n    [self.displayer removeFromSuperview];\n    [self.displayLink invalidate];\n    self.displayLink = nil;\n    self.displayer = nil;\n}\n\n\n#pragma mark - DisplayLink\n- (void)monitor: (CADisplayLink *)link {\n    _count++;\n    NSTimeInterval delta = link.timestamp - _lastTime;\n    if (delta < 1) { return; }\n    _lastTime = link.timestamp;\n    \n    double fps = _count / delta;\n    _count = 0;\n    [self.displayer updateFPS: (int)round(fps)];\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/FPS/LXDWeakProxy.h",
    "content": "//\n//  LXDWeakProxy.h\n//  LXDAppFluencyMonitor\n//\n//  Created by linxinda on 2017/3/24.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n/*!\n *  @brief  弱引用代理对象\n */\n@interface LXDWeakProxy : NSObject\n\n+ (instancetype)proxyWithConsignor: (id)consignor;\n- (instancetype)initWithConsignor: (id)consignor;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/FPS/LXDWeakProxy.m",
    "content": "//\n//  LXDWeakProxy.m\n//  LXDAppFluencyMonitor\n//\n//  Created by linxinda on 2017/3/24.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDWeakProxy.h\"\n\n\n@interface LXDWeakProxy ()\n\n@property (nonatomic, weak) id consignor;\n\n@end\n\n\n@implementation LXDWeakProxy\n\n\n#pragma mark - Public\n+ (instancetype)proxyWithConsignor: (id)consignor {\n    return [[self alloc] initWithConsignor: consignor];\n}\n\n- (instancetype)initWithConsignor: (id)consignor {\n    if (self = [super init]) {\n        self.consignor = consignor;\n    }\n    return self;\n}\n\n\n#pragma mark - method transmit\n- (id)forwardingTargetForSelector: (SEL)aSelector {\n    return _consignor;\n}\n\n- (void)forwardInvocation: (NSInvocation *)anInvocation {\n    void * null = NULL;\n    [anInvocation setReturnValue: &null];\n}\n\n- (NSMethodSignature *)methodSignatureForSelector: (SEL)aSelector {\n    return [_consignor methodSignatureForSelector: aSelector];\n}\n\n\n#pragma mark - judge\n- (BOOL)isProxy {\n    return YES;\n}\n\n- (Class)class {\n    return [_consignor class];\n}\n\n- (Class)superclass {\n    return [_consignor superclass];\n}\n\n- (NSUInteger)hash {\n    return [_consignor hash];\n}\n\n- (NSString *)description {\n    return [_consignor description];\n}\n\n- (NSString *)debugDescription {\n    return [_consignor debugDescription];\n}\n\n- (BOOL)isEqual: (id)object {\n    return [_consignor isEqual: object];\n}\n\n- (BOOL)isKindOfClass: (Class)aClass {\n    return [_consignor isKindOfClass: aClass];\n}\n\n- (BOOL)isMemberOfClass: (Class)aClass {\n    return [_consignor isMemberOfClass: aClass];\n}\n\n- (BOOL)respondsToSelector: (SEL)aSelector {\n    return [_consignor respondsToSelector: aSelector];\n}\n\n- (BOOL)conformsToProtocol: (Protocol *)aProtocol {\n    return [_consignor conformsToProtocol: aProtocol];\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Fluency/LXDAppFluencyMonitor.h",
    "content": "//\n//  LXDAppFluencyMonitor.h\n//  LXDAppFluencyMonitor\n//\n//  Created by linxinda on 2017/3/22.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n\n#define FLUENCYMONITOR [LXDAppFluencyMonitor monitor]\n\n\n/*!\n *  @brief  监听UI线程卡顿\n */\n@interface LXDAppFluencyMonitor : NSObject\n\n+ (instancetype)monitor;\n\n- (void)startMonitoring;\n- (void)stopMonitoring;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Fluency/LXDAppFluencyMonitor.m",
    "content": "//\n//  LXDAppFluencyMonitor.m\n//  LXDAppFluencyMonitor\n//\n//  Created by linxinda on 2017/3/22.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDAppFluencyMonitor.h\"\n#import \"LXDBacktraceLogger.h\"\n#import <UIKit/UIKit.h>\n\n\n#define LXD_SEMAPHORE_SUCCESS 0\nstatic BOOL lxd_is_monitoring = NO;\nstatic dispatch_semaphore_t lxd_semaphore;\nstatic NSTimeInterval lxd_time_out_interval = 0.5;\n\n\n@implementation LXDAppFluencyMonitor\n\nstatic inline dispatch_queue_t __lxd_fluecy_monitor_queue() {\n    static dispatch_queue_t lxd_fluecy_monitor_queue;\n    static dispatch_once_t once;\n    dispatch_once(&once, ^{\n        lxd_fluecy_monitor_queue = dispatch_queue_create(\"com.sindrilin.lxd_monitor_queue\", NULL);\n    });\n    return lxd_fluecy_monitor_queue;\n}\n\nstatic inline void __lxd_monitor_init() {\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        lxd_semaphore = dispatch_semaphore_create(0);\n    });\n}\n\n#pragma mark - Public\n+ (instancetype)monitor {\n    return [LXDAppFluencyMonitor new];\n}\n\n- (void)startMonitoring {\n    if (lxd_is_monitoring) { return; }\n    lxd_is_monitoring = YES;\n    __lxd_monitor_init();\n    dispatch_async(__lxd_fluecy_monitor_queue(), ^{\n        while (lxd_is_monitoring) {\n            __block BOOL timeOut = YES;\n            dispatch_async(dispatch_get_main_queue(), ^{\n                timeOut = NO;\n                dispatch_semaphore_signal(lxd_semaphore);\n            });\n            [NSThread sleepForTimeInterval: lxd_time_out_interval];\n            if (timeOut) {\n                [LXDBacktraceLogger lxd_logMain];\n            }\n            dispatch_wait(lxd_semaphore, DISPATCH_TIME_FOREVER);\n        }\n    });\n}\n\n- (void)stopMonitoring {\n    if (!lxd_is_monitoring) { return; }\n    lxd_is_monitoring = NO;\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Intercept/LXDDNSInterceptor.h",
    "content": "//\n//  LXDDNSInterceptor.h\n//  LXDAppFluecyMonitor\n//\n//  Created by linxinda on 2017/3/28.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\ntypedef void(^LXDInvalidIpHandle)(NSURL * originUrl);\n\n#define REGISTER_INTERCEPTOR [LXDDNSInterceptor registerInterceptor];\n#define UNREGISTER_INTERCEPTOR [LXDDNSInterceptor unregisterInterceptor];\n/*!\n *  @brief  DNS拦截器\n */\n@interface LXDDNSInterceptor : NSURLProtocol\n\n+ (void)registerInterceptor;\n+ (void)unregisterInterceptor;\n+ (void)registerInvalidIpHandle: (LXDInvalidIpHandle)invalidIpHandle;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Intercept/LXDDNSInterceptor.m",
    "content": "//\n//  LXDDNSInterceptor.m\n//  LXDAppFluecyMonitor\n//\n//  Created by linxinda on 2017/3/28.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDDNSInterceptor.h\"\n#import \"LXDHostMapper.h\"\n#import \"LXDHostFilterRule.h\"\n#import \"NSURLProtocol+WebKitSupport.h\"\n#import <objc/runtime.h>\n\n\n#define INVALID_STATUS_CODE 404\n\n\nstatic LXDInvalidIpHandle lxd_invalid_ip_handle;\nstatic void(^lxd_url_session_configure)(NSURLSessionConfiguration * configuration);\nstatic NSString * const LXDURLHasHandledKey = @\"LXDURLHasHandledKey\";\n\n\n\n@interface NSURLSession (LXDIntercept)\n\n- (instancetype)initWithConfiguration: (NSURLSessionConfiguration *)configuration delegate: (id<NSURLSessionDelegate>)delegate delegateQueue: (NSOperationQueue *)queue;\n\n@end\n\n\n\n@implementation NSURLSession (LXDIntercept)\n\n+ (void)load {\n    Method origin = class_getClassMethod([NSURLSession class], @selector(initWithConfiguration:delegate:delegateQueue:));\n    Method custom = class_getClassMethod([NSURLSession class], @selector(lxd_initWithConfiguration:delegate:delegateQueue:));\n    method_exchangeImplementations(origin, custom);\n}\n\n- (NSURLSession *)lxd_initWithConfiguration: (NSURLSessionConfiguration *)configuration delegate: (id<NSURLSessionDelegate>)delegate delegateQueue: (NSOperationQueue *)queue {\n    if (lxd_url_session_configure) {\n        lxd_url_session_configure(configuration);\n    }\n    return [self lxd_initWithConfiguration: configuration delegate: delegate delegateQueue: queue];\n}\n\n@end\n\n\n\n@interface LXDDNSInterceptor ()<NSURLConnectionDelegate>\n\n@property (nonatomic, copy) NSURL * originUrl;\n@property (nonatomic, copy) LXDInvalidIpHandle invalidIpHandle;\n\n@property (nonatomic, strong) NSURLConnection * connection;\n\n@end\n\n\n\n@implementation LXDDNSInterceptor\n\n\n#pragma mark - Public\n+ (void)foreachURLSchemesWithHandle: (void(^)(NSString * scheme))handle {\n    NSParameterAssert(handle);\n    for (NSString * scheme in @[@\"http\", @\"https\"]) {\n        handle(scheme);\n    }\n}\n\n+ (void)registerInterceptor {\n    [NSURLProtocol registerClass: [LXDDNSInterceptor class]];\n    [self foreachURLSchemesWithHandle: ^(NSString *scheme) {\n        [NSURLProtocol lxd_registerScheme: scheme];\n    }];\n    lxd_url_session_configure = ^(NSURLSessionConfiguration * configuration){\n        if (![configuration.protocolClasses containsObject: [LXDDNSInterceptor class]]) {\n            NSMutableArray * protocolClasses = [NSMutableArray arrayWithArray: configuration.protocolClasses];\n            [protocolClasses addObject: [LXDDNSInterceptor class]];\n            configuration.protocolClasses = protocolClasses;\n        }\n    };\n}\n\n+ (void)unregisterInterceptor {\n    lxd_invalid_ip_handle = nil;\n    [NSURLProtocol unregisterClass: [LXDDNSInterceptor class]];\n    [self foreachURLSchemesWithHandle: ^(NSString *scheme) {\n        [NSURLProtocol lxd_unregisterScheme: scheme];\n    }];\n    lxd_url_session_configure = nil;\n}\n\n+ (void)registerInvalidIpHandle: (LXDInvalidIpHandle)invalidIpHandle {\n    lxd_invalid_ip_handle = invalidIpHandle;\n}\n\n\n#pragma mark - Override\n+ (BOOL)canInitWithTask: (NSURLSessionTask *)task {\n    return ([NSURLProtocol propertyForKey: LXDURLHasHandledKey inRequest: task.currentRequest] == nil);\n}\n\n+ (BOOL)canInitWithRequest: (NSURLRequest *)request {\n    return ([NSURLProtocol propertyForKey: LXDURLHasHandledKey inRequest: request] == nil);\n}\n\n+ (NSURLRequest *)canonicalRequestForRequest: (NSURLRequest *)request {\n    NSString * host = request.URL.host;\n    NSString * ip = [LXDHostMapper parseHost: host];\n    if (ip == nil) { return request; }\n    if ([LXDHostFilterRule isIpInvalid: ip]) { return request; }\n    \n    NSString * absoluteURLString = request.URL.absoluteString;\n    NSRange range = [absoluteURLString rangeOfString: host];\n    if (range.location == NSNotFound) { return request; }\n    \n    absoluteURLString = [absoluteURLString stringByReplacingCharactersInRange: range withString: ip];\n    NSMutableURLRequest * canonicalRequest = request.mutableCopy;\n    canonicalRequest.URL = [NSURL URLWithString: absoluteURLString];\n    return canonicalRequest;\n}\n\n- (void)startLoading {\n    NSMutableURLRequest * request = self.request.mutableCopy;\n    [NSURLProtocol setProperty: @YES forKey: LXDURLHasHandledKey inRequest: request];\n    self.connection = [NSURLConnection connectionWithRequest: request delegate: self];\n}\n\n- (void)stopLoading {\n    [self.connection cancel];\n    [NSURLProtocol removePropertyForKey: LXDURLHasHandledKey inRequest: self.connection.currentRequest.mutableCopy];\n}\n\n\n#pragma mark - NSURLConnectionDelegate\n- (void)connection: (NSURLConnection *)connection didReceiveResponse: (NSURLResponse *)response {\n    if ([response isKindOfClass: [NSHTTPURLResponse class]]) {\n        NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response;\n        if (httpResponse.statusCode == INVALID_STATUS_CODE && lxd_invalid_ip_handle) {\n            NSString * host = response.URL.host;\n            if ([LXDHostMapper validIp: host]) {\n                [connection cancel];\n                [LXDHostFilterRule registerInvailIp: host];\n                \n                NSString * absoluteURLString = response.URL.absoluteString;\n                NSRange range = [absoluteURLString rangeOfString: host];\n                if (range.location != NSNotFound) {\n                    absoluteURLString = [absoluteURLString stringByReplacingCharactersInRange: range withString: [LXDHostFilterRule getHostFromIpAddress: host]];\n                    lxd_invalid_ip_handle([NSURL URLWithString: absoluteURLString]);\n                }\n            }\n        }\n    }\n    [self.client URLProtocol: self didReceiveResponse: response cacheStoragePolicy: NSURLCacheStorageAllowedInMemoryOnly];\n}\n\n- (void)connection: (NSURLConnection *)connection didReceiveData: (NSData *)data {\n    [self.client URLProtocol: self didLoadData: data];\n}\n\n- (void)connectionDidFinishLoading: (NSURLConnection *)connection {\n    [self.client URLProtocolDidFinishLoading: self];\n}\n\n- (void)connection: (NSURLConnection *)connection didFailWithError: (NSError *)error {\n    [self.client URLProtocol: self didFailWithError: error];\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Intercept/LXDHostFilterRule.h",
    "content": "//\n//  LXDFilterRule.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/3/29.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n/*!\n *  @brief 域名过滤规则\n */\n@interface LXDHostFilterRule : NSObject\n\n+ (void)registerInvailIp: (NSString *)ip;\n+ (void)mapHost: (NSString *)host toIp: (NSString *)ip;\n\n+ (BOOL)isIpInvalid: (NSString *)ip;\n+ (NSString *)getIpAddressFromHost: (NSString *)host;\n+ (NSString *)getHostFromIpAddress: (NSString *)ipAddress;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Intercept/LXDHostFilterRule.m",
    "content": "//\n//  LXDFilterRule.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/3/29.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDHostFilterRule.h\"\n\nstatic inline NSMutableSet * lxd_invalid_ips() {\n    static NSMutableSet * lxd_invalid_ips;\n    static dispatch_once_t once;\n    dispatch_once(&once, ^{\n        lxd_invalid_ips = [NSMutableSet set];\n    });\n    return lxd_invalid_ips;\n}\n\nstatic inline NSMutableDictionary * lxd_ip_mapper() {\n    static NSMutableDictionary * lxd_ip_mapper;\n    static dispatch_once_t once;\n    dispatch_once(&once, ^{\n        lxd_ip_mapper = @{}.mutableCopy;\n    });\n    return lxd_ip_mapper;\n}\n\nstatic inline NSMutableDictionary * lxd_host_mapper() {\n    static NSMutableDictionary * lxd_host_mapper;\n    static dispatch_once_t once;\n    dispatch_once(&once, ^{\n        lxd_host_mapper = @{}.mutableCopy;\n    });\n    return lxd_host_mapper;\n}\n\n\n@implementation LXDHostFilterRule\n\n\n+ (void)registerInvailIp: (NSString *)ip {\n    [lxd_invalid_ips() addObject: ip];\n}\n\n+ (void)mapHost: (NSString *)host toIp: (NSString *)ip {\n    lxd_ip_mapper()[ip] = host;\n    lxd_host_mapper()[host] = ip;\n}\n\n+ (BOOL)isIpInvalid: (NSString *)ip {\n    return [lxd_invalid_ips() containsObject: ip];\n}\n\n+ (NSString *)getIpAddressFromHost: (NSString *)host {\n    return lxd_host_mapper()[host];\n}\n\n+ (NSString *)getHostFromIpAddress: (NSString *)ipAddress {\n    return lxd_ip_mapper()[ipAddress];\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Intercept/LXDHostMapper.h",
    "content": "//\n//  LXDHostMapper.h\n//  LXDAppFluecyMonitor\n//\n//  Created by linxinda on 2017/3/28.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n\ntypedef NSString *(^LXDHostMap)(NSString * host);\n\n\n/*!\n *  @brief  域名解析\n */\n@interface LXDHostMapper : NSObject\n\n+ (BOOL)validIp: (NSString *)ip;\n+ (void)setHostMap: (LXDHostMap)hostMap;\n+ (void)parseHost: (NSString *)host complete: (void(^)(NSString * ip))complete;\n\n+ (NSString *)parseHost: (NSString *)host;\n+ (NSString *)getIpv4AddressFromHost: (NSString *)host;\n+ (NSString *)getIpv6AddressFromHost: (NSString *)host;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Intercept/LXDHostMapper.m",
    "content": "//\n//  LXDHostMapper.m\n//  LXDAppFluecyMonitor\n//\n//  Created by linxinda on 2017/3/28.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDHostMapper.h\"\n#import \"LXDHostFilterRule.h\"\n#import <netdb.h>\n#import <arpa/inet.h>\n#import <sys/types.h>\n#import <sys/socket.h>\n\n\nstatic LXDHostMap lxd_host_map;\n\n\n@implementation LXDHostMapper\n\n\n+ (BOOL)validIp: (NSString *)ip {\n    return [self validIpv4: ip];\n}\n\n+ (BOOL)validIpv4: (NSString *)ip {\n    NSString * ipRegExp = @\"^(([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\\\\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(0\\\\.0\\\\.0\\\\.0)$\";\n    NSPredicate * predicate = [NSPredicate predicateWithFormat: @\"SELF matches %@\", ipRegExp];\n    return [predicate evaluateWithObject: ip];\n}\n\n+ (BOOL)validIpv6: (NSString *)ip {\n    NSString * ipRegExp = @\"^(^((\\\\p{XDigit}{1,4}):){7}(\\\\p{XDigit}{1,4})$)|(^(::((\\\\p{XDigit}//{1,4}):){0,5}(\\\\p{XDigit}{1,4}))$)|(^((\\\\p{XDigit}{1,4})(:|::)){0,6}(\\\\p//{XDigit}{1,4})$)$\";\n    NSPredicate * predicate = [NSPredicate predicateWithFormat: @\"SELF matches %@\", ipRegExp];\n    return [predicate evaluateWithObject: ip];\n}\n\n+ (BOOL)validHost: (NSString *)host {\n    NSString * hostRegExp = @\"((http[s]?|ftp)://[a-zA-Z0-9\\\\.\\\\-]+\\\\.([a-zA-Z]{2,4})(:\\\\d+)?(/[a-zA-Z0-9\\\\.\\\\-~!@#$%^&*+?:_/=<>]*)?)|(www.[a-zA-Z0-9\\\\.\\\\-]+\\\\.([a-zA-Z]{2,4})(:\\\\d+)?(/[a-zA-Z0-9\\\\.\\\\-~!@#$%^&*+?:_/=<>]*)?)\";\n    NSPredicate * predicate = [NSPredicate predicateWithFormat: @\"SELF matches %@\", hostRegExp];\n    return [predicate evaluateWithObject: host];\n}\n\n+ (void)setHostMap: (LXDHostMap)hostMap {\n    lxd_host_map = [hostMap copy];\n}\n\n+ (void)parseHost: (NSString *)host complete: (void(^)(NSString * ip))complete {\n    NSParameterAssert(complete);\n    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{\n        complete([self parseHost: host]);\n    });\n}\n\n+ (NSString *)parseHost: (NSString *)host {\n    if ([self validIp: host]) { return host; }\n    if (![self validHost: host]) { return nil; }\n    NSString * ipAddress = [LXDHostFilterRule getIpAddressFromHost: host];\n    if (ipAddress != nil) { return ipAddress; }\n    \n    if (lxd_host_map != nil) {\n        NSString * ipAddress = lxd_host_map(host);\n        if (ipAddress == nil) {\n            ipAddress = [self getIpAddressFromHostName: host];\n            [LXDHostFilterRule mapHost: host toIp: ipAddress];\n            return ipAddress;\n        }\n    } else {\n        ipAddress = [self getIpAddressFromHostName: host];\n    }\n    [LXDHostFilterRule mapHost: host toIp: ipAddress];\n    return ipAddress;\n}\n\n+ (NSString *)getIpAddressFromHostName: (NSString *)host {\n    NSString * ipAddress = [self getIpv6AddressFromHost: host];\n    if (ipAddress == nil) {\n        ipAddress = [self getIpv4AddressFromHost: host];\n    }\n    return ipAddress;\n}\n\n+ (NSString *)getIpv4AddressFromHost: (NSString *)host {\n    const char * hostName = host.UTF8String;\n    __block struct hostent * phost = [self getHostByName: hostName execute: ^{\n        phost = gethostbyname(hostName);\n    }];\n    if ( phost == NULL ) { return nil; }\n    \n    struct in_addr ip_addr;\n    memcpy(&ip_addr, phost->h_addr_list[0], 4);\n    \n    char ip[20] = { 0 };\n    inet_ntop(AF_INET, &ip_addr, ip, sizeof(ip));\n    return [NSString stringWithUTF8String: ip];\n}\n\n+ (NSString *)getIpv6AddressFromHost: (NSString *)host {\n    const char * hostName = host.UTF8String;\n    __block struct hostent * phost = [self getHostByName: hostName execute: ^{\n        phost = gethostbyname2(hostName, AF_INET6);\n    }];\n    if ( phost == NULL ) { return nil; }\n    \n    char ip[32] = { 0 };\n    char ** aliases;\n    switch (phost->h_addrtype) {\n        case AF_INET:\n        case AF_INET6: {\n            for (aliases = phost->h_addr_list; *aliases != NULL; aliases++) {\n                NSString * ipAddress = [NSString stringWithUTF8String: inet_ntop(phost->h_addrtype, *aliases, ip, sizeof(ip))];\n                    if (ipAddress) { return ipAddress; }\n            }\n        } break;\n            \n        default:\n            break;\n    }\n    return nil;\n}\n\n\n+ (struct hostent *)getHostByName: (const char *)hostName execute: (dispatch_block_t)execute {\n    if (execute == nil) { return NULL; }\n    __block struct hostent * phost = NULL;\n    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);\n    NSOperationQueue * queue = [NSOperationQueue new];\n    queue.maxConcurrentOperationCount = 1;\n    [queue addOperationWithBlock: ^{\n        execute();\n        dispatch_semaphore_signal(semaphore);\n    }];\n    dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 1.5 * NSEC_PER_SEC));\n    [queue cancelAllOperations];\n    return phost;\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Intercept/NSURLProtocol+WebKitSupport.h",
    "content": "//\n//  NSURLProtocol+WebKitSupport.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/3/30.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n/*!\n *  @brief  WK支持\n */\n@interface NSURLProtocol (WebKitSupport)\n\n+ (void)lxd_registerScheme: (NSString *)scheme;\n+ (void)lxd_unregisterScheme: (NSString *)scheme;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Intercept/NSURLProtocol+WebKitSupport.m",
    "content": "//\n//  NSURLProtocol+WebKitSupport.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/3/30.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"NSURLProtocol+WebKitSupport.h\"\n#import <WebKit/WebKit.h>\n\nstatic inline NSString * lxd_scheme_selector_suffix() {\n    return @\"SchemeForCustomProtocol:\";\n}\n\nstatic inline id lxd_context_controller() {\n    static Class cls;\n    if (!cls) {\n        cls = [[[NSClassFromString(@\"WKWebView\") new] valueForKey:@\"browsingContextController\"] class];\n    }\n    return cls;\n}\n\nstatic inline SEL lxd_register_scheme_selector() {\n    const NSString * const registerPrefix = @\"register\";\n    return NSSelectorFromString([registerPrefix stringByAppendingString: lxd_scheme_selector_suffix()]);\n}\n\nstatic inline SEL lxd_unregister_scheme_selector() {\n    const NSString * const unregisterPrefix = @\"unregister\";\n    return NSSelectorFromString([unregisterPrefix stringByAppendingString: lxd_scheme_selector_suffix()]);\n}\n\n\n@implementation NSURLProtocol (WebKitSupport)\n\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n+ (void)lxd_registerScheme: (NSString *)scheme {\n    if ([lxd_context_controller() respondsToSelector: lxd_register_scheme_selector()]) {\n        [lxd_context_controller() performSelector: lxd_register_scheme_selector() withObject: scheme];\n    }\n}\n\n+ (void)lxd_unregisterScheme: (NSString *)scheme {\n    if ([lxd_context_controller() respondsToSelector: lxd_unregister_scheme_selector()]) {\n        [lxd_context_controller() performSelector: lxd_unregister_scheme_selector() withObject: scheme];\n    }\n}\n#pragma clang diagnostic pop\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Resource/LXDApplicationCPU.h",
    "content": "//\n//  LXDApplicationCPU.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/25.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n/*!\n *  @brief  应用CPU占用\n */\n@interface LXDApplicationCPU : NSObject\n\n- (double)currentUsage;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Resource/LXDApplicationCPU.m",
    "content": "//\n//  LXDApplicationCPU.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/25.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDApplicationCPU.h\"\n#import <mach/task.h>\n#import <mach/vm_map.h>\n#import <mach/mach_init.h>\n#import <mach/thread_act.h>\n#import <mach/thread_info.h>\n\n\n@implementation LXDApplicationCPU\n\n\n- (double)currentUsage {\n    double usageRatio = 0;\n    thread_info_data_t thinfo;\n    thread_act_array_t threads;\n    thread_basic_info_t basic_info_t;\n    mach_msg_type_number_t count = 0;\n    mach_msg_type_number_t thread_info_count = THREAD_INFO_MAX;\n    \n    if (task_threads(mach_task_self(), &threads, &count) == KERN_SUCCESS) {\n        for (int idx = 0; idx < count; idx++) {\n            if (thread_info(threads[idx], THREAD_BASIC_INFO, (thread_info_t)thinfo, &thread_info_count) == KERN_SUCCESS) {\n                basic_info_t = (thread_basic_info_t)thinfo;\n                if (!(basic_info_t->flags & TH_FLAGS_IDLE)) {\n                    usageRatio += basic_info_t->cpu_usage / (double)TH_USAGE_SCALE;\n                }\n            }\n        }\n        assert(vm_deallocate(mach_task_self(), (vm_address_t)threads, count * sizeof(thread_t)) == KERN_SUCCESS);\n    }\n    return usageRatio * 100.;\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Resource/LXDApplicationMemory.h",
    "content": "//\n//  LXDApplicationMemory.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/26.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\ntypedef struct LXDApplicationMemoryUsage\n{\n    double usage;   ///< 已用内存(MB)\n    double total;   ///< 总内存(MB)\n    double ratio;   ///< 占用比率\n} LXDApplicationMemoryUsage;\n\n/*!\n *  @brief  应用内存占用\n */\n@interface LXDApplicationMemory : NSObject\n\n- (LXDApplicationMemoryUsage)currentUsage;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Resource/LXDApplicationMemory.m",
    "content": "//\n//  LXDApplicationMemory.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/26.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDApplicationMemory.h\"\n#import <mach/mach.h>\n#import <mach/task_info.h>\n\n\n#ifndef NBYTE_PER_MB\n#define NBYTE_PER_MB (1024 * 1024)\n#endif\n\n\n@implementation LXDApplicationMemory\n\n\n- (LXDApplicationMemoryUsage)currentUsage {\n    struct mach_task_basic_info info;\n    mach_msg_type_number_t count = sizeof(info) / sizeof(integer_t);\n    if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &count) == KERN_SUCCESS) {\n        return (LXDApplicationMemoryUsage){\n            .usage = info.resident_size / NBYTE_PER_MB,\n            .total = [NSProcessInfo processInfo].physicalMemory / NBYTE_PER_MB,\n            .ratio = info.virtual_size / [NSProcessInfo processInfo].physicalMemory,\n        };\n    }\n    return (LXDApplicationMemoryUsage){ 0 };\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Resource/LXDCPUDisplayer.h",
    "content": "//\n//  LXDCPUDisplayer.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/27.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n/*!\n *  @brief  CPU占用展示器\n */\n@interface LXDCPUDisplayer : UIView\n\n- (void)displayCPUUsage: (double)usage;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Resource/LXDCPUDisplayer.m",
    "content": "//\n//  LXDCPUDisplayer.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/27.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDCPUDisplayer.h\"\n#import \"LXDMonitorUI.h\"\n#import \"LXDDispatchAsync.h\"\n\n\n@interface LXDCPUDisplayer ()\n\n@property (nonatomic, strong) LXDAsyncLabel * displayerLabel;\n\n@end\n\n\n@implementation LXDCPUDisplayer\n\n\n- (instancetype)initWithFrame: (CGRect)frame {\n    if (self = [super initWithFrame: frame]) {\n        CAShapeLayer * bgLayer = [CAShapeLayer layer];\n        bgLayer.fillColor = [UIColor colorWithWhite: 0 alpha: 0.7].CGColor;\n        bgLayer.path = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame)) cornerRadius: 5].CGPath;\n        [self.layer addSublayer: bgLayer];\n        \n        self.displayerLabel = [[LXDAsyncLabel alloc] initWithFrame: self.bounds];\n        self.displayerLabel.textColor = [UIColor whiteColor];\n        self.displayerLabel.textAlignment = NSTextAlignmentCenter;\n        self.displayerLabel.font = [UIFont fontWithName: @\"Menlo\" size: 14];\n        [self addSubview: self.displayerLabel];\n    }\n    return self;\n}\n\n- (void)displayCPUUsage: (double)usage {\n    int use = usage;\n    LXDDispatchQueueAsyncBlockInDefault(^{\n        NSMutableAttributedString * attributed = [[NSMutableAttributedString alloc] initWithString: @\"CPU\" attributes: @{ NSForegroundColorAttributeName: [UIColor whiteColor], NSFontAttributeName: _displayerLabel.font }];\n        [attributed appendAttributedString: [[NSAttributedString alloc] initWithString: [NSString stringWithFormat: @\"%d%%\", use] attributes: @{ NSFontAttributeName: _displayerLabel.font, NSForegroundColorAttributeName: [UIColor colorWithHue: 0.27 * (0.8 - (use / 100.)) saturation: 1 brightness: 0.9 alpha: 1] }]];\n        self.displayerLabel.attributedText = attributed;\n    });\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Resource/LXDMemoryDisplayer.h",
    "content": "//\n//  LXDMemoryDisplayer.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/27.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n/*!\n *  @brief  内存使用展示器\n */\n@interface LXDMemoryDisplayer : UIView\n\n- (void)displayUsage: (double)usage;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Resource/LXDMemoryDisplayer.m",
    "content": "//\n//  LXDMemoryDisplayer.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/27.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDMemoryDisplayer.h\"\n#import \"LXDMonitorUI.h\"\n#import \"LXDDispatchAsync.h\"\n\n\n#define LXD_HIGH_MEMORY_USAGE (([NSProcessInfo processInfo].physicalMemory / 1024 / 1024) / 2)\n\n\n@interface LXDMemoryDisplayer ()\n\n@property (nonatomic, strong) LXDAsyncLabel * displayerLabel;\n\n@end\n\n\n@implementation LXDMemoryDisplayer\n\n\n- (instancetype)initWithFrame: (CGRect)frame {\n    if (self = [super initWithFrame: frame]) {\n        CAShapeLayer * bgLayer = [CAShapeLayer layer];\n        bgLayer.fillColor = [UIColor colorWithWhite: 0 alpha: 0.7].CGColor;\n        bgLayer.path = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(0, 0, CGRectGetWidth(frame), CGRectGetHeight(frame)) cornerRadius: 5].CGPath;\n        [self.layer addSublayer: bgLayer];\n        \n        self.displayerLabel = [[LXDAsyncLabel alloc] initWithFrame: self.bounds];\n        self.displayerLabel.textColor = [UIColor whiteColor];\n        self.displayerLabel.textAlignment = NSTextAlignmentCenter;\n        self.displayerLabel.font = [UIFont fontWithName: @\"Menlo\" size: 14];\n        [self addSubview: self.displayerLabel];\n    }\n    return self;\n}\n\n- (void)displayUsage: (double)usage {\n    LXDDispatchQueueAsyncBlockInBackground(^{\n        NSMutableAttributedString * attributed = [[NSMutableAttributedString alloc] initWithString: [NSString stringWithFormat: @\"%.1f\", usage] attributes: @{ NSFontAttributeName: _displayerLabel.font, NSForegroundColorAttributeName: [UIColor colorWithHue: 0.27 * (0.8 - usage / LXD_HIGH_MEMORY_USAGE) saturation: 1 brightness: 0.9 alpha: 1] }];\n        [attributed appendAttributedString: [[NSAttributedString alloc] initWithString: @\"MB\" attributes: @{ NSForegroundColorAttributeName: [UIColor whiteColor], NSFontAttributeName: _displayerLabel.font }]];\n        self.displayerLabel.attributedText = attributed;\n    });\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Resource/LXDResourceMonitor.h",
    "content": "//\n//  LXDResourceMonitor.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/27.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n\n#define RESOURCE_MONITOR [LXDResourceMonitor new]\n\n\ntypedef NS_ENUM(NSInteger, LXDResourceMonitorType)\n{\n    LXDResourceMonitorTypeDefault = (1 << 2) | (1 << 3),\n    LXDResourceMonitorTypeSystemCpu = 1 << 0,   ///<    监控系统CPU使用率，优先级低\n    LXDResourceMonitorTypeSystemMemory = 1 << 1,    ///<    监控系统内存使用率，优先级低\n    LXDResourceMonitorTypeApplicationCpu = 1 << 2,  ///<    监控应用CPU使用率，优先级高\n    LXDResourceMonitorTypeApplicationMemoty = 1 << 3,   ///<    监控应用内存使用率，优先级高\n};\n\n\n/*!\n *  @brief  硬件资源监控\n */\n@interface LXDResourceMonitor : NSObject\n\n+ (instancetype)monitorWithMonitorType: (LXDResourceMonitorType)monitorType;\n- (void)startMonitoring;\n- (void)stopMonitoring;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Resource/LXDResourceMonitor.m",
    "content": "//\n//  LXDResourceMonitor.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/27.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDResourceMonitor.h\"\n\n#import \"LXDSystemCPU.h\"\n#import \"LXDApplicationCPU.h\"\n#import \"LXDSystemMemory.h\"\n#import \"LXDApplicationMemory.h\"\n\n#import \"LXDMonitorUI.h\"\n#import \"LXDGlobalTimer.h\"\n#import \"LXDCPUDisplayer.h\"\n#import \"LXDMemoryDisplayer.h\"\n\n\n@interface LXDResourceMonitor ()\n\n@property (nonatomic, strong) LXDSystemCPU * sysCpu;\n@property (nonatomic, strong) LXDApplicationCPU * appCpu;\n@property (nonatomic, strong) LXDSystemMemory * sysMemory;\n@property (nonatomic, strong) LXDApplicationMemory * appMemory;\n\n@property (nonatomic, strong) LXDCPUDisplayer * cpuDisplayer;\n@property (nonatomic, strong) LXDMemoryDisplayer * memoryDisplayer;\n\n@end\n\n\n@implementation LXDResourceMonitor\n\n\n+ (instancetype)monitorWithMonitorType: (LXDResourceMonitorType)monitorType {\n    return [[self alloc] initWithMonitorType: monitorType];\n}\n\n- (instancetype)init {\n    return [self initWithMonitorType: LXDResourceMonitorTypeDefault];\n}\n\n- (instancetype)initWithMonitorType: (LXDResourceMonitorType)monitorType {\n    if (self = [super init]) {\n        BOOL cpuMonitorEnabled = YES, memoryMonitorEnabled = YES;\n        if (monitorType & LXDResourceMonitorTypeApplicationCpu) {\n            self.appCpu = [LXDApplicationCPU new];\n        } else if (monitorType & LXDResourceMonitorTypeSystemCpu) {\n            self.sysCpu = [LXDSystemCPU new];\n        } else {\n            cpuMonitorEnabled = NO;\n        }\n        if (monitorType & LXDResourceMonitorTypeApplicationMemoty) {\n            self.appMemory = [LXDApplicationMemory new];\n        } else if (monitorType & LXDResourceMonitorTypeSystemMemory) {\n            self.sysMemory = [LXDSystemMemory new];\n        } else {\n            memoryMonitorEnabled = NO;\n        }\n        if (!(cpuMonitorEnabled | memoryMonitorEnabled)) {\n            @throw [NSException exceptionWithName: NSInvalidArgumentException reason: [NSString stringWithFormat: @\"[%@ initWithMonitorType]: cannot create %@ instance without monitor type\", [self class], [self class]] userInfo: nil];\n        }\n        \n        if (cpuMonitorEnabled) {\n            self.cpuDisplayer = [[LXDCPUDisplayer alloc] initWithFrame: CGRectMake(0, 30, 60, 20)];\n            CGFloat centerX = round(CGRectGetWidth([UIScreen mainScreen].bounds) / 4);\n            self.cpuDisplayer.center = CGPointMake(centerX, self.cpuDisplayer.center.y);\n        }\n        if (memoryMonitorEnabled) {\n            self.memoryDisplayer = [[LXDMemoryDisplayer alloc] initWithFrame: CGRectMake(CGRectGetWidth([UIScreen mainScreen].bounds) - 140, 30, 60, 20)];\n            CGFloat centerX = round(CGRectGetWidth([UIScreen mainScreen].bounds) / 4 * 3);\n            self.memoryDisplayer.center = CGPointMake(centerX, self.memoryDisplayer.center.y);\n        }\n    }\n    return self;\n}\n\nstatic NSString * lxd_resource_monitor_callback_key;\n\n- (void)startMonitoring {\n    if (lxd_resource_monitor_callback_key != nil) { return; }\n    lxd_resource_monitor_callback_key = [[LXDGlobalTimer registerTimerCallback: ^{\n        double cpuUsage, memoryUsage;\n        if (_appCpu) {\n            cpuUsage = [_appCpu currentUsage];\n        } else {\n            LXDSystemCPUUsage usage = [_sysCpu currentUsage];\n            cpuUsage = usage.user + usage.system + usage.nice;\n        }\n        if (_appMemory) {\n            LXDApplicationMemoryUsage usage = [_appMemory currentUsage];\n            memoryUsage = usage.usage;\n        } else {\n            LXDSystemMemoryUsage usage = [_sysMemory currentUsage];\n            memoryUsage = (usage.wired + usage.active);\n        }\n        [self.cpuDisplayer displayCPUUsage: cpuUsage];\n        [self.memoryDisplayer displayUsage: memoryUsage];\n    }] copy];\n    [[LXDTopWindow topWindow] addSubview: self.cpuDisplayer];\n    [[LXDTopWindow topWindow] addSubview: self.memoryDisplayer];\n}\n\n- (void)stopMonitoring {\n    if (lxd_resource_monitor_callback_key == nil) { return; }\n    [LXDGlobalTimer resignTimerCallbackWithKey: lxd_resource_monitor_callback_key];\n    [self.cpuDisplayer removeFromSuperview];\n    [self.memoryDisplayer removeFromSuperview];\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Resource/LXDSystemCPU.h",
    "content": "//\n//  LXDSystemCPU.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/1.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\ntypedef struct LXDSystemCPUUsage\n{\n    double system;  ///< 系统占用率\n    double user;    ///< user占用率\n    double nice;    ///< 加权user占用率\n    double idle;    ///< 空闲率\n} LXDSystemCPUUsage;\n\n/*!\n *  @brief  系统CPU占用\n */\n@interface LXDSystemCPU : NSObject\n\n@property (nonatomic, readonly) double systemRatio;\n@property (nonatomic, readonly) double userRatio;\n@property (nonatomic, readonly) double niceRatio;\n@property (nonatomic, readonly) double idleRatio;\n\n- (LXDSystemCPUUsage)currentUsage;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Resource/LXDSystemCPU.m",
    "content": "//\n//  LXDSystemCPU.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/1.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDSystemCPU.h\"\n#import <mach/vm_map.h>\n#import <mach/mach_host.h>\n#import <mach/processor_info.h>\n\n\nstatic NSArray * previousCPUInfo;\n\n\n/// processor_info_array_t结构数据偏移位\ntypedef NS_ENUM(NSInteger, LXDCPUInfoOffsetState)\n{\n    LXDCPUInfoOffsetStateSystem = 0,\n    LXDCPUInfoOffsetStateUser = 1,\n    LXDCPUInfoOffsetStateNice = 2,\n    LXDCPUInfoOffsetStateIdle = 3,\n    LXDCPUInfoOffsetStateMask = 4,\n};\n\n/// cpu信息结构体\nstatic NSUInteger LXDSystemCPUInfoCount = 4;\ntypedef struct LXDSystemCPUInfo {\n    NSUInteger system;  ///< 系统态占用。\n    NSUInteger user;    ///< 用户态占用。\n    NSUInteger nice;    ///< nice加权的用户态占用。\n    NSUInteger idle;    ///< 空闲占用\n} LXDSystemCPUInfo;\n\n/// 结构体构造转换\nstatic inline LXDSystemCPUInfo __LXDSystemCPUInfoMake(NSUInteger system, NSUInteger user, NSUInteger nice, NSUInteger idle) {\n    return (LXDSystemCPUInfo){ system, user, nice, idle };\n}\n\nstatic inline NSString * LXDStringFromSystemCPUInfo(LXDSystemCPUInfo systemCPUInfo) {\n    return [NSString stringWithFormat: @\"%lu-%lu-%lu-%lu\", systemCPUInfo.system, systemCPUInfo.user, systemCPUInfo.nice, systemCPUInfo.idle];\n}\n\nstatic inline LXDSystemCPUInfo LXDSystemCPUInfoFromString(NSString * string) {\n    NSArray * infos = [string componentsSeparatedByString: @\"-\"];\n    if (infos.count == LXDSystemCPUInfoCount) {\n        return __LXDSystemCPUInfoMake(\n                                    [infos[LXDCPUInfoOffsetStateSystem] integerValue],\n                                    [infos[LXDCPUInfoOffsetStateUser] integerValue],\n                                    [infos[LXDCPUInfoOffsetStateNice] integerValue],\n                                    [infos[LXDCPUInfoOffsetStateIdle] integerValue]);\n    }\n    return (LXDSystemCPUInfo){ 0 };\n}\n\n\n@interface LXDSystemCPU ()\n\n@property (nonatomic, assign) double systemRatio;\n@property (nonatomic, assign) double userRatio;\n@property (nonatomic, assign) double niceRatio;\n@property (nonatomic, assign) double idleRatio;\n\n@property (nonatomic, copy) NSArray<NSString *> * cpuInfos;\n\n@end\n\n\n@implementation LXDSystemCPU\n\n\n- (LXDSystemCPUUsage)currentUsage {\n    return [self generateSystemCpuUsageWithCpuInfos: [self generateCpuInfos]];\n}\n\n- (NSArray<NSString *> *)generateCpuInfos {\n    natural_t cpu_processor_count = 0;\n    natural_t cpu_processor_info_count = 0;\n    processor_info_array_t cpu_processor_infos = NULL;\n    \n    kern_return_t result = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &cpu_processor_count, &cpu_processor_infos, &cpu_processor_info_count);\n    if ( result == KERN_SUCCESS && cpu_processor_infos != NULL ) {\n        NSMutableArray * infos = [NSMutableArray arrayWithCapacity: cpu_processor_count];\n        for (int idx = 0; idx < cpu_processor_count; idx++) {\n            NSInteger offset = LXDCPUInfoOffsetStateMask * idx;\n            \n            double system, user, nice, idle;\n            if (previousCPUInfo.count > idx) {\n                LXDSystemCPUInfo previousInfo = LXDSystemCPUInfoFromString(previousCPUInfo[idx]);\n                system = cpu_processor_infos[offset + LXDCPUInfoOffsetStateSystem] - previousInfo.system;\n                user = cpu_processor_infos[offset + LXDCPUInfoOffsetStateUser] - previousInfo.user;\n                nice = cpu_processor_infos[offset + LXDCPUInfoOffsetStateNice] - previousInfo.nice;\n                idle = cpu_processor_infos[offset + LXDCPUInfoOffsetStateIdle] - previousInfo.idle;\n            } else {\n                system = cpu_processor_infos[offset + LXDCPUInfoOffsetStateSystem];\n                user = cpu_processor_infos[offset + LXDCPUInfoOffsetStateUser];\n                nice = cpu_processor_infos[offset + LXDCPUInfoOffsetStateNice];\n                idle = cpu_processor_infos[offset + LXDCPUInfoOffsetStateIdle];\n            }\n            LXDSystemCPUInfo info = __LXDSystemCPUInfoMake( system, user, nice, idle );\n            [infos addObject: LXDStringFromSystemCPUInfo(info)];\n        }\n        \n        vm_size_t cpuInfoSize = sizeof(int32_t) * cpu_processor_count;\n        vm_deallocate(mach_task_self_, (vm_address_t)cpu_processor_infos, cpuInfoSize);\n        return infos;\n    }\n    return nil;\n}\n\n- (LXDSystemCPUUsage)generateSystemCpuUsageWithCpuInfos: (NSArray<NSString *> *)cpuInfos {\n    if (cpuInfos.count == 0) { return (LXDSystemCPUUsage){ 0 }; }\n    double system = 0, user = 0, nice = 0, idle = 0;\n    for (NSString * cpuInfoString in cpuInfos) {\n        LXDSystemCPUInfo cpuInfo = LXDSystemCPUInfoFromString(cpuInfoString);\n        system += cpuInfo.system;\n        user += cpuInfo.user;\n        nice += cpuInfo.nice;\n        idle += cpuInfo.idle;\n    }\n    system /= cpuInfos.count;\n    user /= cpuInfos.count;\n    nice /= cpuInfos.count;\n    idle /= cpuInfos.count;\n    \n    double total = system + user + nice + idle;\n    return (LXDSystemCPUUsage){\n        .system = system / total,\n        .user = user / total,\n        .nice = nice / total,\n        .idle = idle / total,\n    };\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Resource/LXDSystemMemory.h",
    "content": "//\n//  LXDMemoryUsage.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/26.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\ntypedef struct LXDSystemMemoryUsage\n{\n    double free;    ///< 自由内存(MB)\n    double wired;   ///< 固定内存(MB)\n    double active;  ///< 正在使用的内存(MB)\n    double inactive;    ///< 缓存、后台内存(MB)\n    double compressed;  ///< 压缩内存(MB)\n    double total;   ///< 总内存(MB)\n} LXDSystemMemoryUsage;\n\n/*!\n *  @brief  系统内存使用\n */\n@interface LXDSystemMemory : NSObject\n\n- (LXDSystemMemoryUsage)currentUsage;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Resource/LXDSystemMemory.m",
    "content": "//\n//  LXDMemoryUsage.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/26.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDSystemMemory.h\"\n#import <mach/mach.h>\n#import <mach/vm_statistics.h>\n\n\n#ifndef NBYTE_PER_MB\n#define NBYTE_PER_MB (1024 * 1024)\n#endif\n\n\n@implementation LXDSystemMemory\n\n\n- (LXDSystemMemoryUsage)currentUsage {\n    vm_statistics64_data_t vmstat;\n    natural_t size = HOST_VM_INFO64_COUNT;\n    if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t)&vmstat, &size) == KERN_SUCCESS) {\n        return (LXDSystemMemoryUsage){\n            .free = vmstat.free_count * PAGE_SIZE / NBYTE_PER_MB,\n            .wired = vmstat.wire_count * PAGE_SIZE / NBYTE_PER_MB,\n            .active = vmstat.active_count * PAGE_SIZE / NBYTE_PER_MB,\n            .inactive = vmstat.inactive_count * PAGE_SIZE / NBYTE_PER_MB,\n            .compressed = vmstat.compressor_page_count * PAGE_SIZE / NBYTE_PER_MB,\n            .total = [NSProcessInfo processInfo].physicalMemory / NBYTE_PER_MB,\n        };\n    }\n    return (LXDSystemMemoryUsage){ 0 };\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/Backtrace/LXDBacktraceLogger.h",
    "content": "//\n//  LXDBacktraceLogger.h\n//  LXDAppFluencyMonitor\n//\n//  Created by linxinda on 2017/3/23.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n/*!\n *  @brief  线程堆栈上下文输出\n */\n@interface LXDBacktraceLogger : NSObject\n\n+ (NSString *)lxd_backtraceOfAllThread;\n+ (NSString *)lxd_backtraceOfMainThread;\n+ (NSString *)lxd_backtraceOfCurrentThread;\n+ (NSString *)lxd_backtraceOfNSThread:(NSThread *)thread;\n\n+ (void)lxd_logMain;\n+ (void)lxd_logCurrent;\n+ (void)lxd_logAllThread;\n\n+ (NSString *)backtraceLogFilePath;\n+ (void)recordLoggerWithFileName: (NSString *)fileName;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/Backtrace/LXDBacktraceLogger.m",
    "content": "//\n//  LXDBacktraceLogger.m\n//  LXDAppFluencyMonitor\n//\n//  Created by linxinda on 2017/3/23.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDBacktraceLogger.h\"\n#import <dlfcn.h>\n#import <limits.h>\n#import <string.h>\n#import <pthread.h>\n#import <sys/types.h>\n#import <mach/mach.h>\n#import <mach-o/nlist.h>\n#import <mach-o/dyld.h>\n\n\n\n\n\n/*!\n *  @brief  适配不同CPU的宏定义\n *\n *  @thx    代码出自https://github.com/bestswifter/BSBacktraceLogger 加工修改\n */\n#if defined(__arm64__)\n#define DETAG_INSTRUCTION_ADDRESS(A) ((A) & ~(3UL))\n#define LXD_THREAD_STATE_COUNT ARM_THREAD_STATE64_COUNT\n#define LXD_THREAD_STATE ARM_THREAD_STATE64\n#define LXD_FRAME_POINTER __fp\n#define LXD_STACK_POINTER __sp\n#define LXD_INSTRUCTION_ADDRESS __pc\n\n#elif defined(__arm__)\n#define DETAG_INSTRUCTION_ADDRESS(A) ((A) & ~(1UL))\n#define LXD_THREAD_STATE_COUNT ARM_THREAD_STATE_COUNT\n#define LXD_THREAD_STATE ARM_THREAD_STATE\n#define LXD_FRAME_POINTER __r[7]\n#define LXD_STACK_POINTER __sp\n#define LXD_INSTRUCTION_ADDRESS __pc\n\n#elif defined(__x86_64__)\n#define DETAG_INSTRUCTION_ADDRESS(A) (A)\n#define LXD_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT\n#define LXD_THREAD_STATE x86_THREAD_STATE64\n#define LXD_FRAME_POINTER __rbp\n#define LXD_STACK_POINTER __rsp\n#define LXD_INSTRUCTION_ADDRESS __rip\n\n#elif defined(__i386__)\n#define DETAG_INSTRUCTION_ADDRESS(A) (A)\n#define LXD_THREAD_STATE_COUNT x86_THREAD_STATE32_COUNT\n#define LXD_THREAD_STATE x86_THREAD_STATE32\n#define LXD_FRAME_POINTER __ebp\n#define LXD_STACK_POINTER __esp\n#define LXD_INSTRUCTION_ADDRESS __eip\n\n#endif\n\n#if defined(__LP64__)\n#define TRACE_FMT         \"%-4d%-31s 0x%016lx %s + %lu\"\n#define POINTER_FMT       \"0x%016lx\"\n#define POINTER_SHORT_FMT \"0x%lx\"\n#define LXD_NLIST struct nlist_64\n#else\n#define TRACE_FMT         \"%-4d%-31s 0x%08lx %s + %lu\"\n#define POINTER_FMT       \"0x%08lx\"\n#define POINTER_SHORT_FMT \"0x%lx\"\n#define LXD_NLIST struct nlist\n\n#endif\n\n#define MAX_FRAME_NUMBER 30\n#define LOG_SEPERATE printf(\"\\n\");\n#define FAILED_UINT_PTR_ADDRESS 0\n#define CALL_INSTRUCTION_FROM_RETURN_ADDRESS(A) (DETAG_INSTRUCTION_ADDRESS((A)) - 1)\n\n\ntypedef struct LXDStackFrameEntry{\n    const struct LXDStackFrameEntry * const previous;\n    const uintptr_t return_address;\n} LXDStackFrameEntry;\n\nstatic mach_port_t main_thread_id;\n\nstatic inline dispatch_queue_t lxd_log_IO_queue() {\n    static dispatch_queue_t lxd_log_IO_queue;\n    static dispatch_once_t once;\n    dispatch_once(&once, ^{\n        lxd_log_IO_queue = dispatch_queue_create(\"com.sindrilin.lxd_log_IO_queue\", NULL);\n    });\n    return lxd_log_IO_queue;\n}\n\n\n\n@implementation LXDBacktraceLogger\n\n+ (void)load {\n    main_thread_id = mach_thread_self();\n}\n\n\n#pragma mark - Public\n+ (NSString *)lxd_backtraceOfAllThread {\n    thread_act_array_t threads;\n    mach_msg_type_number_t thread_count = 0;\n    \n    kern_return_t kr = task_threads(mach_task_self(), &threads, &thread_count);\n    if (kr != KERN_SUCCESS) {\n        return @\"Failed to get information of all threads\";\n    }\n    NSMutableString * result = @\"\".mutableCopy;\n    for (int idx = 0; idx < thread_count; idx++) {\n        [result appendString: _lxd_backtraceOfThread(threads[idx])];\n    }\n    return result.copy;\n}\n\n+ (NSString *)lxd_backtraceOfMainThread {\n    return [self lxd_backtraceOfNSThread: [NSThread mainThread]];\n}\n\n+ (NSString *)lxd_backtraceOfCurrentThread {\n    return [self lxd_backtraceOfNSThread: [NSThread currentThread]];\n}\n\n+ (NSString *)lxd_backtraceOfNSThread:(NSThread *)thread {\n    return _lxd_backtraceOfThread(lxd_machThreadFromNSThread(thread));\n}\n\n+ (void)lxd_logMain {\n    LOG_SEPERATE\n    NSLog(@\"%@\", [self lxd_backtraceOfMainThread]);\n    LOG_SEPERATE\n}\n\n+ (void)lxd_logCurrent {\n    LOG_SEPERATE\n    NSLog(@\"%@\", [self lxd_backtraceOfCurrentThread]);\n    LOG_SEPERATE\n}\n\n+ (void)lxd_logAllThread {\n    LOG_SEPERATE\n    NSLog(@\"%@\", [self lxd_backtraceOfAllThread]);\n    LOG_SEPERATE\n}\n\n\n#pragma mark - Generate\nthread_t lxd_machThreadFromNSThread(NSThread * nsthread) {\n    char name[256];\n    thread_act_array_t list;\n    mach_msg_type_number_t count;\n    task_threads(mach_task_self(), &list, &count);\n    \n    NSTimeInterval timeStamp = [[NSDate date] timeIntervalSince1970];\n    NSString * originName = nsthread.name;\n    [nsthread setName: [NSString stringWithFormat: @\"%f\", timeStamp]];\n    \n    if ([nsthread isMainThread]) { return (thread_t)main_thread_id; }\n    \n    for (int idx = 0; idx < count; idx++) {\n        pthread_t pt = pthread_from_mach_thread_np(list[idx]);\n        if ([nsthread isMainThread] && list[idx] == main_thread_id) { return list[idx]; }\n        if (pt) {\n            name[0] = '\\0';\n            pthread_getname_np(pt, name, sizeof(name));\n            if (!strcmp(name, [nsthread name].UTF8String)) {\n                [nsthread setName: originName];\n                return list[idx];\n            }\n        }\n    }\n    [nsthread setName: originName];\n    return mach_thread_self();\n}\n\nNSString * _lxd_backtraceOfThread(thread_t thread) {\n    uintptr_t backtraceBuffer[MAX_FRAME_NUMBER];\n    int idx = 0;\n    NSMutableString * result = [NSString stringWithFormat: @\"Backtrace of Thread %u:\\n======================================================================================\\n\", thread].mutableCopy;\n    \n    _STRUCT_MCONTEXT machineContext;\n    if (!lxd_fillThreadStateIntoMachineContext(thread, &machineContext)) {\n        return [NSString stringWithFormat: @\"Failed to get information abount thread: %u\", thread];\n    }\n    const uintptr_t instructionAddress = lxd_mach_instructionAddress(&machineContext);\n    backtraceBuffer[idx++] = instructionAddress;\n    \n    uintptr_t linkRegister = lxd_mach_linkRegister(&machineContext);\n    if (linkRegister) {\n        backtraceBuffer[idx++] = linkRegister;\n    }\n    if (instructionAddress == FAILED_UINT_PTR_ADDRESS) { return @\"Failed to get instruction address\"; }\n    \n    LXDStackFrameEntry frame = { 0 };\n    const uintptr_t framePtr = lxd_mach_framePointer(&machineContext);\n    if (framePtr == FAILED_UINT_PTR_ADDRESS ||\n        lxd_mach_copyMem((void *)framePtr, &frame, sizeof(frame)) != KERN_SUCCESS) {\n        return @\"failed to get frame pointer\";\n    }\n    \n    for (; idx < MAX_FRAME_NUMBER; idx++) {\n        backtraceBuffer[idx] = frame.return_address;\n        if (backtraceBuffer[idx] == FAILED_UINT_PTR_ADDRESS ||\n            frame.previous == NULL ||\n            lxd_mach_copyMem(frame.previous, &frame, sizeof(frame)) != KERN_SUCCESS) {\n            break;\n        }\n    }\n    \n    int backtraceLength = idx;\n    Dl_info symbolicated[backtraceLength];\n    lxd_symbolicate(backtraceBuffer, symbolicated, backtraceLength, 0);\n    for (int idx = 0; idx < backtraceLength; idx++) {\n        [result appendFormat: @\"%@\", lxd_logBacktraceEntry(idx, backtraceBuffer[idx], &symbolicated[idx])];\n    }\n    [result appendString: @\"\\n\"];\n    [result appendString: @\"======================================================================================\"];\n    return result.copy;\n}\n\n\n#pragma mark - operate machine context\nbool lxd_fillThreadStateIntoMachineContext(thread_t thread, _STRUCT_MCONTEXT * machineContext) {\n    mach_msg_type_number_t state_count = LXD_THREAD_STATE_COUNT;\n    kern_return_t kr = thread_get_state(thread, LXD_THREAD_STATE, (thread_state_t)&machineContext->__ss, &state_count);\n    return (kr == KERN_SUCCESS);\n}\n\nuintptr_t lxd_mach_linkRegister(_STRUCT_MCONTEXT * const machineContext){\n#if defined(__i386__) || defined(__x86_64__)\n    return FAILED_UINT_PTR_ADDRESS;\n#else\n    return machineContext->__ss.__lr;\n#endif\n}\n\nuintptr_t lxd_mach_framePointer(_STRUCT_MCONTEXT * const machineContext) {\n    return machineContext->__ss.LXD_FRAME_POINTER;\n}\n\nuintptr_t lxd_mach_instructionAddress(_STRUCT_MCONTEXT * const machineContext) {\n    return machineContext->__ss.LXD_INSTRUCTION_ADDRESS;\n}\n\nkern_return_t lxd_mach_copyMem(const void * src, const void * dst, const size_t numBytes) {\n    vm_size_t bytesCopied = 0;\n    return vm_read_overwrite(mach_task_self(), (vm_address_t)src, (vm_size_t)numBytes, (vm_address_t)dst, &bytesCopied);\n}\n\n\n#pragma mark - handle symbolicate\nvoid lxd_symbolicate(const uintptr_t * const backtraceBuffer, Dl_info * const symbolsBuffer, const int numEntries, const int skippedEntries) {\n    int idx = 0;\n    if (!skippedEntries && idx < numEntries) {\n        lxd_dladdr(backtraceBuffer[idx], &symbolsBuffer[idx]);\n        idx++;\n    }\n    \n    for (; idx < numEntries; idx++) {\n        lxd_dladdr(CALL_INSTRUCTION_FROM_RETURN_ADDRESS(backtraceBuffer[idx]), &symbolsBuffer[idx]);\n    }\n}\n\nbool lxd_dladdr(const uintptr_t address, Dl_info * const info) {\n    info->dli_fname = NULL;\n    info->dli_fbase = NULL;\n    info->dli_sname = NULL;\n    info->dli_saddr = NULL;\n    \n    const uint32_t idx = lxd_imageIndexContainingAddress(address);\n    if (idx == UINT_MAX) { return false; }\n    \n    const struct mach_header * header = _dyld_get_image_header(idx);\n    const uintptr_t imageVMAddressSlide = (uintptr_t)_dyld_get_image_vmaddr_slide(idx);\n    const uintptr_t addressWithSlide = address - imageVMAddressSlide;\n    const uintptr_t segmentBase = lxd_segmentBaseOfImageIndex(idx) + imageVMAddressSlide;\n    if (segmentBase == FAILED_UINT_PTR_ADDRESS) { return false; }\n    \n    info->dli_fbase = (void *)header;\n    info->dli_fname = _dyld_get_image_name(idx);\n    \n    const LXD_NLIST * bestMatch = NULL;\n    uintptr_t bestDistance = ULONG_MAX;\n    uintptr_t cmdPtr = lxd_firstCmdAfterHeader(header);\n    if (cmdPtr == FAILED_UINT_PTR_ADDRESS) { return false; }\n    \n    for (uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) {\n        const struct load_command * loadCmd = (struct load_command *)cmdPtr;\n        if (loadCmd->cmd == LC_SYMTAB) {\n            const struct symtab_command * symtabCmd = (struct symtab_command *)cmdPtr;\n            const LXD_NLIST * symbolTable = (LXD_NLIST *)(segmentBase + symtabCmd->symoff);\n            const uintptr_t stringTable = segmentBase + symtabCmd->stroff;\n            \n            for (uint32_t iSym = 0; iSym < symtabCmd->nsyms; iSym++) {\n                if (symbolTable[iSym].n_value == FAILED_UINT_PTR_ADDRESS) { continue; }\n                uintptr_t symbolBase = symbolTable[iSym].n_value;\n                uintptr_t currentDistance = addressWithSlide - symbolBase;\n                if ( (addressWithSlide >= symbolBase && currentDistance <= bestDistance) ) {\n                    bestMatch = symbolTable + iSym;\n                    bestDistance = currentDistance;\n                }\n            }\n            if (bestMatch != NULL) {\n                info->dli_saddr = (void *)(bestMatch->n_value + imageVMAddressSlide);\n                info->dli_sname = (char *)((intptr_t)stringTable + (intptr_t)bestMatch->n_un.n_strx);\n                if (*info->dli_sname == '_') {\n                    info->dli_sname++;\n                }\n                if (info->dli_saddr == info->dli_fbase && bestMatch->n_type == 3) {\n                    info->dli_sname = NULL;\n                }\n                break;\n            }\n        }\n        cmdPtr += loadCmd->cmdsize;\n    }\n    return true;\n}\n\nuintptr_t lxd_firstCmdAfterHeader(const struct mach_header * const header) {\n    switch (header->magic) {\n        case MH_MAGIC:\n        case MH_CIGAM:\n            return (uintptr_t)(header + 1);\n        case MH_MAGIC_64:\n        case MH_CIGAM_64:\n            return (uintptr_t)(((struct mach_header_64*)header) + 1);\n        default:\n            return 0;\n    }\n}\n\nuintptr_t lxd_segmentBaseOfImageIndex(const uint32_t idx) {\n    const struct mach_header * header = _dyld_get_image_header(idx);\n    \n    uintptr_t cmdPtr = lxd_firstCmdAfterHeader(header);\n    if (cmdPtr == FAILED_UINT_PTR_ADDRESS) { return FAILED_UINT_PTR_ADDRESS; }\n    for (uint32_t idx = 0; idx < header->ncmds; idx++) {\n        const struct load_command * loadCmd = (struct load_command *)cmdPtr;\n        if (loadCmd->cmd == LC_SEGMENT) {\n            const struct segment_command * segCmd = (struct segment_command *)cmdPtr;\n            if (strcmp(segCmd->segname, SEG_LINKEDIT) == 0) {\n                return segCmd->vmaddr - segCmd->fileoff;\n            }\n        } else if (loadCmd->cmd == LC_SEGMENT_64) {\n            const struct segment_command_64 * segCmd = (struct segment_command_64 *)cmdPtr;\n            if (strcmp(segCmd->segname, SEG_LINKEDIT) == 0) {\n                return (uintptr_t)(segCmd->vmaddr - segCmd->fileoff);\n            }\n        }\n        cmdPtr += loadCmd->cmdsize;\n    }\n    return FAILED_UINT_PTR_ADDRESS;\n}\n\nuint32_t lxd_imageIndexContainingAddress(const uintptr_t address) {\n    const uint32_t imageCount = _dyld_image_count();\n    const struct mach_header * header = FAILED_UINT_PTR_ADDRESS;\n    \n    for (uint32_t iImg = 0; iImg < imageCount; iImg++) {\n        header = _dyld_get_image_header(iImg);\n        if (header != NULL) {\n            uintptr_t addressWSlide = address - (uintptr_t)_dyld_get_image_vmaddr_slide(iImg);\n            uintptr_t cmdPtr = lxd_firstCmdAfterHeader(header);\n            if (cmdPtr == FAILED_UINT_PTR_ADDRESS) { continue; }\n            \n            for (uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) {\n                const struct load_command * loadCmd = (struct load_command *)cmdPtr;\n                if (loadCmd->cmd == LC_SEGMENT) {\n                    const struct segment_command * segCmd = (struct segment_command *)cmdPtr;\n                    if (addressWSlide >= segCmd->vmaddr &&\n                        addressWSlide < segCmd->vmaddr + segCmd->vmsize) {\n                        return iImg;\n                    }\n                } else if (loadCmd->cmd == LC_SEGMENT_64) {\n                    const struct segment_command_64 * segCmd = (struct segment_command_64 *)cmdPtr;\n                    if (addressWSlide >= segCmd->vmaddr &&\n                        addressWSlide < segCmd->vmaddr + segCmd->vmsize) {\n                        return iImg;\n                    }\n                }\n                cmdPtr += loadCmd->cmdsize;\n            }\n        }\n    }\n    return UINT_MAX;\n}\n\n\n#pragma mark - generate backtrace entry\nconst char * lxd_lastPathEntry(const char * const path) {\n    if (path == NULL) { return NULL; }\n    char * lastFile = strrchr(path, '/');\n    return lastFile == NULL ? path: lastFile + 1;\n}\n\nNSString * lxd_logBacktraceEntry(const int entryNum, const uintptr_t address, const Dl_info * const dlInfo) {\n    char faddrBuffer[20];\n    char saddrBuffer[20];\n    \n    const char * fname = lxd_lastPathEntry(dlInfo->dli_fname);\n    if (fname == NULL) {\n        sprintf(faddrBuffer, POINTER_FMT, (uintptr_t)dlInfo->dli_fbase);\n        fname = faddrBuffer;\n    }\n    \n    uintptr_t offset = address - (uintptr_t)dlInfo->dli_saddr;\n    const char * sname = dlInfo->dli_sname;\n    if (sname == NULL) {\n        sprintf(saddrBuffer, POINTER_SHORT_FMT, (uintptr_t)dlInfo->dli_fbase);\n        sname = saddrBuffer;\n        offset = address - (uintptr_t)dlInfo->dli_fbase;\n    }\n    return [NSString stringWithFormat: @\"%-30s 0x%08\" PRIxPTR \" %s + %lu\\n\", fname, (uintptr_t)address, sname, offset];\n}\n\n+ (NSString *)backtraceLogFilePath {\n    static NSString * const fileDirectoryName = @\"lxd_backtrace\";\n    NSString * filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent: fileDirectoryName];\n    NSFileManager * manager = [NSFileManager defaultManager];\n    if (![manager fileExistsAtPath: filePath]) {\n        [manager createDirectoryAtPath: filePath withIntermediateDirectories: YES attributes: nil error: nil];\n    }\n    return filePath;\n}\n\n+ (void)recordLoggerWithFileName: (NSString *)fileName {\n    NSParameterAssert(fileName);\n    dispatch_async(lxd_log_IO_queue(), ^{\n        NSDateFormatter * formatter = [NSDateFormatter new];\n        formatter.dateFormat = @\"mmssS\";\n        NSString * filePath = [[self backtraceLogFilePath] stringByAppendingString: [formatter stringFromDate: [NSDate date]]];\n        NSString * backtraceStackInfo = [self lxd_backtraceOfMainThread];\n        [backtraceStackInfo writeToFile: filePath atomically: YES encoding: NSUTF8StringEncoding error: nil];\n    });\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/Dispatch/LXDDispatchAsync.h",
    "content": "//\n//  LXDDispatchQueuePool.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/2.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n\ntypedef NS_ENUM(NSInteger, LXDQualityOfService) {\n    LXDQualityOfServiceUserInteractive = NSQualityOfServiceUserInteractive,\n    LXDQualityOfServiceUserInitiated = NSQualityOfServiceUserInitiated,\n    LXDQualityOfServiceUtility = NSQualityOfServiceUtility,\n    LXDQualityOfServiceBackground = NSQualityOfServiceBackground,\n    LXDQualityOfServiceDefault = NSQualityOfServiceDefault,\n};\n\n\ndispatch_queue_t LXDDispatchQueueAsyncBlockInQOS(LXDQualityOfService qos, dispatch_block_t block);\ndispatch_queue_t LXDDispatchQueueAsyncBlockInUserInteractive(dispatch_block_t block);\ndispatch_queue_t LXDDispatchQueueAsyncBlockInUserInitiated(dispatch_block_t block);\ndispatch_queue_t LXDDispatchQueueAsyncBlockInBackground(dispatch_block_t block);\ndispatch_queue_t LXDDispatchQueueAsyncBlockInDefault(dispatch_block_t block);\ndispatch_queue_t LXDDispatchQueueAsyncBlockInUtility(dispatch_block_t block);\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/Dispatch/LXDDispatchAsync.m",
    "content": "//\n//  LXDDispatchQueuePool.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/2.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDDispatchAsync.h\"\n#import <libkern/OSAtomic.h>\n\n\n#ifndef LXDDispatchAsync_m\n#define LXDDispatchAsync_m\n#endif\n\n#define LXD_INLINE static inline\n#define LXD_QUEUE_MAX_COUNT 32\n\n\ntypedef struct __LXDDispatchContext {\n    const char * name;\n    void ** queues;\n    uint32_t queueCount;\n    int32_t offset;\n} *DispatchContext, LXDDispatchContext;\n\n\nLXD_INLINE dispatch_queue_priority_t __LXDQualityOfServiceToDispatchPriority(LXDQualityOfService qos) {\n    switch (qos) {\n        case LXDQualityOfServiceUserInteractive: return DISPATCH_QUEUE_PRIORITY_HIGH;\n        case LXDQualityOfServiceUserInitiated: return DISPATCH_QUEUE_PRIORITY_HIGH;\n        case LXDQualityOfServiceUtility: return DISPATCH_QUEUE_PRIORITY_LOW;\n        case LXDQualityOfServiceBackground: return DISPATCH_QUEUE_PRIORITY_BACKGROUND;\n        case LXDQualityOfServiceDefault: return DISPATCH_QUEUE_PRIORITY_DEFAULT;\n        default: return DISPATCH_QUEUE_PRIORITY_DEFAULT;\n    }\n}\n\nLXD_INLINE qos_class_t __LXDQualityOfServiceToQOSClass(LXDQualityOfService qos) {\n    switch (qos) {\n        case LXDQualityOfServiceUserInteractive: return QOS_CLASS_USER_INTERACTIVE;\n        case LXDQualityOfServiceUserInitiated: return QOS_CLASS_USER_INITIATED;\n        case LXDQualityOfServiceUtility: return QOS_CLASS_UTILITY;\n        case LXDQualityOfServiceBackground: return QOS_CLASS_BACKGROUND;\n        case LXDQualityOfServiceDefault: return QOS_CLASS_DEFAULT;\n        default: return QOS_CLASS_UNSPECIFIED;\n    }\n}\n\nLXD_INLINE dispatch_queue_attr_t __LXDQoSToQueueAttributes(LXDQualityOfService qos) {\n    dispatch_qos_class_t qosClass = __LXDQualityOfServiceToQOSClass(qos);\n    return dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, qosClass, 0);\n};\n\nLXD_INLINE dispatch_queue_t __LXDQualityOfServiceToDispatchQueue(LXDQualityOfService qos, const char * queueName) {\n    if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) {\n        dispatch_queue_attr_t attr = __LXDQoSToQueueAttributes(qos);\n        return dispatch_queue_create(queueName, attr);\n    } else {\n        dispatch_queue_t queue = dispatch_queue_create(queueName, DISPATCH_QUEUE_SERIAL);\n        dispatch_set_target_queue(queue, dispatch_get_global_queue(__LXDQualityOfServiceToDispatchPriority(qos), 0));\n        return queue;\n    }\n}\n\nLXD_INLINE DispatchContext __LXDDispatchContextCreate(const char * name,\n                                                      uint32_t queueCount,\n                                                      LXDQualityOfService qos) {\n    DispatchContext context = calloc(1, sizeof(LXDDispatchContext));\n    if (context == NULL) { return NULL; }\n    \n    context->queues = calloc(queueCount, sizeof(void *));\n    if (context->queues == NULL) {\n        free(context);\n        return NULL;\n    }\n    for (int idx = 0; idx < queueCount; idx++) {\n        context->queues[idx] = (__bridge_retained void *)__LXDQualityOfServiceToDispatchQueue(qos, name);\n    }\n    context->queueCount = queueCount;\n    if (name) {\n        context->name = strdup(name);\n    }\n    context->offset = 0;\n    return context;\n}\n\nLXD_INLINE void __LXDDispatchContextRelease(DispatchContext context) {\n    if (context == NULL) { return; }\n    if (context->queues != NULL) { free(context->queues);  }\n    if (context->name != NULL) { free((void *)context->name); }\n    context->queues = NULL;\n    if (context) { free(context); }\n}\n\nLXD_INLINE dispatch_semaphore_t __LXDSemaphore() {\n    static dispatch_semaphore_t semaphore;\n    static dispatch_once_t once;\n    dispatch_once(&once, ^{\n        semaphore = dispatch_semaphore_create(0);\n    });\n    return semaphore;\n}\n\nLXD_INLINE dispatch_queue_t __LXDDispatchContextGetQueue(DispatchContext context) {\n    dispatch_semaphore_wait(__LXDSemaphore(), dispatch_time(DISPATCH_TIME_NOW, DISPATCH_TIME_FOREVER));\n    uint32_t offset = (uint32_t)OSAtomicIncrement32(&context->offset);\n    dispatch_queue_t queue = (__bridge dispatch_queue_t)context->queues[offset % context->queueCount];\n    dispatch_semaphore_signal(__LXDSemaphore());\n    if (queue) { return queue; }\n    return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);\n}\n\nLXD_INLINE DispatchContext __LXDDispatchContextGetForQos(LXDQualityOfService qos) {\n    static DispatchContext contexts[5];\n    int count = (int)[NSProcessInfo processInfo].activeProcessorCount;\n    count = MIN(1, MAX(count, LXD_QUEUE_MAX_COUNT));\n    switch (qos) {\n        case LXDQualityOfServiceUserInteractive: {\n            static dispatch_once_t once;\n            dispatch_once(&once, ^{\n                contexts[0] = __LXDDispatchContextCreate(\"com.sindrilin.user_interactive\", count, qos);\n            });\n            return contexts[0];\n        }\n            \n        case LXDQualityOfServiceUserInitiated: {\n            static dispatch_once_t once;\n            dispatch_once(&once, ^{\n                contexts[1] = __LXDDispatchContextCreate(\"com.sindrilin.user_initated\", count, qos);\n            });\n            return contexts[1];\n        }\n            \n        case LXDQualityOfServiceUtility: {\n            static dispatch_once_t once;\n            dispatch_once(&once, ^{\n                contexts[2] = __LXDDispatchContextCreate(\"com.sindrilin.utility\", count, qos);\n            });\n            return contexts[2];\n        }\n            \n        case LXDQualityOfServiceBackground: {\n            static dispatch_once_t once;\n            dispatch_once(&once, ^{\n                contexts[3] = __LXDDispatchContextCreate(\"com.sindrilin.background\", count, qos);\n            });\n            return contexts[3];\n        }\n            \n        case LXDQualityOfServiceDefault:\n        default: {\n            static dispatch_once_t once;\n            dispatch_once(&once, ^{\n                contexts[4] = __LXDDispatchContextCreate(\"com.sindrilin.default\", count, qos);\n            });\n            return contexts[4];\n        }\n    }\n}\n\ndispatch_queue_t LXDDispatchQueueAsyncBlockInQOS(LXDQualityOfService qos, dispatch_block_t block) {\n    if (block == nil) { return NULL; }\n    DispatchContext context = __LXDDispatchContextGetForQos(qos);\n    dispatch_queue_t queue = __LXDDispatchContextGetQueue(context);\n    dispatch_async(queue, block);\n    return queue;\n}\n\ndispatch_queue_t LXDDispatchQueueAsyncBlockInUserInteractive(dispatch_block_t block) {\n    return LXDDispatchQueueAsyncBlockInQOS(LXDQualityOfServiceUserInteractive, block);\n}\n\ndispatch_queue_t LXDDispatchQueueAsyncBlockInUserInitiated(dispatch_block_t block) {\n    return LXDDispatchQueueAsyncBlockInQOS(LXDQualityOfServiceUserInitiated, block);\n}\n\ndispatch_queue_t LXDDispatchQueueAsyncBlockInUtility(dispatch_block_t block) {\n    return LXDDispatchQueueAsyncBlockInQOS(LXDQualityOfServiceUtility, block);\n}\n\ndispatch_queue_t LXDDispatchQueueAsyncBlockInBackground(dispatch_block_t block) {\n    return LXDDispatchQueueAsyncBlockInQOS(LXDQualityOfServiceBackground, block);\n}\n\ndispatch_queue_t LXDDispatchQueueAsyncBlockInDefault(dispatch_block_t block) {\n    return LXDDispatchQueueAsyncBlockInQOS(LXDQualityOfServiceDefault, block);\n}\n\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/Dispatch/LXDDispatchOperation.h",
    "content": "//\n//  LXDDispatchOperation.h\n//  LXDDispatchOperation\n//\n//  Created by linxinda on 2017/4/6.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n@class LXDDispatchOperation;\ntypedef void(^LXDCancelableBlock)(LXDDispatchOperation * operation);\n\n\n/*!\n *  @brief  派发任务封装\n */\n@interface LXDDispatchOperation : NSObject\n\n@property (nonatomic, readonly) BOOL isCanceled;\n@property (nonatomic, readonly) dispatch_queue_t queue;\n\n+ (instancetype)dispatchOperationWithBlock: (dispatch_block_t)block;\n+ (instancetype)dispatchOperationWithBlock: (dispatch_block_t)block inQoS: (NSQualityOfService)qos;\n\n+ (instancetype)dispatchOperationWithCancelableBlock:(LXDCancelableBlock)block;\n+ (instancetype)dispatchOperationWithCancelableBlock:(LXDCancelableBlock)block inQos: (NSQualityOfService)qos;\n\n- (void)start;\n- (void)cancel;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/Dispatch/LXDDispatchOperation.m",
    "content": "//\n//  LXDDispatchOperation.m\n//  LXDDispatchOperation\n//\n//  Created by linxinda on 2017/4/6.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDDispatchOperation.h\"\n#import \"LXDDispatchAsync.h\"\n\n\n#ifndef LXDDispatchAsync_m\n#define LXD_INLINE static inline\n#endif\n\n#define LXD_FUNCTION_OVERLOAD __attribute__((overloadable))\n\n\nLXD_INLINE LXD_FUNCTION_OVERLOAD void __LXDLockExecute(dispatch_block_t block, dispatch_time_t threshold);\n\nLXD_INLINE LXD_FUNCTION_OVERLOAD void __LXDLockExecute(dispatch_block_t block) {\n    __LXDLockExecute(block, dispatch_time(DISPATCH_TIME_NOW, DISPATCH_TIME_FOREVER));\n}\n\nLXD_INLINE LXD_FUNCTION_OVERLOAD void __LXDLockExecute(dispatch_block_t block, dispatch_time_t threshold) {\n    if (block == nil) { return ; }\n    static dispatch_semaphore_t lxd_queue_semaphore;\n    static dispatch_once_t once;\n    dispatch_once(&once, ^{\n        lxd_queue_semaphore = dispatch_semaphore_create(0);\n    });\n    dispatch_semaphore_wait(lxd_queue_semaphore, threshold);\n    block();\n    dispatch_semaphore_signal(lxd_queue_semaphore);\n}\n\n\n@interface LXDDispatchOperation ()\n\n@property (nonatomic, assign) BOOL isCanceled;\n@property (nonatomic, assign) BOOL isExcuting;\n@property (nonatomic, assign) dispatch_queue_t queue;\n@property (nonatomic, assign) dispatch_queue_t (*asyn)(dispatch_block_t);\n@property (nonatomic, copy) LXDCancelableBlock cancelableBlock;\n\n@end\n\n\n@implementation LXDDispatchOperation\n\n\n+ (instancetype)dispatchOperationWithBlock: (dispatch_block_t)block {\n    return [self dispatchOperationWithCancelableBlock: ^(LXDDispatchOperation *operation) {\n        if (!operation.isCanceled) {\n            block();\n        }\n    } inQos: NSQualityOfServiceDefault];\n}\n\n+ (instancetype)dispatchOperationWithBlock: (dispatch_block_t)block inQoS: (NSQualityOfService)qos {\n    return [self dispatchOperationWithCancelableBlock: ^(LXDDispatchOperation *operation) {\n        if (!operation.isCanceled) {\n            block();\n        }\n    } inQos: qos];\n}\n\n+ (instancetype)dispatchOperationWithCancelableBlock:(LXDCancelableBlock)block {\n    return [self dispatchOperationWithCancelableBlock: block inQos: NSQualityOfServiceDefault];\n}\n\n+ (instancetype)dispatchOperationWithCancelableBlock:(LXDCancelableBlock)block inQos: (NSQualityOfService)qos {\n    return [[self alloc] initWithBlock: block inQos: qos];\n}\n\n- (instancetype)initWithBlock: (LXDCancelableBlock)block inQos: (NSQualityOfService)qos {\n    if (block == nil) { return nil; }\n    if (self = [super init]) {\n        switch (qos) {\n            case NSQualityOfServiceUserInteractive:\n                self.asyn = LXDDispatchQueueAsyncBlockInUserInteractive;\n                break;\n            case NSQualityOfServiceUserInitiated:\n                self.asyn = LXDDispatchQueueAsyncBlockInUserInitiated;\n                break;\n            case NSQualityOfServiceDefault:\n                self.asyn = LXDDispatchQueueAsyncBlockInDefault;\n                break;\n            case NSQualityOfServiceUtility:\n                self.asyn = LXDDispatchQueueAsyncBlockInUtility;\n                break;\n            case NSQualityOfServiceBackground:\n                self.asyn = LXDDispatchQueueAsyncBlockInBackground;\n                break;\n            default:\n                self.asyn = LXDDispatchQueueAsyncBlockInDefault;\n                break;\n        }\n        self.cancelableBlock = block;\n    }\n    return self;\n}\n\n- (void)dealloc {\n    [self cancel];\n}\n\n- (void)start {\n    __LXDLockExecute(^{\n        self.queue = self.asyn(^{\n            self.cancelableBlock(self);\n            self.cancelableBlock = nil;\n        });\n        self.isExcuting = YES;\n    });\n}\n\n- (void)cancel {\n    __LXDLockExecute(^{\n        self.isCanceled = YES;\n        if (!self.isExcuting) {\n            self.asyn = NULL;\n            self.cancelableBlock = nil;\n        }\n    });\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/Performance/LXDTransaction.h",
    "content": "//\n//  LXDTransaction.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/5/2.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n/*!\n *  @brief  任务封装\n */\n@interface LXDTransaction : NSObject\n\n+ (void)begin;\n+ (void)commit;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/Performance/LXDTransaction.m",
    "content": "//\n//  LXDTransaction.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/5/2.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDTransaction.h\"\n#import <sys/time.h>\n\n\n\n#define TRANSACTION_LOCK(__lock) dispatch_wait(__lock, DISPATCH_TIME_FOREVER)\n#define TRANSACTION_UNLOCK(__lock) dispatch_semaphore_signal(__lock);\n\n\n\n#pragma mark - Task Queue\n@interface LXDExecuteTaskQueue : NSObject\n@end\n\n\n@implementation LXDExecuteTaskQueue\n\n\nstatic inline CFMutableArrayRef _lxd_execute_task_queue() {\n    static CFMutableArrayRef lxd_execute_task_queue;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        lxd_execute_task_queue = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);\n    });\n    return lxd_execute_task_queue;\n}\n\nstatic inline dispatch_semaphore_t _lxd_excute_task_queue_lock() {\n    static dispatch_semaphore_t lxd_transaction_queue_lock;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        lxd_transaction_queue_lock = dispatch_semaphore_create(1);\n    });\n    return lxd_transaction_queue_lock;\n}\n\n+ (dispatch_block_t)fetchExecuteTask {\n    if (CFArrayGetCount(_lxd_execute_task_queue()) == 0) { return nil; }\n    TRANSACTION_LOCK(_lxd_excute_task_queue_lock());\n    dispatch_block_t executeTask = CFArrayGetValueAtIndex(_lxd_execute_task_queue(), 0);\n    CFArrayRemoveValueAtIndex(_lxd_execute_task_queue(), 0);\n    TRANSACTION_UNLOCK(_lxd_excute_task_queue_lock());\n    return executeTask;\n}\n\n+ (void)insertExecuteTask: (dispatch_block_t)block {\n    assert(block != nil);\n    TRANSACTION_LOCK(_lxd_excute_task_queue_lock());\n    CFArrayAppendValue(_lxd_execute_task_queue(), (__bridge void *)[block copy]);\n    TRANSACTION_UNLOCK(_lxd_excute_task_queue_lock());\n}\n\n\n@end\n\n\n\n\n#pragma mark - RunLoop Observer\nstatic struct timeval lxd_free_loop_entry_time;\nstatic inline bool _lxd_calculate_time_interval_valid(struct timeval start, struct timeval end) {\n    static long lxd_max_loop_time = NSEC_PER_SEC / 60 * 0.8;\n    long time_interval = (end.tv_sec - start.tv_sec) * NSEC_PER_SEC + (end.tv_usec - start.tv_usec);\n    return time_interval < lxd_max_loop_time;\n}\n\nstatic void _lxd_run_loop_free_time_observer(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void * info) {\n    gettimeofday(&lxd_free_loop_entry_time, NULL);\n}\n\nstatic void _lxd_transaction_run_loop_observer(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void * info) {\n    struct timeval current_time;\n    dispatch_block_t executeTask;\n    \n    do {\n        executeTask = [LXDExecuteTaskQueue fetchExecuteTask];\n        if (executeTask != nil) { executeTask(); }\n        else { break; }\n        gettimeofday(&current_time, NULL);\n    } while( _lxd_calculate_time_interval_valid(lxd_free_loop_entry_time, current_time) );\n}\n\n\n\n#pragma mark - Transaction\n@implementation LXDTransaction\n\n\nstatic bool lxd_transaction_flag = false;\nstatic inline dispatch_semaphore_t _lxd_transaction_lock() {\n    static dispatch_semaphore_t lxd_transaction_lock;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        lxd_transaction_lock = dispatch_semaphore_create(1);\n    });\n    return lxd_transaction_lock;\n}\n\n+ (void)load {\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        CFRunLoopRef runloop = CFRunLoopGetMain();\n        CFRunLoopObserverRef observer;\n        \n        observer = CFRunLoopObserverCreate(CFAllocatorGetDefault(),\n                                           kCFRunLoopBeforeWaiting | kCFRunLoopExit,\n                                           true, 0x0,\n                                           _lxd_run_loop_free_time_observer, NULL);\n        CFRunLoopAddObserver(runloop, observer, kCFRunLoopCommonModes);\n        CFRelease(observer);\n        \n        observer = CFRunLoopObserverCreate(CFAllocatorGetDefault(),\n                                           kCFRunLoopBeforeWaiting | kCFRunLoopExit,\n                                           true,\n                                           0xFFFFFF,\n                                           _lxd_transaction_run_loop_observer, NULL);\n        CFRunLoopAddObserver(runloop, observer, kCFRunLoopCommonModes);\n        CFRelease(observer);\n    });\n}\n\n+ (void)begin {\n    if (lxd_transaction_flag) { return; }\n    TRANSACTION_LOCK(_lxd_transaction_lock());\n    lxd_transaction_flag = true;\n    TRANSACTION_UNLOCK(_lxd_transaction_lock());\n}\n\n+ (void)commit {\n    if (!lxd_transaction_flag) { return; }\n    TRANSACTION_LOCK(_lxd_transaction_lock());\n    lxd_transaction_flag = false;\n    TRANSACTION_UNLOCK(_lxd_transaction_lock());\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/Timer/LXDGlobalTimer.h",
    "content": "//\n//  LXDGlobalTimer.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/27.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <Foundation/Foundation.h>\n\n/*!\n *  @brief  全局倒计时\n */\n@interface LXDGlobalTimer : NSObject\n\n/*!\n *  @brief  注册定时器回调处理，返回时间戳作为key\n */\n+ (NSString *)registerTimerCallback: (dispatch_block_t)callback;\n\n/*!\n *  @brief  注册定时器回调处理\n */\n+ (void)registerTimerCallback: (dispatch_block_t)callback key: (NSString *)key;\n\n/*!\n *  @brief  取消定时器注册\n */\n+ (void)resignTimerCallbackWithKey: (NSString *)key;\n\n/*!\n *  @brief  设置定时器间隔，默认为2\n */\n+ (void)setCallbackInterval: (NSUInteger)interval;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/Timer/LXDGlobalTimer.m",
    "content": "//\n//  LXDGlobalTimer.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/27.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDGlobalTimer.h\"\n#import \"LXDDispatchAsync.h\"\n\n\nstatic NSUInteger lxd_timer_time_interval = 2;\nstatic dispatch_source_t lxd_global_timer = NULL;\nstatic CFMutableDictionaryRef lxd_global_callbacks = NULL;\n\n\n@implementation LXDGlobalTimer\n\n\nCF_INLINE void __LXDSyncExecute(dispatch_block_t block) {\n    LXDDispatchQueueAsyncBlockInBackground(^{\n        assert(block != nil);\n        block();\n    });\n}\n\nCF_INLINE void __LXDInitGlobalCallbacks() {\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        lxd_global_callbacks = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);\n    });\n}\n\nCF_INLINE void __LXDResetTimer() {\n    if (lxd_global_timer != NULL) {\n        dispatch_source_cancel(lxd_global_timer);\n    }\n    lxd_global_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, LXDDispatchQueueAsyncBlockInDefault(^{}));\n    dispatch_source_set_timer(lxd_global_timer, DISPATCH_TIME_NOW, lxd_timer_time_interval * NSEC_PER_SEC, 0);\n    dispatch_source_set_event_handler(lxd_global_timer, ^{\n        NSUInteger count = CFDictionaryGetCount(lxd_global_callbacks);\n        void * callbacks[count];\n        CFDictionaryGetKeysAndValues(lxd_global_callbacks, NULL, (const void **)callbacks);\n        for (uint idx = 0; idx < count; idx++) {\n            dispatch_block_t callback = (__bridge dispatch_block_t)callbacks[idx];\n            callback();\n        }\n    });\n}\n\nCF_INLINE void __LXDAutoSwitchTimer() {\n    if (CFDictionaryGetCount(lxd_global_callbacks) > 0) {\n        if (lxd_global_timer == NULL) {\n            __LXDResetTimer();\n            dispatch_resume(lxd_global_timer);\n        }\n    } else {\n        if (lxd_global_timer != NULL) {\n            dispatch_source_cancel(lxd_global_timer);\n            lxd_global_timer = NULL;\n        }\n    }\n}\n\n+ (NSString *)registerTimerCallback: (dispatch_block_t)callback {\n    NSString * key = [NSString stringWithFormat: @\"%.2f\", [[NSDate date] timeIntervalSince1970]];\n    [self registerTimerCallback: callback key: key];\n    return key;\n}\n\n+ (void)registerTimerCallback: (dispatch_block_t)callback key: (NSString *)key {\n    if (!callback) { return; }\n    __LXDInitGlobalCallbacks();\n    __LXDSyncExecute(^{\n        CFDictionarySetValue(lxd_global_callbacks, (__bridge void *)key, (__bridge void *)[callback copy]);\n        __LXDAutoSwitchTimer();\n    });\n}\n\n+ (void)resignTimerCallbackWithKey: (NSString *)key {\n    if (key == nil) { return; }\n    __LXDInitGlobalCallbacks();\n    __LXDSyncExecute(^{\n        CFDictionaryRemoveValue(lxd_global_callbacks, (__bridge void *)key);\n        __LXDAutoSwitchTimer();\n    });\n}\n\n+ (void)setCallbackInterval: (NSUInteger)interval {\n    if (interval <= 0) { interval = 1; }\n    lxd_timer_time_interval = interval;\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/UI/LXDAsyncLabel.h",
    "content": "//\n//  LXDAsyncLabel.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/27.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n\n/*!\n *  @brief  异步绘制标签栏\n */\n@interface LXDAsyncLabel : UILabel\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/UI/LXDAsyncLabel.m",
    "content": "//\n//  LXDAsyncLabel.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/27.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDAsyncLabel.h\"\n#import \"LXDDispatchAsync.h\"\n#import <CoreText/CoreText.h>\n\n\n@implementation LXDAsyncLabel\n\n\n- (void)setText: (NSString *)text {\n    if ([NSThread isMainThread]) {\n        LXDDispatchQueueAsyncBlockInBackground(^{\n            [self displayAttributedText: [[NSAttributedString alloc] initWithString: text attributes: @{ NSFontAttributeName: self.font, NSForegroundColorAttributeName: self.textColor }]];\n        });\n    } else {\n        [self displayAttributedText: [[NSAttributedString alloc] initWithString: text attributes: @{ NSFontAttributeName: self.font, NSForegroundColorAttributeName: self.textColor }]];\n    }\n}\n\n- (void)setAttributedText: (NSAttributedString *)attributedText {\n    if ([NSThread isMainThread]) {\n        LXDDispatchQueueAsyncBlockInBackground(^{\n            [self displayAttributedText: attributedText];\n        });\n    } else {\n        [self displayAttributedText: attributedText];\n    }\n}\n\n- (void)displayAttributedText: (NSAttributedString *)attributedText {\n    if (attributedText == nil) {\n        attributedText = [NSMutableAttributedString new];\n    } else if ([attributedText isMemberOfClass: [NSAttributedString class]]) {\n        attributedText = attributedText.mutableCopy;\n    }\n    \n    NSMutableParagraphStyle * style = [NSMutableParagraphStyle new];\n    style.alignment = self.textAlignment;\n    [((NSMutableAttributedString *)attributedText) addAttributes: @{ NSParagraphStyleAttributeName: style } range: NSMakeRange(0, attributedText.length)];\n    \n    CGSize size = self.frame.size;\n    size.height += 10;\n    UIGraphicsBeginImageContextWithOptions(size, NO, 0);\n    CGContextRef context = UIGraphicsGetCurrentContext();\n    if (context != NULL) {\n        CGContextSetTextMatrix(context, CGAffineTransformIdentity);\n        CGContextTranslateCTM(context, 0, size.height);\n        CGContextScaleCTM(context, 1, -1);\n        \n        CGSize textSize = [attributedText.string boundingRectWithSize: size options: NSStringDrawingUsesLineFragmentOrigin attributes: @{ NSFontAttributeName: self.font } context: nil].size;\n        textSize.width = ceil(textSize.width);\n        textSize.height = ceil(textSize.height);\n        \n        CGMutablePathRef path = CGPathCreateMutable();\n        CGPathAddRect(path, NULL, CGRectMake((size.width - textSize.width) / 2, 5, textSize.width, textSize.height));\n        CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedText);\n        CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, attributedText.length), path, NULL);\n        CTFrameDraw(frame, context);\n        \n        UIImage * contents = UIGraphicsGetImageFromCurrentImageContext();\n        UIGraphicsEndImageContext();\n        CFRelease(frameSetter);\n        CFRelease(frame);\n        CFRelease(path);\n        dispatch_async(dispatch_get_main_queue(), ^{\n            self.layer.contents = (id)contents.CGImage;\n        });\n    }\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/UI/LXDMonitorUI.h",
    "content": "//\n//  LXDMonitorUI.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/27.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#ifndef LXDMonitorUI_h\n#define LXDMonitorUI_h\n\n#import \"LXDAsyncLabel.h\"\n#import \"LXDTopWindow.h\"\n\n#endif /* LXDMonitorUI_h */\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/UI/LXDTopWindow.h",
    "content": "//\n//  LXDTopWindow.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/27.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n/*!\n *  @brief  非交互的顶部窗口\n */\n@interface LXDTopWindow : UIWindow\n\n+ (instancetype)topWindow;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/UI/LXDTopWindow.m",
    "content": "//\n//  LXDTopWindow.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/27.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"LXDTopWindow.h\"\n\n\nstatic LXDTopWindow * lxd_top_window;\n\n\n\n@implementation LXDTopWindow\n\n\n+ (instancetype)topWindow {\n#if DEBUG\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        lxd_top_window = [[super allocWithZone: NSDefaultMallocZone()] initWithFrame: [UIScreen mainScreen].bounds];\n    });\n#endif\n    return lxd_top_window;\n}\n\n+ (instancetype)allocWithZone: (struct _NSZone *)zone {\n    return [self topWindow];\n}\n\n- (instancetype)copy {\n    return [[self class] topWindow];\n}\n\n- (instancetype)initWithFrame: (CGRect)frame {\n    if (self = [super initWithFrame: frame]) {\n        [super setUserInteractionEnabled: NO];\n        [super setWindowLevel: CGFLOAT_MAX];\n        \n        self.rootViewController = [UIViewController new];\n        [self makeKeyAndVisible];\n    }\n    return self;\n}\n\n- (void)setWindowLevel: (UIWindowLevel)windowLevel { }\n- (void)setBackgroundColor: (UIColor *)backgroundColor { }\n- (void)setUserInteractionEnabled: (BOOL)userInteractionEnabled { }\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/UI/UIApplication+LXDTool.h",
    "content": "//\n//  UIApplication+LXDTool.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/28.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n/*!\n *  @brief  工具类\n */\n@interface UIApplication (LXDTool)\n\n- (UIViewController *)findTopViewController;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/LXDAppMonitor/Tool/UI/UIApplication+LXDTool.m",
    "content": "//\n//  UIApplication+LXDTool.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/4/28.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"UIApplication+LXDTool.h\"\n\n\n@implementation UIApplication (LXDTool)\n\n\nUIViewController * _findViewController(UIViewController * viewController) {\n    if (viewController.presentedViewController != nil) {\n        return _findViewController(viewController.presentedViewController);\n    } else if ([viewController isKindOfClass: [UINavigationController class]]) {\n        return _findViewController(((UINavigationController *)viewController).topViewController);\n    } else if ([viewController isKindOfClass: [UITabBarController class]]) {\n        UITabBarController * tabBarController = (UITabBarController *)viewController;\n        return _findViewController(tabBarController.viewControllers[tabBarController.selectedIndex]);\n    }\n    return viewController;\n}\n\n- (UIViewController *)findTopViewController {\n    UIWindow * window = self.keyWindow;\n    if (self.keyWindow.windowLevel != UIWindowLevelNormal) {\n        for (UIWindow * win in [self windows]) {\n            if (win.windowLevel == UIWindowLevelNormal) {\n                window = win;\n                break;\n            }\n        }\n    }\n    UIView * frontView = [[window subviews] lastObject];\n    UIViewController * viewController;\n    if ([frontView.nextResponder isKindOfClass: [UIViewController class]]) {\n        viewController = (UIViewController *)frontView.nextResponder;\n    } else {\n        viewController = window.rootViewController;\n    }\n    return _findViewController(viewController);\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/ViewController.h",
    "content": "//\n//  ViewController.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/3/29.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n@interface ViewController : UIViewController\n\n\n@end\n\n"
  },
  {
    "path": "LXDAppMonitor/ViewController.m",
    "content": "//\n//  ViewController.m\n//  LXDAppFluencyMonitor\n//\n//  Created by linxinda on 2017/3/22.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"ViewController.h\"\n#import \"LXDFPSMonitor.h\"\n#import \"LXDResourceMonitor.h\"\n\n\n@interface ViewController ()<UITableViewDelegate, UITableViewDataSource>\n\n@property (weak, nonatomic) IBOutlet UITableView *tableView;\n\n@end\n\n@implementation ViewController\n\n\n- (void)viewDidLoad {\n    [super viewDidLoad];\n    [self.tableView registerClass: [UITableViewCell class] forCellReuseIdentifier: @\"cell\"];\n    \n    [FPS_MONITOR startMonitoring];\n    [RESOURCE_MONITOR startMonitoring];\n}\n\n- (void)viewDidAppear: (BOOL)animated {\n    [super viewDidAppear: animated];\n}\n\n\n#pragma mark - UITableViewDataSource\n- (NSInteger)tableView: (UITableView *)tableView numberOfRowsInSection: (NSInteger)section {\n    return 1000;\n}\n\n- (UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {\n    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: @\"cell\"];\n    cell.textLabel.text = [NSString stringWithFormat: @\"%lu\", indexPath.row];\n    if (indexPath.row > 0 && indexPath.row % 30 == 0) {\n        usleep(2000000);\n    }\n    return cell;\n}\n\n\n#pragma mark - UITableViewDelegate\n- (void)tableView: (UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {\n    for (int idx = 0; idx < 100; idx++) {\n        usleep(10000);\n    }\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/WebViewController.h",
    "content": "//\n//  WebViewController.h\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/3/29.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n\n/*!\n *  @brief  网页\n */\n@interface WebViewController : UIViewController\n\n- (instancetype)initWithUrl: (NSString *)url;\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/WebViewController.m",
    "content": "//\n//  WebViewController.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/3/29.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import \"WebViewController.h\"\n#import <WebKit/WebKit.h>\n\n\n@interface WebViewController ()\n\n@property (nonatomic, copy) NSString * url;\n@property (weak, nonatomic) IBOutlet UIWebView *webView;\n\n@end\n\n@implementation WebViewController\n\n- (instancetype)initWithUrl: (NSString *)url {\n    self = [super initWithNibName: NSStringFromClass([self class]) bundle: nil];\n    self.url = url;\n    return self;\n}\n\n#define WEBKITSUPPORT\n\n- (void)viewDidLoad {\n    [super viewDidLoad];\n}\n\n\n@end\n"
  },
  {
    "path": "LXDAppMonitor/WebViewController.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"12118\" systemVersion=\"16E195\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" colorMatched=\"YES\">\n    <device id=\"retina4_7\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"12086\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\" customClass=\"WebViewController\">\n            <connections>\n                <outlet property=\"view\" destination=\"i5M-Pr-FkT\" id=\"sfx-zR-JGt\"/>\n                <outlet property=\"webView\" destination=\"A9R-Ew-fZF\" id=\"uRC-L3-f4K\"/>\n            </connections>\n        </placeholder>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <view clearsContextBeforeDrawing=\"NO\" contentMode=\"scaleToFill\" id=\"i5M-Pr-FkT\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n            <subviews>\n                <webView contentMode=\"scaleToFill\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"A9R-Ew-fZF\">\n                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                    <color key=\"backgroundColor\" red=\"0.36078431370000003\" green=\"0.38823529410000002\" blue=\"0.4039215686\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                </webView>\n            </subviews>\n            <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n            <constraints>\n                <constraint firstItem=\"A9R-Ew-fZF\" firstAttribute=\"leading\" secondItem=\"i5M-Pr-FkT\" secondAttribute=\"leading\" id=\"9e8-m4-oOs\"/>\n                <constraint firstItem=\"A9R-Ew-fZF\" firstAttribute=\"top\" secondItem=\"i5M-Pr-FkT\" secondAttribute=\"top\" id=\"Ssf-OJ-nMi\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"A9R-Ew-fZF\" secondAttribute=\"bottom\" id=\"f5u-eR-ZsM\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"A9R-Ew-fZF\" secondAttribute=\"trailing\" id=\"yvv-cW-Ybq\"/>\n            </constraints>\n        </view>\n    </objects>\n</document>\n"
  },
  {
    "path": "LXDAppMonitor/main.m",
    "content": "//\n//  main.m\n//  LXDAppMonitor\n//\n//  Created by linxinda on 2017/3/29.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <UIKit/UIKit.h>\n#import \"AppDelegate.h\"\n\n\n\nint main(int argc, char * argv[]) {\n    @autoreleasepool {\n        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));\n    }\n}\n"
  },
  {
    "path": "LXDAppMonitor.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\tEF368A901EBC6FA200A629B1 /* LXDCrashLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A4C1EBC6FA200A629B1 /* LXDCrashLogger.m */; };\n\t\tEF368A911EBC6FA200A629B1 /* LXDCrashMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A4E1EBC6FA200A629B1 /* LXDCrashMonitor.m */; };\n\t\tEF368A921EBC6FA200A629B1 /* LXDAppFluencyMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A511EBC6FA200A629B1 /* LXDAppFluencyMonitor.m */; };\n\t\tEF368A931EBC6FA200A629B1 /* LXDFPSDisplayer.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A541EBC6FA200A629B1 /* LXDFPSDisplayer.m */; };\n\t\tEF368A941EBC6FA200A629B1 /* LXDFPSMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A561EBC6FA200A629B1 /* LXDFPSMonitor.m */; };\n\t\tEF368A951EBC6FA200A629B1 /* LXDWeakProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A581EBC6FA200A629B1 /* LXDWeakProxy.m */; };\n\t\tEF368A961EBC6FA200A629B1 /* LXDDNSInterceptor.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A5B1EBC6FA200A629B1 /* LXDDNSInterceptor.m */; };\n\t\tEF368A971EBC6FA200A629B1 /* LXDHostFilterRule.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A5D1EBC6FA200A629B1 /* LXDHostFilterRule.m */; };\n\t\tEF368A981EBC6FA200A629B1 /* LXDHostMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A5F1EBC6FA200A629B1 /* LXDHostMapper.m */; };\n\t\tEF368A991EBC6FA200A629B1 /* NSURLProtocol+WebKitSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A611EBC6FA200A629B1 /* NSURLProtocol+WebKitSupport.m */; };\n\t\tEF368A9A1EBC6FA200A629B1 /* LXDApplicationCPU.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A641EBC6FA200A629B1 /* LXDApplicationCPU.m */; };\n\t\tEF368A9B1EBC6FA200A629B1 /* LXDApplicationMemory.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A661EBC6FA200A629B1 /* LXDApplicationMemory.m */; };\n\t\tEF368A9C1EBC6FA200A629B1 /* LXDCPUDisplayer.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A681EBC6FA200A629B1 /* LXDCPUDisplayer.m */; };\n\t\tEF368A9D1EBC6FA200A629B1 /* LXDMemoryDisplayer.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A6A1EBC6FA200A629B1 /* LXDMemoryDisplayer.m */; };\n\t\tEF368A9E1EBC6FA200A629B1 /* LXDResourceMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A6C1EBC6FA200A629B1 /* LXDResourceMonitor.m */; };\n\t\tEF368A9F1EBC6FA200A629B1 /* LXDSystemCPU.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A6E1EBC6FA200A629B1 /* LXDSystemCPU.m */; };\n\t\tEF368AA01EBC6FA200A629B1 /* LXDSystemMemory.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A701EBC6FA200A629B1 /* LXDSystemMemory.m */; };\n\t\tEF368AA11EBC6FA200A629B1 /* LXDBacktraceLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A741EBC6FA200A629B1 /* LXDBacktraceLogger.m */; };\n\t\tEF368AA21EBC6FA200A629B1 /* LXDDispatchAsync.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A771EBC6FA200A629B1 /* LXDDispatchAsync.m */; };\n\t\tEF368AA31EBC6FA200A629B1 /* LXDDispatchOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A791EBC6FA200A629B1 /* LXDDispatchOperation.m */; };\n\t\tEF368AA91EBC6FA200A629B1 /* LXDGlobalTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A871EBC6FA200A629B1 /* LXDGlobalTimer.m */; };\n\t\tEF368AAA1EBC6FA200A629B1 /* LXDAsyncLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A8A1EBC6FA200A629B1 /* LXDAsyncLabel.m */; };\n\t\tEF368AAB1EBC6FA200A629B1 /* LXDTopWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A8D1EBC6FA200A629B1 /* LXDTopWindow.m */; };\n\t\tEF368AAC1EBC6FA200A629B1 /* UIApplication+LXDTool.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368A8F1EBC6FA200A629B1 /* UIApplication+LXDTool.m */; };\n\t\tEF368AB21EBC6FDE00A629B1 /* LXDTransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = EF368AB11EBC6FDE00A629B1 /* LXDTransaction.m */; };\n\t\tEF82D86E1E8B8E9600DD4776 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = EF82D86D1E8B8E9600DD4776 /* main.m */; };\n\t\tEF82D8711E8B8E9600DD4776 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = EF82D8701E8B8E9600DD4776 /* AppDelegate.m */; };\n\t\tEF82D8741E8B8E9600DD4776 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EF82D8731E8B8E9600DD4776 /* ViewController.m */; };\n\t\tEF82D8771E8B8E9600DD4776 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EF82D8751E8B8E9600DD4776 /* Main.storyboard */; };\n\t\tEF82D8791E8B8E9600DD4776 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EF82D8781E8B8E9600DD4776 /* Assets.xcassets */; };\n\t\tEF82D87C1E8B8E9600DD4776 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EF82D87A1E8B8E9600DD4776 /* LaunchScreen.storyboard */; };\n\t\tEF82D8871E8B8E9600DD4776 /* LXDAppMonitorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = EF82D8861E8B8E9600DD4776 /* LXDAppMonitorTests.m */; };\n\t\tEF82D8921E8B8E9600DD4776 /* LXDAppMonitorUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = EF82D8911E8B8E9600DD4776 /* LXDAppMonitorUITests.m */; };\n\t\tEF82D8C01E8B901000DD4776 /* WebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = EF82D8BE1E8B901000DD4776 /* WebViewController.m */; };\n\t\tEF82D8C11E8B901000DD4776 /* WebViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = EF82D8BF1E8B901000DD4776 /* WebViewController.xib */; };\n\t\tEFF925A01EB2E5B1005D9BEB /* libsqlite3.0.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = EFF9259F1EB2E5B1005D9BEB /* libsqlite3.0.tbd */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\tEF82D8831E8B8E9600DD4776 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = EF82D8611E8B8E9600DD4776 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = EF82D8681E8B8E9600DD4776;\n\t\t\tremoteInfo = LXDAppMonitor;\n\t\t};\n\t\tEF82D88E1E8B8E9600DD4776 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = EF82D8611E8B8E9600DD4776 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = EF82D8681E8B8E9600DD4776;\n\t\t\tremoteInfo = LXDAppMonitor;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXFileReference section */\n\t\tEF368A4B1EBC6FA200A629B1 /* LXDCrashLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDCrashLogger.h; sourceTree = \"<group>\"; };\n\t\tEF368A4C1EBC6FA200A629B1 /* LXDCrashLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDCrashLogger.m; sourceTree = \"<group>\"; };\n\t\tEF368A4D1EBC6FA200A629B1 /* LXDCrashMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDCrashMonitor.h; sourceTree = \"<group>\"; };\n\t\tEF368A4E1EBC6FA200A629B1 /* LXDCrashMonitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDCrashMonitor.m; sourceTree = \"<group>\"; };\n\t\tEF368A501EBC6FA200A629B1 /* LXDAppFluencyMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDAppFluencyMonitor.h; sourceTree = \"<group>\"; };\n\t\tEF368A511EBC6FA200A629B1 /* LXDAppFluencyMonitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDAppFluencyMonitor.m; sourceTree = \"<group>\"; };\n\t\tEF368A531EBC6FA200A629B1 /* LXDFPSDisplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDFPSDisplayer.h; sourceTree = \"<group>\"; };\n\t\tEF368A541EBC6FA200A629B1 /* LXDFPSDisplayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDFPSDisplayer.m; sourceTree = \"<group>\"; };\n\t\tEF368A551EBC6FA200A629B1 /* LXDFPSMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDFPSMonitor.h; sourceTree = \"<group>\"; };\n\t\tEF368A561EBC6FA200A629B1 /* LXDFPSMonitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDFPSMonitor.m; sourceTree = \"<group>\"; };\n\t\tEF368A571EBC6FA200A629B1 /* LXDWeakProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDWeakProxy.h; sourceTree = \"<group>\"; };\n\t\tEF368A581EBC6FA200A629B1 /* LXDWeakProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDWeakProxy.m; sourceTree = \"<group>\"; };\n\t\tEF368A5A1EBC6FA200A629B1 /* LXDDNSInterceptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDDNSInterceptor.h; sourceTree = \"<group>\"; };\n\t\tEF368A5B1EBC6FA200A629B1 /* LXDDNSInterceptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDDNSInterceptor.m; sourceTree = \"<group>\"; };\n\t\tEF368A5C1EBC6FA200A629B1 /* LXDHostFilterRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDHostFilterRule.h; sourceTree = \"<group>\"; };\n\t\tEF368A5D1EBC6FA200A629B1 /* LXDHostFilterRule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDHostFilterRule.m; sourceTree = \"<group>\"; };\n\t\tEF368A5E1EBC6FA200A629B1 /* LXDHostMapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDHostMapper.h; sourceTree = \"<group>\"; };\n\t\tEF368A5F1EBC6FA200A629B1 /* LXDHostMapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDHostMapper.m; sourceTree = \"<group>\"; };\n\t\tEF368A601EBC6FA200A629B1 /* NSURLProtocol+WebKitSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"NSURLProtocol+WebKitSupport.h\"; sourceTree = \"<group>\"; };\n\t\tEF368A611EBC6FA200A629B1 /* NSURLProtocol+WebKitSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"NSURLProtocol+WebKitSupport.m\"; sourceTree = \"<group>\"; };\n\t\tEF368A631EBC6FA200A629B1 /* LXDApplicationCPU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDApplicationCPU.h; sourceTree = \"<group>\"; };\n\t\tEF368A641EBC6FA200A629B1 /* LXDApplicationCPU.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDApplicationCPU.m; sourceTree = \"<group>\"; };\n\t\tEF368A651EBC6FA200A629B1 /* LXDApplicationMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDApplicationMemory.h; sourceTree = \"<group>\"; };\n\t\tEF368A661EBC6FA200A629B1 /* LXDApplicationMemory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDApplicationMemory.m; sourceTree = \"<group>\"; };\n\t\tEF368A671EBC6FA200A629B1 /* LXDCPUDisplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDCPUDisplayer.h; sourceTree = \"<group>\"; };\n\t\tEF368A681EBC6FA200A629B1 /* LXDCPUDisplayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDCPUDisplayer.m; sourceTree = \"<group>\"; };\n\t\tEF368A691EBC6FA200A629B1 /* LXDMemoryDisplayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDMemoryDisplayer.h; sourceTree = \"<group>\"; };\n\t\tEF368A6A1EBC6FA200A629B1 /* LXDMemoryDisplayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDMemoryDisplayer.m; sourceTree = \"<group>\"; };\n\t\tEF368A6B1EBC6FA200A629B1 /* LXDResourceMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDResourceMonitor.h; sourceTree = \"<group>\"; };\n\t\tEF368A6C1EBC6FA200A629B1 /* LXDResourceMonitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDResourceMonitor.m; sourceTree = \"<group>\"; };\n\t\tEF368A6D1EBC6FA200A629B1 /* LXDSystemCPU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDSystemCPU.h; sourceTree = \"<group>\"; };\n\t\tEF368A6E1EBC6FA200A629B1 /* LXDSystemCPU.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDSystemCPU.m; sourceTree = \"<group>\"; };\n\t\tEF368A6F1EBC6FA200A629B1 /* LXDSystemMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDSystemMemory.h; sourceTree = \"<group>\"; };\n\t\tEF368A701EBC6FA200A629B1 /* LXDSystemMemory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDSystemMemory.m; sourceTree = \"<group>\"; };\n\t\tEF368A731EBC6FA200A629B1 /* LXDBacktraceLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDBacktraceLogger.h; sourceTree = \"<group>\"; };\n\t\tEF368A741EBC6FA200A629B1 /* LXDBacktraceLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDBacktraceLogger.m; sourceTree = \"<group>\"; };\n\t\tEF368A761EBC6FA200A629B1 /* LXDDispatchAsync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDDispatchAsync.h; sourceTree = \"<group>\"; };\n\t\tEF368A771EBC6FA200A629B1 /* LXDDispatchAsync.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDDispatchAsync.m; sourceTree = \"<group>\"; };\n\t\tEF368A781EBC6FA200A629B1 /* LXDDispatchOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDDispatchOperation.h; sourceTree = \"<group>\"; };\n\t\tEF368A791EBC6FA200A629B1 /* LXDDispatchOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDDispatchOperation.m; sourceTree = \"<group>\"; };\n\t\tEF368A861EBC6FA200A629B1 /* LXDGlobalTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDGlobalTimer.h; sourceTree = \"<group>\"; };\n\t\tEF368A871EBC6FA200A629B1 /* LXDGlobalTimer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDGlobalTimer.m; sourceTree = \"<group>\"; };\n\t\tEF368A891EBC6FA200A629B1 /* LXDAsyncLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDAsyncLabel.h; sourceTree = \"<group>\"; };\n\t\tEF368A8A1EBC6FA200A629B1 /* LXDAsyncLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDAsyncLabel.m; sourceTree = \"<group>\"; };\n\t\tEF368A8B1EBC6FA200A629B1 /* LXDMonitorUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDMonitorUI.h; sourceTree = \"<group>\"; };\n\t\tEF368A8C1EBC6FA200A629B1 /* LXDTopWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDTopWindow.h; sourceTree = \"<group>\"; };\n\t\tEF368A8D1EBC6FA200A629B1 /* LXDTopWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDTopWindow.m; sourceTree = \"<group>\"; };\n\t\tEF368A8E1EBC6FA200A629B1 /* UIApplication+LXDTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = \"UIApplication+LXDTool.h\"; sourceTree = \"<group>\"; };\n\t\tEF368A8F1EBC6FA200A629B1 /* UIApplication+LXDTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = \"UIApplication+LXDTool.m\"; sourceTree = \"<group>\"; };\n\t\tEF368AB01EBC6FDE00A629B1 /* LXDTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXDTransaction.h; sourceTree = \"<group>\"; };\n\t\tEF368AB11EBC6FDE00A629B1 /* LXDTransaction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXDTransaction.m; sourceTree = \"<group>\"; };\n\t\tEF82D8691E8B8E9600DD4776 /* LXDAppMonitor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LXDAppMonitor.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tEF82D86D1E8B8E9600DD4776 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = \"<group>\"; };\n\t\tEF82D86F1E8B8E9600DD4776 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = \"<group>\"; };\n\t\tEF82D8701E8B8E9600DD4776 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = \"<group>\"; };\n\t\tEF82D8721E8B8E9600DD4776 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = \"<group>\"; };\n\t\tEF82D8731E8B8E9600DD4776 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = \"<group>\"; };\n\t\tEF82D8761E8B8E9600DD4776 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\tEF82D8781E8B8E9600DD4776 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\tEF82D87B1E8B8E9600DD4776 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = \"<group>\"; };\n\t\tEF82D87D1E8B8E9600DD4776 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tEF82D8821E8B8E9600DD4776 /* LXDAppMonitorTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LXDAppMonitorTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tEF82D8861E8B8E9600DD4776 /* LXDAppMonitorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LXDAppMonitorTests.m; sourceTree = \"<group>\"; };\n\t\tEF82D8881E8B8E9600DD4776 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tEF82D88D1E8B8E9600DD4776 /* LXDAppMonitorUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LXDAppMonitorUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tEF82D8911E8B8E9600DD4776 /* LXDAppMonitorUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LXDAppMonitorUITests.m; sourceTree = \"<group>\"; };\n\t\tEF82D8931E8B8E9600DD4776 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tEF82D8BD1E8B901000DD4776 /* WebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebViewController.h; sourceTree = \"<group>\"; };\n\t\tEF82D8BE1E8B901000DD4776 /* WebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewController.m; sourceTree = \"<group>\"; };\n\t\tEF82D8BF1E8B901000DD4776 /* WebViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = WebViewController.xib; sourceTree = \"<group>\"; };\n\t\tEFF9259F1EB2E5B1005D9BEB /* libsqlite3.0.tbd */ = {isa = PBXFileReference; lastKnownFileType = \"sourcecode.text-based-dylib-definition\"; name = libsqlite3.0.tbd; path = usr/lib/libsqlite3.0.tbd; sourceTree = SDKROOT; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tEF82D8661E8B8E9600DD4776 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tEFF925A01EB2E5B1005D9BEB /* libsqlite3.0.tbd in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tEF82D87F1E8B8E9600DD4776 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tEF82D88A1E8B8E9600DD4776 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\tEF368A491EBC6FA200A629B1 /* LXDAppMonitor */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF368A4A1EBC6FA200A629B1 /* Crash */,\n\t\t\t\tEF368A4F1EBC6FA200A629B1 /* Fluency */,\n\t\t\t\tEF368A521EBC6FA200A629B1 /* FPS */,\n\t\t\t\tEF368A591EBC6FA200A629B1 /* Intercept */,\n\t\t\t\tEF368A621EBC6FA200A629B1 /* Resource */,\n\t\t\t\tEF368A711EBC6FA200A629B1 /* Tool */,\n\t\t\t);\n\t\t\tpath = LXDAppMonitor;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF368A4A1EBC6FA200A629B1 /* Crash */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF368A4B1EBC6FA200A629B1 /* LXDCrashLogger.h */,\n\t\t\t\tEF368A4C1EBC6FA200A629B1 /* LXDCrashLogger.m */,\n\t\t\t\tEF368A4D1EBC6FA200A629B1 /* LXDCrashMonitor.h */,\n\t\t\t\tEF368A4E1EBC6FA200A629B1 /* LXDCrashMonitor.m */,\n\t\t\t);\n\t\t\tpath = Crash;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF368A4F1EBC6FA200A629B1 /* Fluency */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF368A501EBC6FA200A629B1 /* LXDAppFluencyMonitor.h */,\n\t\t\t\tEF368A511EBC6FA200A629B1 /* LXDAppFluencyMonitor.m */,\n\t\t\t);\n\t\t\tpath = Fluency;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF368A521EBC6FA200A629B1 /* FPS */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF368A531EBC6FA200A629B1 /* LXDFPSDisplayer.h */,\n\t\t\t\tEF368A541EBC6FA200A629B1 /* LXDFPSDisplayer.m */,\n\t\t\t\tEF368A551EBC6FA200A629B1 /* LXDFPSMonitor.h */,\n\t\t\t\tEF368A561EBC6FA200A629B1 /* LXDFPSMonitor.m */,\n\t\t\t\tEF368A571EBC6FA200A629B1 /* LXDWeakProxy.h */,\n\t\t\t\tEF368A581EBC6FA200A629B1 /* LXDWeakProxy.m */,\n\t\t\t);\n\t\t\tpath = FPS;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF368A591EBC6FA200A629B1 /* Intercept */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF368A5A1EBC6FA200A629B1 /* LXDDNSInterceptor.h */,\n\t\t\t\tEF368A5B1EBC6FA200A629B1 /* LXDDNSInterceptor.m */,\n\t\t\t\tEF368A5C1EBC6FA200A629B1 /* LXDHostFilterRule.h */,\n\t\t\t\tEF368A5D1EBC6FA200A629B1 /* LXDHostFilterRule.m */,\n\t\t\t\tEF368A5E1EBC6FA200A629B1 /* LXDHostMapper.h */,\n\t\t\t\tEF368A5F1EBC6FA200A629B1 /* LXDHostMapper.m */,\n\t\t\t\tEF368A601EBC6FA200A629B1 /* NSURLProtocol+WebKitSupport.h */,\n\t\t\t\tEF368A611EBC6FA200A629B1 /* NSURLProtocol+WebKitSupport.m */,\n\t\t\t);\n\t\t\tpath = Intercept;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF368A621EBC6FA200A629B1 /* Resource */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF368A631EBC6FA200A629B1 /* LXDApplicationCPU.h */,\n\t\t\t\tEF368A641EBC6FA200A629B1 /* LXDApplicationCPU.m */,\n\t\t\t\tEF368A651EBC6FA200A629B1 /* LXDApplicationMemory.h */,\n\t\t\t\tEF368A661EBC6FA200A629B1 /* LXDApplicationMemory.m */,\n\t\t\t\tEF368A671EBC6FA200A629B1 /* LXDCPUDisplayer.h */,\n\t\t\t\tEF368A681EBC6FA200A629B1 /* LXDCPUDisplayer.m */,\n\t\t\t\tEF368A691EBC6FA200A629B1 /* LXDMemoryDisplayer.h */,\n\t\t\t\tEF368A6A1EBC6FA200A629B1 /* LXDMemoryDisplayer.m */,\n\t\t\t\tEF368A6B1EBC6FA200A629B1 /* LXDResourceMonitor.h */,\n\t\t\t\tEF368A6C1EBC6FA200A629B1 /* LXDResourceMonitor.m */,\n\t\t\t\tEF368A6D1EBC6FA200A629B1 /* LXDSystemCPU.h */,\n\t\t\t\tEF368A6E1EBC6FA200A629B1 /* LXDSystemCPU.m */,\n\t\t\t\tEF368A6F1EBC6FA200A629B1 /* LXDSystemMemory.h */,\n\t\t\t\tEF368A701EBC6FA200A629B1 /* LXDSystemMemory.m */,\n\t\t\t);\n\t\t\tpath = Resource;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF368A711EBC6FA200A629B1 /* Tool */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF368A721EBC6FA200A629B1 /* Backtrace */,\n\t\t\t\tEF368A751EBC6FA200A629B1 /* Dispatch */,\n\t\t\t\tEF368A7A1EBC6FA200A629B1 /* Performance */,\n\t\t\t\tEF368A851EBC6FA200A629B1 /* Timer */,\n\t\t\t\tEF368A881EBC6FA200A629B1 /* UI */,\n\t\t\t);\n\t\t\tpath = Tool;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF368A721EBC6FA200A629B1 /* Backtrace */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF368A731EBC6FA200A629B1 /* LXDBacktraceLogger.h */,\n\t\t\t\tEF368A741EBC6FA200A629B1 /* LXDBacktraceLogger.m */,\n\t\t\t);\n\t\t\tpath = Backtrace;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF368A751EBC6FA200A629B1 /* Dispatch */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF368A761EBC6FA200A629B1 /* LXDDispatchAsync.h */,\n\t\t\t\tEF368A771EBC6FA200A629B1 /* LXDDispatchAsync.m */,\n\t\t\t\tEF368A781EBC6FA200A629B1 /* LXDDispatchOperation.h */,\n\t\t\t\tEF368A791EBC6FA200A629B1 /* LXDDispatchOperation.m */,\n\t\t\t);\n\t\t\tpath = Dispatch;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF368A7A1EBC6FA200A629B1 /* Performance */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF368AB01EBC6FDE00A629B1 /* LXDTransaction.h */,\n\t\t\t\tEF368AB11EBC6FDE00A629B1 /* LXDTransaction.m */,\n\t\t\t);\n\t\t\tpath = Performance;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF368A851EBC6FA200A629B1 /* Timer */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF368A861EBC6FA200A629B1 /* LXDGlobalTimer.h */,\n\t\t\t\tEF368A871EBC6FA200A629B1 /* LXDGlobalTimer.m */,\n\t\t\t);\n\t\t\tpath = Timer;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF368A881EBC6FA200A629B1 /* UI */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF368A891EBC6FA200A629B1 /* LXDAsyncLabel.h */,\n\t\t\t\tEF368A8A1EBC6FA200A629B1 /* LXDAsyncLabel.m */,\n\t\t\t\tEF368A8B1EBC6FA200A629B1 /* LXDMonitorUI.h */,\n\t\t\t\tEF368A8C1EBC6FA200A629B1 /* LXDTopWindow.h */,\n\t\t\t\tEF368A8D1EBC6FA200A629B1 /* LXDTopWindow.m */,\n\t\t\t\tEF368A8E1EBC6FA200A629B1 /* UIApplication+LXDTool.h */,\n\t\t\t\tEF368A8F1EBC6FA200A629B1 /* UIApplication+LXDTool.m */,\n\t\t\t);\n\t\t\tpath = UI;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF82D8601E8B8E9600DD4776 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF82D86B1E8B8E9600DD4776 /* LXDAppMonitor */,\n\t\t\t\tEF82D8851E8B8E9600DD4776 /* LXDAppMonitorTests */,\n\t\t\t\tEF82D8901E8B8E9600DD4776 /* LXDAppMonitorUITests */,\n\t\t\t\tEF82D86A1E8B8E9600DD4776 /* Products */,\n\t\t\t\tEFF9259E1EB2E5B1005D9BEB /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF82D86A1E8B8E9600DD4776 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF82D8691E8B8E9600DD4776 /* LXDAppMonitor.app */,\n\t\t\t\tEF82D8821E8B8E9600DD4776 /* LXDAppMonitorTests.xctest */,\n\t\t\t\tEF82D88D1E8B8E9600DD4776 /* LXDAppMonitorUITests.xctest */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF82D86B1E8B8E9600DD4776 /* LXDAppMonitor */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF368A491EBC6FA200A629B1 /* LXDAppMonitor */,\n\t\t\t\tEF82D86F1E8B8E9600DD4776 /* AppDelegate.h */,\n\t\t\t\tEF82D8701E8B8E9600DD4776 /* AppDelegate.m */,\n\t\t\t\tEF82D8721E8B8E9600DD4776 /* ViewController.h */,\n\t\t\t\tEF82D8731E8B8E9600DD4776 /* ViewController.m */,\n\t\t\t\tEF82D8751E8B8E9600DD4776 /* Main.storyboard */,\n\t\t\t\tEF82D8781E8B8E9600DD4776 /* Assets.xcassets */,\n\t\t\t\tEF82D87A1E8B8E9600DD4776 /* LaunchScreen.storyboard */,\n\t\t\t\tEF82D87D1E8B8E9600DD4776 /* Info.plist */,\n\t\t\t\tEF82D86C1E8B8E9600DD4776 /* Supporting Files */,\n\t\t\t\tEF82D8BD1E8B901000DD4776 /* WebViewController.h */,\n\t\t\t\tEF82D8BE1E8B901000DD4776 /* WebViewController.m */,\n\t\t\t\tEF82D8BF1E8B901000DD4776 /* WebViewController.xib */,\n\t\t\t);\n\t\t\tpath = LXDAppMonitor;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF82D86C1E8B8E9600DD4776 /* Supporting Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF82D86D1E8B8E9600DD4776 /* main.m */,\n\t\t\t);\n\t\t\tname = \"Supporting Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF82D8851E8B8E9600DD4776 /* LXDAppMonitorTests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF82D8861E8B8E9600DD4776 /* LXDAppMonitorTests.m */,\n\t\t\t\tEF82D8881E8B8E9600DD4776 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = LXDAppMonitorTests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF82D8901E8B8E9600DD4776 /* LXDAppMonitorUITests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEF82D8911E8B8E9600DD4776 /* LXDAppMonitorUITests.m */,\n\t\t\t\tEF82D8931E8B8E9600DD4776 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = LXDAppMonitorUITests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEFF9259E1EB2E5B1005D9BEB /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tEFF9259F1EB2E5B1005D9BEB /* libsqlite3.0.tbd */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\tEF82D8681E8B8E9600DD4776 /* LXDAppMonitor */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = EF82D8961E8B8E9600DD4776 /* Build configuration list for PBXNativeTarget \"LXDAppMonitor\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tEF82D8651E8B8E9600DD4776 /* Sources */,\n\t\t\t\tEF82D8661E8B8E9600DD4776 /* Frameworks */,\n\t\t\t\tEF82D8671E8B8E9600DD4776 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = LXDAppMonitor;\n\t\t\tproductName = LXDAppMonitor;\n\t\t\tproductReference = EF82D8691E8B8E9600DD4776 /* LXDAppMonitor.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\tEF82D8811E8B8E9600DD4776 /* LXDAppMonitorTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = EF82D8991E8B8E9600DD4776 /* Build configuration list for PBXNativeTarget \"LXDAppMonitorTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tEF82D87E1E8B8E9600DD4776 /* Sources */,\n\t\t\t\tEF82D87F1E8B8E9600DD4776 /* Frameworks */,\n\t\t\t\tEF82D8801E8B8E9600DD4776 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tEF82D8841E8B8E9600DD4776 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = LXDAppMonitorTests;\n\t\t\tproductName = LXDAppMonitorTests;\n\t\t\tproductReference = EF82D8821E8B8E9600DD4776 /* LXDAppMonitorTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\tEF82D88C1E8B8E9600DD4776 /* LXDAppMonitorUITests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = EF82D89C1E8B8E9600DD4776 /* Build configuration list for PBXNativeTarget \"LXDAppMonitorUITests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tEF82D8891E8B8E9600DD4776 /* Sources */,\n\t\t\t\tEF82D88A1E8B8E9600DD4776 /* Frameworks */,\n\t\t\t\tEF82D88B1E8B8E9600DD4776 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\tEF82D88F1E8B8E9600DD4776 /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = LXDAppMonitorUITests;\n\t\t\tproductName = LXDAppMonitorUITests;\n\t\t\tproductReference = EF82D88D1E8B8E9600DD4776 /* LXDAppMonitorUITests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.ui-testing\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tEF82D8611E8B8E9600DD4776 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastUpgradeCheck = 0830;\n\t\t\t\tORGANIZATIONNAME = Jolimark;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\tEF82D8681E8B8E9600DD4776 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.3;\n\t\t\t\t\t\tDevelopmentTeam = 7J57ACJ383;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t};\n\t\t\t\t\tEF82D8811E8B8E9600DD4776 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.3;\n\t\t\t\t\t\tDevelopmentTeam = 7J57ACJ383;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t\tTestTargetID = EF82D8681E8B8E9600DD4776;\n\t\t\t\t\t};\n\t\t\t\t\tEF82D88C1E8B8E9600DD4776 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.3;\n\t\t\t\t\t\tDevelopmentTeam = 7J57ACJ383;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t\tTestTargetID = EF82D8681E8B8E9600DD4776;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = EF82D8641E8B8E9600DD4776 /* Build configuration list for PBXProject \"LXDAppMonitor\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = EF82D8601E8B8E9600DD4776;\n\t\t\tproductRefGroup = EF82D86A1E8B8E9600DD4776 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tEF82D8681E8B8E9600DD4776 /* LXDAppMonitor */,\n\t\t\t\tEF82D8811E8B8E9600DD4776 /* LXDAppMonitorTests */,\n\t\t\t\tEF82D88C1E8B8E9600DD4776 /* LXDAppMonitorUITests */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\tEF82D8671E8B8E9600DD4776 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tEF82D87C1E8B8E9600DD4776 /* LaunchScreen.storyboard in Resources */,\n\t\t\t\tEF82D8791E8B8E9600DD4776 /* Assets.xcassets in Resources */,\n\t\t\t\tEF82D8771E8B8E9600DD4776 /* Main.storyboard in Resources */,\n\t\t\t\tEF82D8C11E8B901000DD4776 /* WebViewController.xib in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tEF82D8801E8B8E9600DD4776 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tEF82D88B1E8B8E9600DD4776 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\tEF82D8651E8B8E9600DD4776 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tEF82D8741E8B8E9600DD4776 /* ViewController.m in Sources */,\n\t\t\t\tEF368A911EBC6FA200A629B1 /* LXDCrashMonitor.m in Sources */,\n\t\t\t\tEF368A971EBC6FA200A629B1 /* LXDHostFilterRule.m in Sources */,\n\t\t\t\tEF368A931EBC6FA200A629B1 /* LXDFPSDisplayer.m in Sources */,\n\t\t\t\tEF82D8711E8B8E9600DD4776 /* AppDelegate.m in Sources */,\n\t\t\t\tEF368AA11EBC6FA200A629B1 /* LXDBacktraceLogger.m in Sources */,\n\t\t\t\tEF368AB21EBC6FDE00A629B1 /* LXDTransaction.m in Sources */,\n\t\t\t\tEF82D8C01E8B901000DD4776 /* WebViewController.m in Sources */,\n\t\t\t\tEF368AAA1EBC6FA200A629B1 /* LXDAsyncLabel.m in Sources */,\n\t\t\t\tEF368AA91EBC6FA200A629B1 /* LXDGlobalTimer.m in Sources */,\n\t\t\t\tEF368A9B1EBC6FA200A629B1 /* LXDApplicationMemory.m in Sources */,\n\t\t\t\tEF368A9D1EBC6FA200A629B1 /* LXDMemoryDisplayer.m in Sources */,\n\t\t\t\tEF368A951EBC6FA200A629B1 /* LXDWeakProxy.m in Sources */,\n\t\t\t\tEF368A941EBC6FA200A629B1 /* LXDFPSMonitor.m in Sources */,\n\t\t\t\tEF368A9F1EBC6FA200A629B1 /* LXDSystemCPU.m in Sources */,\n\t\t\t\tEF368AA01EBC6FA200A629B1 /* LXDSystemMemory.m in Sources */,\n\t\t\t\tEF368A961EBC6FA200A629B1 /* LXDDNSInterceptor.m in Sources */,\n\t\t\t\tEF368A901EBC6FA200A629B1 /* LXDCrashLogger.m in Sources */,\n\t\t\t\tEF368A9A1EBC6FA200A629B1 /* LXDApplicationCPU.m in Sources */,\n\t\t\t\tEF368A991EBC6FA200A629B1 /* NSURLProtocol+WebKitSupport.m in Sources */,\n\t\t\t\tEF368AAC1EBC6FA200A629B1 /* UIApplication+LXDTool.m in Sources */,\n\t\t\t\tEF368A921EBC6FA200A629B1 /* LXDAppFluencyMonitor.m in Sources */,\n\t\t\t\tEF368AA31EBC6FA200A629B1 /* LXDDispatchOperation.m in Sources */,\n\t\t\t\tEF82D86E1E8B8E9600DD4776 /* main.m in Sources */,\n\t\t\t\tEF368AA21EBC6FA200A629B1 /* LXDDispatchAsync.m in Sources */,\n\t\t\t\tEF368AAB1EBC6FA200A629B1 /* LXDTopWindow.m in Sources */,\n\t\t\t\tEF368A9E1EBC6FA200A629B1 /* LXDResourceMonitor.m in Sources */,\n\t\t\t\tEF368A9C1EBC6FA200A629B1 /* LXDCPUDisplayer.m in Sources */,\n\t\t\t\tEF368A981EBC6FA200A629B1 /* LXDHostMapper.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tEF82D87E1E8B8E9600DD4776 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tEF82D8871E8B8E9600DD4776 /* LXDAppMonitorTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tEF82D8891E8B8E9600DD4776 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tEF82D8921E8B8E9600DD4776 /* LXDAppMonitorUITests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\tEF82D8841E8B8E9600DD4776 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = EF82D8681E8B8E9600DD4776 /* LXDAppMonitor */;\n\t\t\ttargetProxy = EF82D8831E8B8E9600DD4776 /* PBXContainerItemProxy */;\n\t\t};\n\t\tEF82D88F1E8B8E9600DD4776 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = EF82D8681E8B8E9600DD4776 /* LXDAppMonitor */;\n\t\t\ttargetProxy = EF82D88E1E8B8E9600DD4776 /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin PBXVariantGroup section */\n\t\tEF82D8751E8B8E9600DD4776 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tEF82D8761E8B8E9600DD4776 /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tEF82D87A1E8B8E9600DD4776 /* LaunchScreen.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tEF82D87B1E8B8E9600DD4776 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\tEF82D8941E8B8E9600DD4776 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 10.3;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tEF82D8951E8B8E9600DD4776 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 10.3;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tEF82D8971E8B8E9600DD4776 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tDEVELOPMENT_TEAM = 7J57ACJ383;\n\t\t\t\tINFOPLIST_FILE = LXDAppMonitor/Info.plist;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tOTHER_LDFLAGS = \"\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = jolimark.com.LXDAppMonitor;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tEF82D8981E8B8E9600DD4776 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tDEVELOPMENT_TEAM = 7J57ACJ383;\n\t\t\t\tINFOPLIST_FILE = LXDAppMonitor/Info.plist;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 8.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks\";\n\t\t\t\tOTHER_LDFLAGS = \"\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = jolimark.com.LXDAppMonitor;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tEF82D89A1E8B8E9600DD4776 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tDEVELOPMENT_TEAM = 7J57ACJ383;\n\t\t\t\tINFOPLIST_FILE = LXDAppMonitorTests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = jolimark.com.LXDAppMonitorTests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/LXDAppMonitor.app/LXDAppMonitor\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tEF82D89B1E8B8E9600DD4776 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tDEVELOPMENT_TEAM = 7J57ACJ383;\n\t\t\t\tINFOPLIST_FILE = LXDAppMonitorTests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = jolimark.com.LXDAppMonitorTests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/LXDAppMonitor.app/LXDAppMonitor\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tEF82D89D1E8B8E9600DD4776 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tDEVELOPMENT_TEAM = 7J57ACJ383;\n\t\t\t\tINFOPLIST_FILE = LXDAppMonitorUITests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = jolimark.com.LXDAppMonitorUITests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_TARGET_NAME = LXDAppMonitor;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tEF82D89E1E8B8E9600DD4776 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tDEVELOPMENT_TEAM = 7J57ACJ383;\n\t\t\t\tINFOPLIST_FILE = LXDAppMonitorUITests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = \"$(inherited) @executable_path/Frameworks @loader_path/Frameworks\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = jolimark.com.LXDAppMonitorUITests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tTEST_TARGET_NAME = LXDAppMonitor;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\tEF82D8641E8B8E9600DD4776 /* Build configuration list for PBXProject \"LXDAppMonitor\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tEF82D8941E8B8E9600DD4776 /* Debug */,\n\t\t\t\tEF82D8951E8B8E9600DD4776 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tEF82D8961E8B8E9600DD4776 /* Build configuration list for PBXNativeTarget \"LXDAppMonitor\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tEF82D8971E8B8E9600DD4776 /* Debug */,\n\t\t\t\tEF82D8981E8B8E9600DD4776 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tEF82D8991E8B8E9600DD4776 /* Build configuration list for PBXNativeTarget \"LXDAppMonitorTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tEF82D89A1E8B8E9600DD4776 /* Debug */,\n\t\t\t\tEF82D89B1E8B8E9600DD4776 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tEF82D89C1E8B8E9600DD4776 /* Build configuration list for PBXNativeTarget \"LXDAppMonitorUITests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tEF82D89D1E8B8E9600DD4776 /* Debug */,\n\t\t\t\tEF82D89E1E8B8E9600DD4776 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = EF82D8611E8B8E9600DD4776 /* Project object */;\n}\n"
  },
  {
    "path": "LXDAppMonitor.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:LXDAppMonitor.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "LXDAppMonitor.xcodeproj/xcuserdata/linxinda.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Bucket\n   type = \"1\"\n   version = \"2.0\">\n   <Breakpoints>\n      <BreakpointProxy\n         BreakpointExtensionID = \"Xcode.Breakpoint.ExceptionBreakpoint\">\n         <BreakpointContent\n            shouldBeEnabled = \"Yes\"\n            ignoreCount = \"0\"\n            continueAfterRunningActions = \"No\"\n            scope = \"0\"\n            stopOnStyle = \"0\">\n         </BreakpointContent>\n      </BreakpointProxy>\n   </Breakpoints>\n</Bucket>\n"
  },
  {
    "path": "LXDAppMonitor.xcodeproj/xcuserdata/linxinda.xcuserdatad/xcschemes/LXDAppMonitor.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0830\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"EF82D8681E8B8E9600DD4776\"\n               BuildableName = \"LXDAppMonitor.app\"\n               BlueprintName = \"LXDAppMonitor\"\n               ReferencedContainer = \"container:LXDAppMonitor.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"EF82D8811E8B8E9600DD4776\"\n               BuildableName = \"LXDAppMonitorTests.xctest\"\n               BlueprintName = \"LXDAppMonitorTests\"\n               ReferencedContainer = \"container:LXDAppMonitor.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"EF82D88C1E8B8E9600DD4776\"\n               BuildableName = \"LXDAppMonitorUITests.xctest\"\n               BlueprintName = \"LXDAppMonitorUITests\"\n               ReferencedContainer = \"container:LXDAppMonitor.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"EF82D8681E8B8E9600DD4776\"\n            BuildableName = \"LXDAppMonitor.app\"\n            BlueprintName = \"LXDAppMonitor\"\n            ReferencedContainer = \"container:LXDAppMonitor.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <AdditionalOptions>\n         <AdditionalOption\n            key = \"NSZombieEnabled\"\n            value = \"YES\"\n            isEnabled = \"YES\">\n         </AdditionalOption>\n      </AdditionalOptions>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"EF82D8681E8B8E9600DD4776\"\n            BuildableName = \"LXDAppMonitor.app\"\n            BlueprintName = \"LXDAppMonitor\"\n            ReferencedContainer = \"container:LXDAppMonitor.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n      <AdditionalOptions>\n      </AdditionalOptions>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"EF82D8681E8B8E9600DD4776\"\n            BuildableName = \"LXDAppMonitor.app\"\n            BlueprintName = \"LXDAppMonitor\"\n            ReferencedContainer = \"container:LXDAppMonitor.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "LXDAppMonitor.xcodeproj/xcuserdata/linxinda.xcuserdatad/xcschemes/xcschememanagement.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>SchemeUserState</key>\n\t<dict>\n\t\t<key>LXDAppMonitor.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>0</integer>\n\t\t</dict>\n\t</dict>\n\t<key>SuppressBuildableAutocreation</key>\n\t<dict>\n\t\t<key>EF82D8681E8B8E9600DD4776</key>\n\t\t<dict>\n\t\t\t<key>primary</key>\n\t\t\t<true/>\n\t\t</dict>\n\t\t<key>EF82D8811E8B8E9600DD4776</key>\n\t\t<dict>\n\t\t\t<key>primary</key>\n\t\t\t<true/>\n\t\t</dict>\n\t\t<key>EF82D88C1E8B8E9600DD4776</key>\n\t\t<dict>\n\t\t\t<key>primary</key>\n\t\t\t<true/>\n\t\t</dict>\n\t</dict>\n</dict>\n</plist>\n"
  },
  {
    "path": "LXDAppMonitorTests/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "LXDAppMonitorTests/LXDAppMonitorTests.m",
    "content": "//\n//  LXDAppMonitorTests.m\n//  LXDAppMonitorTests\n//\n//  Created by linxinda on 2017/3/29.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <XCTest/XCTest.h>\n\n@interface LXDAppMonitorTests : XCTestCase\n\n@end\n\n@implementation LXDAppMonitorTests\n\n- (void)setUp {\n    [super setUp];\n    // Put setup code here. This method is called before the invocation of each test method in the class.\n}\n\n- (void)tearDown {\n    // Put teardown code here. This method is called after the invocation of each test method in the class.\n    [super tearDown];\n}\n\n- (void)testExample {\n    // This is an example of a functional test case.\n    // Use XCTAssert and related functions to verify your tests produce the correct results.\n}\n\n- (void)testPerformanceExample {\n    // This is an example of a performance test case.\n    [self measureBlock:^{\n        // Put the code you want to measure the time of here.\n    }];\n}\n\n@end\n"
  },
  {
    "path": "LXDAppMonitorUITests/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "LXDAppMonitorUITests/LXDAppMonitorUITests.m",
    "content": "//\n//  LXDAppMonitorUITests.m\n//  LXDAppMonitorUITests\n//\n//  Created by linxinda on 2017/3/29.\n//  Copyright © 2017年 Jolimark. All rights reserved.\n//\n\n#import <XCTest/XCTest.h>\n\n@interface LXDAppMonitorUITests : XCTestCase\n\n@end\n\n@implementation LXDAppMonitorUITests\n\n- (void)setUp {\n    [super setUp];\n    \n    // Put setup code here. This method is called before the invocation of each test method in the class.\n    \n    // In UI tests it is usually best to stop immediately when a failure occurs.\n    self.continueAfterFailure = NO;\n    // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.\n    [[[XCUIApplication alloc] init] launch];\n    \n    // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.\n}\n\n- (void)tearDown {\n    // Put teardown code here. This method is called after the invocation of each test method in the class.\n    [super tearDown];\n}\n\n- (void)testExample {\n    // Use recording to get started writing UI tests.\n    // Use XCTAssert and related functions to verify your tests produce the correct results.\n}\n\n@end\n"
  },
  {
    "path": "ReadMe.md",
    "content": "**LXDAppMonitor**\n====\n`LXDAppMonitor`是一套轻量级的应用性能管理组件。\n\n为了实现高效率，项目中对`LXDDispatchQueue`多线程组件有比较强的依赖关系。`LXDAppMonitor`目前能够完成以下的监控任务：\n\n- `LXDAppFluencyMonitor` 应用卡顿检测\n\n\t\t[FLUENCYMONITOR startMonitoring];\n- `LXDFPSMonitor` FPS监控器\n\n\t\t[FPS_MONITOR startMonitoring];\n- `LXDDNSInterceptor` DNS解析器\n\t 重新实现`canonicalRequestForRequest`完成请求的重定向\n- `LXDResourceMonitor` 系统资源监控器\n\n\t\t[RESOURCE_MONITOR startMonitoring];\n\t\t\n- `LXDCrashMonitor` 异常监控\n\n\t\t[LXDCrashMonitor startMonitoring];\n\n**演示效果**\n====\n![](http://upload-images.jianshu.io/upload_images/783864-3adef6f9d8cabc88.gif?imageMogr2/auto-orient/strip)\n\n**性能**\n====\n采用`YYDispatchQueuePool`的相同多线程封装技术，对关键数据采集异步处理。所有监控数据展示器采用异步文本渲染方式，对性能几乎无影响。数据展示控件只在`DEBUG`模式下生效。\n\n**警告**\n====\n当前`demo`由于笔者公司不实现服务器数据收集业务，部分功能仅能在开发阶段使用。提交商店审核前需删除`DNS`劫持部分代码或者移除此功能\n\n"
  }
]