<NME> DoraemonManager.m
<BEF> //
//  DoraemonManager.m
//  DoraemonKit
//
//  Created by yixiang on 2017/12/11.
//
#import <UIKit/UIKit.h>
#import "DoraemonManager.h"
#import "DoraemonEntryWindow.h"
#import "DoraemonCacheManager.h"
#import "DoraemonStartPluginProtocol.h"
#import "DoraemonDefine.h"
#import "DoraemonUtil.h"
#import "DoraemonHomeWindow.h"
#import "Doraemoni18NUtil.h"
#import "DoraemonCrashUncaughtExceptionHandler.h"
#import "DoraemonCrashSignalExceptionHandler.h"
#import "DoraemonNSLogManager.h"
#import "DoraemonNSLogViewController.h"
#import "DoraemonNSLogListViewController.h"
#import "DoraemonHomeWindow.h"
#import "DoraemonStatisticsUtil.h"
#import "DoraemonANRManager.h"
#import "DoraemonLargeImageDetectionManager.h"
#import "DoraemonMockManager.h"
#import "DoraemonNetFlowOscillogramWindow.h"
#import "DoraemonNetFlowManager.h"
#import "DoraemonHealthManager.h"

#if DoraemonWithGPS
#import "DoraemonGPSMocker.h"
#endif


#if DoraemonWithLogger
#import "DoraemonCocoaLumberjackLogger.h"
#import "DoraemonCocoaLumberjackViewController.h"
#import "DoraemonCocoaLumberjackListViewController.h"
#endif

#if DoraemonWithWeex
#import "DoraemonWeexLogDataSource.h"
#import "DoraemonWeexInfoDataManager.h"
#endif


#define kTitle        @"title"
#define kDesc         @"desc"
#define kIcon         @"icon"
#define kPluginName   @"pluginName"
#define kAtModule     @"atModule"
#define kBuriedPoint  @"buriedPoint"

@implementation DoraemonManagerPluginTypeModel

@implementation DoraemonManager

+ (DoraemonManager *)shareInstance{
    static dispatch_once_t once;
    static DoraemonManager *instance;
    dispatch_once(&once, ^{

@property (nonatomic, strong) DoraemonEntryWindow *entryWindow;

@property (nonatomic, strong) NSMutableArray *startPlugins;

@property (nonatomic, copy) DoraemonANRBlock anrBlock;

@property (nonatomic, copy) DoraemonPerformanceBlock performanceBlock;

@property (nonatomic, assign) BOOL hasInstall;

// 定制位置
@property (nonatomic) CGPoint startingPosition;

@end

@implementation DoraemonManager

+ (nonnull DoraemonManager *)shareInstance{
    static dispatch_once_t once;
    static DoraemonManager *instance;
    dispatch_once(&once, ^{
        instance = [[DoraemonManager alloc] init];
    });
    return instance;
}

- (instancetype)init{
    self = [super init];
    if (self) {
        _autoDock = YES;
        _keyBlockDic = [[NSMutableDictionary alloc] init];
    }
    return self;
}

- (void)install{
    //启用默认位置
    CGPoint defaultPosition = DoraemonStartingPosition;
    CGSize size = [UIScreen mainScreen].bounds.size;
    if (size.width > size.height) {
        defaultPosition = DoraemonFullScreenStartingPosition;
    }
    [self installWithStartingPosition:defaultPosition];
}

- (void)installWithPid:(NSString *)pId{
    self.pId = pId;
    [self install];
}

- (void)installWithMockDomain:(NSString *)mockDomain{
    self.mockDomain = mockDomain;
    [self install];
}

- (void)installWithStartingPosition:(CGPoint) position{
    _startingPosition = position;
    [self installWithCustomBlock:^{
        //什么也没发生
    }];
}

- (void)installWithCustomBlock:(void(^)(void))customBlock{
    //保证install只执行一次
    if (_hasInstall) {
        return;
    }
    _hasInstall = YES;
    for (int i=0; i<_startPlugins.count; i++) {
        NSString *pluginName = _startPlugins[i];
        Class pluginClass = NSClassFromString(pluginName);
        id<DoraemonStartPluginProtocol> plugin = [[pluginClass alloc] init];
        if (plugin) {
            [plugin startPluginDidLoad];
        }
    }

    [self initData];
    customBlock();

    [self initEntry:self.startingPosition];
    
    //根据开关判断是否收集Crash日志
    if ([[DoraemonCacheManager sharedInstance] crashSwitch]) {
        [DoraemonCrashUncaughtExceptionHandler registerHandler];
        [DoraemonCrashSignalExceptionHandler registerHandler];
    }
    //根据开关判断是否开启流量监控
    if ([[DoraemonCacheManager sharedInstance] netFlowSwitch]) {
        [[DoraemonNetFlowManager shareInstance] canInterceptNetFlow:YES];
        //[[DoraemonNetFlowOscillogramWindow shareInstance] show];
    }

    //重新启动的时候，把帧率、CPU、内存和流量监控关闭
    [[DoraemonCacheManager sharedInstance] saveFpsSwitch:NO];
    [[DoraemonCacheManager sharedInstance] saveCpuSwitch:NO];
    [[DoraemonCacheManager sharedInstance] saveMemorySwitch:NO];

#if DoraemonWithGPS
    //开启mockGPS功能
    if ([[DoraemonCacheManager sharedInstance] mockGPSSwitch]) {
        CLLocationCoordinate2D coordinate = [[DoraemonCacheManager sharedInstance] mockCoordinate];
        CLLocation *loc = [[CLLocation alloc] initWithLatitude:coordinate.latitude longitude:coordinate.longitude];
        [[DoraemonGPSMocker shareInstance] mockPoint:loc];
    }
#endif

    
    //开启NSLog监控功能
    if ([[DoraemonCacheManager sharedInstance] nsLogSwitch]) {
        [[DoraemonNSLogManager sharedInstance] startNSLogMonitor];
    }
    
#if DoraemonWithLogger
    //开启CocoaLumberjack监控
    if ([[DoraemonCacheManager sharedInstance] loggerSwitch]) {
        [[DoraemonCocoaLumberjackLogger sharedInstance] startMonitor];
    }
#endif
    
    [[DoraemonANRManager sharedInstance] addANRBlock:^(NSDictionary *anrInfo) {
        if (self.anrBlock) {
            self.anrBlock(anrInfo);
        }
    }];
    
    //外部设置大图检测的数值
    if (_bigImageDetectionSize > 0){
        [DoraemonLargeImageDetectionManager shareInstance].minimumDetectionSize = _bigImageDetectionSize;
    }
    
    //统计开源项目使用量 不用于任何恶意行为
    [[DoraemonStatisticsUtil shareInstance] upLoadUserInfo];
    
    //拉取最新的mock数据
    [[DoraemonMockManager sharedInstance] queryMockData:^(int flag) {
        DoKitLog(@"mock get data, flag == %i",flag);
    }];
    
    //Weex工具的初始化
#if DoraemonWithWeex
    [DoraemonWeexLogDataSource shareInstance];
    [DoraemonWeexInfoDataManager shareInstance];
#endif
    
    //开启健康体检
    if ([[DoraemonCacheManager sharedInstance] healthStart]) {
        [[DoraemonHealthManager sharedInstance] startHealthCheck];
    }
    
}


/**
 初始化内置工具数据
 */
- (void)initData{
    #pragma mark - 平台工具
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonMockPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonHealthPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonFileSyncPlugin];
    
    #pragma mark - 常用工具
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonAppSettingPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonAppInfoPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonSandboxPlugin];
#if DoraemonWithGPS
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonGPSPlugin];
#endif

    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonH5Plugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonDeleteLocalDataPlugin];
    
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonNSLogPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonNSUserDefaultsPlugin];
#if DoraemonWithLogger
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonCocoaLumberjackPlugin];
#endif
    
#if DoraemonWithDatabase
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonDatabasePlugin];
#endif
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonJavaScriptPlugin];
    
    #pragma mark - 性能检测
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonFPSPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonCPUPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonMemoryPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonNetFlowPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonCrashPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonSubThreadUICheckPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonANRPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonLargeImageFilter];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonWeakNetworkPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonStartTimePlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonUIProfilePlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonTimeProfilePlugin];
#if DoraemonWithLoad
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonMethodUseTimePlugin];
#endif
#if DoraemonWithMLeaksFinder
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonMemoryLeakPlugin];
#endif
    
    #pragma mark - 视觉工具
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonColorPickPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonViewCheckPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonViewAlignPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonViewMetricsPlugin];
    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonHierarchyPlugin];
    
    #pragma mark - Weex专项工具
    #if DoraemonWithWeex
        [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonWeexLogPlugin];
        [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonWeexStoragePlugin];
        [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonWeexInfoPlugin];
        [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonWeexDevToolPlugin];
    #endif
}

/**
 初始化工具入口
 */
- (void)initEntry:(CGPoint) startingPosition{
    _entryWindow = [[DoraemonEntryWindow alloc] initWithStartPoint:startingPosition];
    [_entryWindow show];
    if(_autoDock){
        [_entryWindow setAutoDock:YES];
    }
}

- (void)addStartPlugin:(NSString *)pluginName{
    if (!_startPlugins) {
        _startPlugins = [[NSMutableArray alloc] init];
    }
    [_startPlugins addObject:pluginName];
}

- (void)addPluginWithPluginType:(DoraemonManagerPluginType)pluginType
{
    DoraemonManagerPluginTypeModel *model = [self getDefaultPluginDataWithPluginType:pluginType];
    [self addPluginWithTitle:model.title icon:model.icon desc:model.desc pluginName:model.pluginName atModule:model.atModule buriedPoint:model.buriedPoint];
}

// out 1
- (void)addPluginWithTitle:(NSString *)title icon:(NSString *)iconName desc:(NSString *)desc pluginName:(NSString *)entryName atModule:(NSString *)moduleName{
    [self addPluginWithTitle:title icon:iconName desc:desc pluginName:entryName atModule:moduleName buriedPoint:@"dokit_sdk_business_ck"];
}

- (void)addPluginWithTitle:(NSString *)title icon:(NSString *)iconName desc:(NSString *)desc pluginName:(NSString *)entryName atModule:(NSString *)moduleName buriedPoint:(NSString *)buriedPoint{
    
    NSMutableDictionary *pluginDic = [self foundGroupWithModule:moduleName];
    pluginDic[@"key"] = [NSString stringWithFormat:@"%@-%@-%@-%@",moduleName,title,iconName,desc];
    pluginDic[@"name"] = title;
    pluginDic[@"icon"] = iconName;
    pluginDic[@"desc"] = desc;
    pluginDic[@"pluginName"] = entryName;
    pluginDic[@"buriedPoint"] = buriedPoint;
    pluginDic[@"show"] = @1;
}

// out 2
- (void)addPluginWithTitle:(NSString *)title icon:(NSString *)iconName desc:(NSString *)desc pluginName:(NSString *)entryName atModule:(NSString *)moduleName handle:(void (^)(NSDictionary *))handleBlock
{
    NSMutableDictionary *pluginDic = [self foundGroupWithModule:moduleName];
    pluginDic[@"key"] = [NSString stringWithFormat:@"%@-%@-%@-%@",moduleName,title,iconName,desc];
    pluginDic[@"name"] = title;
    pluginDic[@"icon"] = iconName;
    pluginDic[@"desc"] = desc;
    pluginDic[@"pluginName"] = entryName;
    [_keyBlockDic setValue:[handleBlock copy] forKey:pluginDic[@"key"]];
    pluginDic[@"buriedPoint"] = @"dokit_sdk_business_ck";
    pluginDic[@"show"] = @1;

}

- (void)addPluginWithTitle:(NSString *)title image:(UIImage *)image desc:(NSString *)desc pluginName:(NSString *)entryName atModule:(NSString *)moduleName handle:(void (^)(NSDictionary * _Nonnull))handleBlock {
    NSMutableDictionary *pluginDic = [self foundGroupWithModule:moduleName];
    pluginDic[@"key"] = [NSString stringWithFormat:@"%@-%@-%@",moduleName,title,desc];
    pluginDic[@"name"] = title;
    pluginDic[@"image"] = image;
    pluginDic[@"desc"] = desc;
    pluginDic[@"pluginName"] = entryName;
    if (handleBlock) {
        [_keyBlockDic setValue:[handleBlock copy] forKey:pluginDic[@"key"]];
    }
    pluginDic[@"buriedPoint"] = @"dokit_sdk_business_ck";
    pluginDic[@"show"] = @1;
}

- (NSMutableDictionary *)foundGroupWithModule:(NSString *)module
{
    NSMutableDictionary *pluginDic = [NSMutableDictionary dictionary];
    pluginDic[@"moduleName"] = module;
    __block BOOL hasModule = NO;
    [self.dataArray enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSDictionary *moduleDic = obj;
        NSString *moduleName = moduleDic[@"moduleName"];
        if ([moduleName isEqualToString:module]) {
            hasModule = YES;
            NSMutableArray *pluginArray = moduleDic[@"pluginArray"];
            if (pluginArray) {
                [pluginArray addObject:pluginDic];
            }
            [moduleDic setValue:pluginArray forKey:@"pluginArray"];
            *stop = YES;
        }
    }];
    if (!hasModule) {
        NSMutableArray *pluginArray = [[NSMutableArray alloc] initWithObjects:pluginDic, nil];
        [self registerPluginArray:pluginArray withModule:module];
    }
    return pluginDic;
}
- (void)removePluginWithPluginType:(DoraemonManagerPluginType)pluginType
{
    DoraemonManagerPluginTypeModel *model = [self getDefaultPluginDataWithPluginType:pluginType];
    [self removePluginWithPluginName:model.pluginName atModule:model.atModule];
}

- (void)removePluginWithPluginName:(NSString *)pluginName atModule:(NSString *)moduleName{
    [self unregisterPlugin:pluginName withModule:moduleName];
}

- (void)registerPluginArray:(NSMutableArray*)array withModule:(NSString*)moduleName{
    if (!_dataArray){
        _dataArray = [[NSMutableArray alloc]init];
    }
    NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
    [dic setValue:moduleName forKey:@"moduleName"];
    [dic setValue:array forKey:@"pluginArray"];
    [_dataArray addObject:dic];
}

- (void)unregisterPlugin:(NSString*)pluginName withModule:(NSString*)moduleName{
    if (!_dataArray){
        return;
    }
    id object;
    for (object in _dataArray) {
        NSString *tempModuleName = [((NSMutableDictionary *)object) valueForKey:@"moduleName"];
        if ([tempModuleName isEqualToString:moduleName]) {
            NSMutableArray *tempPluginArray = [((NSMutableDictionary *)object) valueForKey:@"pluginArray"];
            id pluginObject;
            for (pluginObject in tempPluginArray) {
                NSString *tempPluginName = [((NSMutableDictionary *)pluginObject) valueForKey:@"pluginName"];
                if ([tempPluginName isEqualToString:pluginName]) {
                    [tempPluginArray removeObject:pluginObject];
                    return;
                }
            }
        }
    }
}

- (BOOL)isShowDoraemon{
    if (!_entryWindow) {
        return NO;
    }
    return !_entryWindow.hidden;
}

- (void)showDoraemon{
    if (_entryWindow.hidden) {
        _entryWindow.hidden = NO;
    }
}

- (void)hiddenDoraemon{
    if (!_entryWindow.hidden) {
        _entryWindow.hidden = YES;
     }
}


- (void)addH5DoorBlock:(void(^)(NSString *h5Url))block{
    self.h5DoorBlock = block;
}

- (void)addANRBlock:(void(^)(NSDictionary *anrDic))block{
    self.anrBlock = block;
}

- (void)addPerformanceBlock:(void(^)(NSDictionary *performanceDic))block{
    self.performanceBlock = block;
}

- (void)addWebpHandleBlock:(UIImage *(^)(NSString *filePath))block{
    self.webpHandleBlock = block;
}

- (void)hiddenHomeWindow{
    [[DoraemonHomeWindow shareInstance] hide];
}

#pragma mark - default data
- (DoraemonManagerPluginTypeModel *)getDefaultPluginDataWithPluginType:(DoraemonManagerPluginType)pluginType
{
    NSArray *dataArray = @{
                           @(DoraemonManagerPluginType_DoraemonWeexLogPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"日志")},
                                   @{kDesc:@"Weex log"},
                                   @{kIcon:@"doraemon_log"},
                                   @{kPluginName:@"DoraemonWeexLogPlugin"},
                                   @{kAtModule:@"Weex"},
                                   @{kBuriedPoint:@"dokit_sdk_weex_ck_log"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonWeexStoragePlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"缓存")},
                                   @{kDesc:@"weex storage"},
                                   @{kIcon:@"doraemon_file"},
                                   @{kPluginName:@"DoraemonWeexStoragePlugin"},
                                   @{kAtModule:@"Weex"},
                                   @{kBuriedPoint:@"dokit_sdk_weex_ck_storage"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonWeexInfoPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"信息")},
                                   @{kDesc:@"weex info"},
                                   @{kIcon:@"doraemon_app_info"},
                                   @{kPluginName:@"DoraemonWeexInfoPlugin"},
                                   @{kAtModule:@"Weex"},
                                   @{kBuriedPoint:@"dokit_sdk_weex_ck_vessel"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonWeexDevToolPlugin) : @[
                                   @{kTitle:@"DevTool"},
                                   @{kDesc:@"weex devtool"},
                                   @{kIcon:@"doraemon_default"},
                                   @{kPluginName:@"DoraemonWeexDevTooloPlugin"},
                                   @{kAtModule:@"Weex"},
                                   @{kBuriedPoint:@"dokit_sdk_weex_ck_devtool"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonAppSettingPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"应用设置")},
                                   @{kDesc:DoraemonLocalizedString(@"应用设置")},
                                   @{kIcon:@"doraemon_setting"},
                                   @{kPluginName:@"DoraemonAppSettingPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},
                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_setting"}
                                    ],
                           @(DoraemonManagerPluginType_DoraemonAppInfoPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"App信息")},
                                   @{kDesc:DoraemonLocalizedString(@"App信息")},
                                   @{kIcon:@"doraemon_app_info"},
                                   @{kPluginName:@"DoraemonAppInfoPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},
                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_appinfo"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonSandboxPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"沙盒浏览器")},
                                   @{kDesc:DoraemonLocalizedString(@"沙盒浏览器")},
                                   @{kIcon:@"doraemon_file"},
                                   @{kPluginName:@"DoraemonSandboxPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},
                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_sandbox"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonGPSPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"Mock GPS")},
                                   @{kDesc:DoraemonLocalizedString(@"Mock GPS")},
                                   @{kIcon:@"doraemon_mock_gps"},
                                   @{kPluginName:@"DoraemonGPSPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},
                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_gps"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonH5Plugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"H5任意门")},
                                   @{kDesc:DoraemonLocalizedString(@"H5任意门")},
                                   @{kIcon:@"doraemon_h5"},
                                   @{kPluginName:@"DoraemonH5Plugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},
                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_h5"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonDeleteLocalDataPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"清理缓存")},
                                   @{kDesc:DoraemonLocalizedString(@"清理缓存")},
                                   @{kIcon:@"doraemon_qingchu"},
                                   @{kPluginName:@"DoraemonDeleteLocalDataPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},
                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_cache"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonNSLogPlugin) : @[
                                   @{kTitle:@"NSLog"},
                                   @{kDesc:@"NSLog"},
                                   @{kIcon:@"doraemon_nslog"},
                                   @{kPluginName:@"DoraemonNSLogPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},
                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_log"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonCocoaLumberjackPlugin) : @[
                                   @{kTitle:@"Lumberjack"},
                                   @{kDesc:DoraemonLocalizedString(@"Lumberjack")},
                                   @{kIcon:@"doraemon_log"},
                                   @{kPluginName:@"DoraemonCocoaLumberjackPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},
                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_lumberjack"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonDatabasePlugin) : @[
                                   @{kTitle:@"DBView"},
                                   @{kDesc:DoraemonLocalizedString(@"数据库预览")},
                                   @{kIcon:@"doraemon_database"},
                                   @{kPluginName:@"DoraemonDatabasePlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},
                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_dbview"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonNSUserDefaultsPlugin) : @[
                                   @{kTitle:@"UserDefaults"},
                                   @{kDesc:@"UserDefaults"},
                                   @{kIcon:@"doraemon_database"},
                                   @{kPluginName:@"DoraemonNSUserDefaultsPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},
                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_userdefault"}
                           ],
                           @(DoraemonManagerPluginType_DoraemonJavaScriptPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"JS脚本")},
                                   @{kDesc:DoraemonLocalizedString(@"JS脚本")},
                                   @{kIcon:@"doraemon_js"},
                                   @{kPluginName:@"DoraemonJavaScriptPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},
                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_js"}
                           ],
                           
                           // 性能检测
                           @(DoraemonManagerPluginType_DoraemonFPSPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"帧率")},
                                   @{kDesc:DoraemonLocalizedString(@"帧率")},
                                   @{kIcon:@"doraemon_fps"},
                                   @{kPluginName:@"DoraemonFPSPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},
                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_fps"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonCPUPlugin) : @[
                                   @{kTitle:@"CPU"},
                                   @{kDesc:DoraemonLocalizedString(@"CPU")},
                                   @{kIcon:@"doraemon_cpu"},
                                   @{kPluginName:@"DoraemonCPUPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},
                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_cpu"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonMemoryPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"内存")},
                                   @{kDesc:DoraemonLocalizedString(@"内存")},
                                   @{kIcon:@"doraemon_memory"},
                                   @{kPluginName:@"DoraemonMemoryPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},
                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_arm"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonNetFlowPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"网络")},
                                   @{kDesc:DoraemonLocalizedString(@"网络监控")},
                                   @{kIcon:@"doraemon_net"},
                                   @{kPluginName:@"DoraemonNetFlowPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},
                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_network"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonCrashPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"Crash")},
                                   @{kDesc:DoraemonLocalizedString(@"Crash")},
                                   @{kIcon:@"doraemon_crash"},
                                   @{kPluginName:@"DoraemonCrashPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},
                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_crash"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonSubThreadUICheckPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"子线程UI")},
                                   @{kDesc:DoraemonLocalizedString(@"子线程UI")},
                                   @{kIcon:@"doraemon_ui"},
                                   @{kPluginName:@"DoraemonSubThreadUICheckPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},
                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_child_thread"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonANRPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"卡顿")},
                                   @{kDesc:DoraemonLocalizedString(@"卡顿")},
                                   @{kIcon:@"doraemon_kadun"},
                                   @{kPluginName:@"DoraemonANRPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},
                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_block"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonMethodUseTimePlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"Load耗时")},
                                   @{kDesc:DoraemonLocalizedString(@"Load耗时")},
                                   @{kIcon:@"doraemon_method_use_time"},
                                   @{kPluginName:@"DoraemonMethodUseTimePlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},
                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_load"}
                                   ],
                           
                           @(DoraemonManagerPluginType_DoraemonLargeImageFilter) : @[
                                   @{kTitle:DoraemonLocalizedString(@"大图检测")},
                                   @{kDesc:DoraemonLocalizedString(@"大图检测")},
                                   @{kIcon:@"doraemon_net"},
                                   @{kPluginName:@"DoraemonLargeImagePlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},
                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_img"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonStartTimePlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"启动耗时")},
                                   @{kDesc:DoraemonLocalizedString(@"启动耗时")},
                                   @{kIcon:@"doraemon_app_start_time"},
                                   @{kPluginName:@"DoraemonStartTimePlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},
                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_appstart_coast"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonMemoryLeakPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"内存泄漏")},
                                   @{kDesc:DoraemonLocalizedString(@"内存泄漏统计")},
                                   @{kIcon:@"doraemon_memory_leak"},
                                   @{kPluginName:@"DoraemonMLeaksFinderPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},
                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_leak"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonUIProfilePlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"UI层级")},
                                   @{kDesc:DoraemonLocalizedString(@"UI层级s")},
                                   @{kIcon:@"doraemon_view_level"},
                                   @{kPluginName:@"DoraemonUIProfilePlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},
                                   @{kBuriedPoint:@"dokit_sdk_ui_ck_hierarchy"}
                           ],
                           @(DoraemonManagerPluginType_DoraemonTimeProfilePlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"函数耗时")},
                                   @{kDesc:DoraemonLocalizedString(@"函数耗时统计")},
                                   @{kIcon:@"doraemon_time_profiler"},
                                   @{kPluginName:@"DoraemonTimeProfilerPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},
                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_method_coast"}
                           ],
                           @(DoraemonManagerPluginType_DoraemonWeakNetworkPlugin) : @[
                                     @{kTitle:DoraemonLocalizedString(@"模拟弱网")},
                                     @{kDesc:DoraemonLocalizedString(@"模拟弱网测试")},
                                     @{kIcon:@"doraemon_weaknet"},
                                     @{kPluginName:@"DoraemonWeakNetworkPlugin"},
                                     @{kAtModule:DoraemonLocalizedString(@"性能检测")},
                                     @{kBuriedPoint:@"dokit_sdk_comm_ck_weaknetwork"}
                             ],
                           // 视觉工具
                           @(DoraemonManagerPluginType_DoraemonColorPickPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"取色器")},
                                   @{kDesc:DoraemonLocalizedString(@"取色器")},
                                   @{kIcon:@"doraemon_straw"},
                                   @{kPluginName:@"DoraemonColorPickPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"视觉工具")},
                                   @{kBuriedPoint:@"dokit_sdk_ui_ck_color_pick"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonViewCheckPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"组件检查")},
                                   @{kDesc:DoraemonLocalizedString(@"组件检查")},
                                   @{kIcon:@"doraemon_view_check"},
                                   @{kPluginName:@"DoraemonViewCheckPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"视觉工具")},
                                   @{kBuriedPoint:@"dokit_sdk_ui_ck_widget"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonViewAlignPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"对齐标尺")},
                                   @{kDesc:DoraemonLocalizedString(@"对齐标尺")},
                                   @{kIcon:@"doraemon_align"},
                                   @{kPluginName:@"DoraemonViewAlignPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"视觉工具")},
                                   @{kBuriedPoint:@"dokit_sdk_ui_ck_aligin_scaleplate"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonViewMetricsPlugin) : @[
                                   @{kTitle:DoraemonLocalizedString(@"布局边框")},
                                   @{kDesc:DoraemonLocalizedString(@"布局边框")},
                                   @{kIcon:@"doraemon_viewmetrics"},
                                   @{kPluginName:@"DoraemonViewMetricsPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"视觉工具")},
                                   @{kBuriedPoint:@"dokit_sdk_ui_ck_border"}
                                   ],
                          @(DoraemonManagerPluginType_DoraemonHierarchyPlugin) : @[
                                           @{kTitle:DoraemonLocalizedString(@"UI结构")},
                                           @{kDesc:DoraemonLocalizedString(@"显示UI结构")},
                                           @{kIcon:@"doraemon_view_level"},
                                           @{kPluginName:@"DoraemonHierarchyPlugin"},
                                           @{kAtModule:DoraemonLocalizedString(@"视觉工具")},
                                           @{kBuriedPoint:@"dokit_sdk_ui_ck_widget_3d"}
                                   ],
                           // 平台工具
                           @(DoraemonManagerPluginType_DoraemonMockPlugin) : @[
                                @{kTitle:DoraemonLocalizedString(@"Mock数据")},
                                   @{kDesc:DoraemonLocalizedString(@"Mock数据")},
                                   @{kIcon:@"doraemon_mock"},
                                   @{kPluginName:@"DoraemonMockPlugin"},
                                   @{kAtModule:DoraemonLocalizedString(@"平台工具")},
                                   @{kBuriedPoint:@"dokit_sdk_platform_ck_mock"}
                                   ],
                           @(DoraemonManagerPluginType_DoraemonHealthPlugin) : @[
                               @{kTitle:DoraemonLocalizedString(@"健康体检")},
                                  @{kDesc:DoraemonLocalizedString(@"健康体检中心")},
                                  @{kIcon:@"doraemon_health"},
                                  @{kPluginName:@"DoraemonHealthPlugin"},
                                  @{kAtModule:DoraemonLocalizedString(@"平台工具")},
                                  @{kBuriedPoint:@"dokit_sdk_platform_ck_health"}
                                  ],
                           @(DoraemonManagerPluginType_DoraemonFileSyncPlugin) : @[
                                @{kTitle:DoraemonLocalizedString(@"文件同步")},
                                    @{kDesc:DoraemonLocalizedString(@"文件同步")},
                                    @{kIcon:@"doraemon_file_sync"},
                                    @{kPluginName:@"DoraemonFileSyncPlugin"},
                                    @{kAtModule:DoraemonLocalizedString(@"平台工具")},
                                    @{kBuriedPoint:@"dokit_sdk_platform_ck_filesync"}
                                    ]
                           }[@(pluginType)];
    
    DoraemonManagerPluginTypeModel *model = [DoraemonManagerPluginTypeModel new];
    model.title = dataArray[0][kTitle];
    model.desc = dataArray[1][kDesc];
    model.icon = dataArray[2][kIcon];
    model.pluginName = dataArray[3][kPluginName];
    model.atModule = dataArray[4][kAtModule];
    model.buriedPoint = dataArray[5][kBuriedPoint];
    
    return model;
}

- (void)setStartClass:(NSString *)startClass {
    [[DoraemonCacheManager sharedInstance] saveStartClass:startClass];
}

- (NSString *)startClass{
    return [[DoraemonCacheManager sharedInstance] startClass];
}

- (void)configEntryBtnBlingWithText:(NSString *)text backColor:(UIColor *)backColor {
    [self.entryWindow configEntryBtnBlingWithText:text backColor:backColor];
}

@end

<MSG> add `nonnull` for `shareInstance`

<DFF> @@ -55,7 +55,7 @@ typedef void (^DoraemonPerformanceBlock)(NSDictionary *);
 
 @implementation DoraemonManager
 
-+ (DoraemonManager *)shareInstance{
++ (nonnull DoraemonManager *)shareInstance{
     static dispatch_once_t once;
     static DoraemonManager *instance;
     dispatch_once(&once, ^{

{'commit': 'diff --git a/Doc/iOS_cn_guide.md b/Doc/iOS_cn_guide.md\nindex f580f3d2..6f588d03 100644\n--- a/Doc/iOS_cn_guide.md\n+++ b/Doc/iOS_cn_guide.md\n@@ -95,7 +95,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {\n         // Override point for customization after application launch.\n         \n     #if DEBUG\n-        DoraemonManager.shareInstance()?.install()\n+        DoraemonManager.shareInstance().install()\n     #endif\n         return true\n     }\ndiff --git a/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.h b/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.h\nindex 51ed7c49..562b4a08 100644\n--- a/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.h\n+++ b/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.h\n@@ -69,7 +69,7 @@ typedef NS_ENUM(NSUInteger, DoraemonManagerPluginType) {\n \n @interface DoraemonManager : NSObject\n \n-+ (DoraemonManager *)shareInstance;\n++ (nonnull DoraemonManager *)shareInstance;\n \n - (void)install;\n \ndiff --git a/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.m b/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.m\nindex 6cb7b849..9b51f145 100644\n--- a/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.m\n+++ b/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.m\n@@ -55,7 +55,7 @@ typedef void (^DoraemonPerformanceBlock)(NSDictionary *);\n \n @implementation DoraemonManager\n \n-+ (DoraemonManager *)shareInstance{\n++ (nonnull DoraemonManager *)shareInstance{\n     static dispatch_once_t once;\n     static DoraemonManager *instance;\n     dispatch_once(&once, ^{\n', 'commit_subject': 'add `nonnull` for `shareInstance`', 'repo_name': 'didi/DoraemonKit', 'committer': {'name': 'licd', 'email': 'c83adb9d4a5387b23debf16b29ceac183df2dfc6@dxy.cn', 'time_sec': '1550642492', 'tz_offset': '480', 'date': {'seconds': '1550642492'}}, 'commit_tree': 'c616b7e5345b1e1555208e7bd9b39642e2c213c8', 'commit_message': 'add `nonnull` for `shareInstance`\n', 'language_name': 'C++', 'license': 'apache-2.0', 'hunks': '@@ -55,7 +55,7 @@ typedef void (^DoraemonPerformanceBlock)(NSDictionary *);\n \n @implementation DoraemonManager\n \n-+ (DoraemonManager *)shareInstance{\n++ (nonnull DoraemonManager *)shareInstance{\n     static dispatch_once_t once;\n     static DoraemonManager *instance;\n     dispatch_once(&once, ^{\n', 'addition_count': 1, 'deletion_count': 1, 'src_file': 'a/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.m', 'tgt_file': 'b/iOS/DoraemonKit/Src/Core/Manager/DoraemonManager.m', 'file_extension': '.m', 'before_file': '//\n//  DoraemonManager.m\n//  DoraemonKit\n//\n//  Created by yixiang on 2017/12/11.\n//\n#import <UIKit/UIKit.h>\n#import "DoraemonManager.h"\n#import "DoraemonEntryWindow.h"\n#import "DoraemonCacheManager.h"\n#import "DoraemonStartPluginProtocol.h"\n#import "DoraemonDefine.h"\n#import "DoraemonUtil.h"\n#import "DoraemonHomeWindow.h"\n#import "Doraemoni18NUtil.h"\n#import "DoraemonCrashUncaughtExceptionHandler.h"\n#import "DoraemonCrashSignalExceptionHandler.h"\n#import "DoraemonNSLogManager.h"\n#import "DoraemonNSLogViewController.h"\n#import "DoraemonNSLogListViewController.h"\n#import "DoraemonHomeWindow.h"\n#import "DoraemonStatisticsUtil.h"\n#import "DoraemonANRManager.h"\n#import "DoraemonLargeImageDetectionManager.h"\n#import "DoraemonMockManager.h"\n#import "DoraemonNetFlowOscillogramWindow.h"\n#import "DoraemonNetFlowManager.h"\n#import "DoraemonHealthManager.h"\n\n#if DoraemonWithGPS\n#import "DoraemonGPSMocker.h"\n#endif\n\n\n#if DoraemonWithLogger\n#import "DoraemonCocoaLumberjackLogger.h"\n#import "DoraemonCocoaLumberjackViewController.h"\n#import "DoraemonCocoaLumberjackListViewController.h"\n#endif\n\n#if DoraemonWithWeex\n#import "DoraemonWeexLogDataSource.h"\n#import "DoraemonWeexInfoDataManager.h"\n#endif\n\n\n#define kTitle        @"title"\n#define kDesc         @"desc"\n#define kIcon         @"icon"\n#define kPluginName   @"pluginName"\n#define kAtModule     @"atModule"\n#define kBuriedPoint  @"buriedPoint"\n\n@implementation DoraemonManagerPluginTypeModel\n\n@implementation DoraemonManager\n\n+ (DoraemonManager *)shareInstance{\n    static dispatch_once_t once;\n    static DoraemonManager *instance;\n    dispatch_once(&once, ^{\n\n@property (nonatomic, strong) DoraemonEntryWindow *entryWindow;\n\n@property (nonatomic, strong) NSMutableArray *startPlugins;\n\n@property (nonatomic, copy) DoraemonANRBlock anrBlock;\n\n@property (nonatomic, copy) DoraemonPerformanceBlock performanceBlock;\n\n@property (nonatomic, assign) BOOL hasInstall;\n\n// 定制位置\n@property (nonatomic) CGPoint startingPosition;\n\n@end\n\n@implementation DoraemonManager\n\n+ (nonnull DoraemonManager *)shareInstance{\n    static dispatch_once_t once;\n    static DoraemonManager *instance;\n    dispatch_once(&once, ^{\n        instance = [[DoraemonManager alloc] init];\n    });\n    return instance;\n}\n\n- (instancetype)init{\n    self = [super init];\n    if (self) {\n        _autoDock = YES;\n        _keyBlockDic = [[NSMutableDictionary alloc] init];\n    }\n    return self;\n}\n\n- (void)install{\n    //启用默认位置\n    CGPoint defaultPosition = DoraemonStartingPosition;\n    CGSize size = [UIScreen mainScreen].bounds.size;\n    if (size.width > size.height) {\n        defaultPosition = DoraemonFullScreenStartingPosition;\n    }\n    [self installWithStartingPosition:defaultPosition];\n}\n\n- (void)installWithPid:(NSString *)pId{\n    self.pId = pId;\n    [self install];\n}\n\n- (void)installWithMockDomain:(NSString *)mockDomain{\n    self.mockDomain = mockDomain;\n    [self install];\n}\n\n- (void)installWithStartingPosition:(CGPoint) position{\n    _startingPosition = position;\n    [self installWithCustomBlock:^{\n        //什么也没发生\n    }];\n}\n\n- (void)installWithCustomBlock:(void(^)(void))customBlock{\n    //保证install只执行一次\n    if (_hasInstall) {\n        return;\n    }\n    _hasInstall = YES;\n    for (int i=0; i<_startPlugins.count; i++) {\n        NSString *pluginName = _startPlugins[i];\n        Class pluginClass = NSClassFromString(pluginName);\n        id<DoraemonStartPluginProtocol> plugin = [[pluginClass alloc] init];\n        if (plugin) {\n            [plugin startPluginDidLoad];\n        }\n    }\n\n    [self initData];\n    customBlock();\n\n    [self initEntry:self.startingPosition];\n    \n    //根据开关判断是否收集Crash日志\n    if ([[DoraemonCacheManager sharedInstance] crashSwitch]) {\n        [DoraemonCrashUncaughtExceptionHandler registerHandler];\n        [DoraemonCrashSignalExceptionHandler registerHandler];\n    }\n    //根据开关判断是否开启流量监控\n    if ([[DoraemonCacheManager sharedInstance] netFlowSwitch]) {\n        [[DoraemonNetFlowManager shareInstance] canInterceptNetFlow:YES];\n        //[[DoraemonNetFlowOscillogramWindow shareInstance] show];\n    }\n\n    //重新启动的时候，把帧率、CPU、内存和流量监控关闭\n    [[DoraemonCacheManager sharedInstance] saveFpsSwitch:NO];\n    [[DoraemonCacheManager sharedInstance] saveCpuSwitch:NO];\n    [[DoraemonCacheManager sharedInstance] saveMemorySwitch:NO];\n\n#if DoraemonWithGPS\n    //开启mockGPS功能\n    if ([[DoraemonCacheManager sharedInstance] mockGPSSwitch]) {\n        CLLocationCoordinate2D coordinate = [[DoraemonCacheManager sharedInstance] mockCoordinate];\n        CLLocation *loc = [[CLLocation alloc] initWithLatitude:coordinate.latitude longitude:coordinate.longitude];\n        [[DoraemonGPSMocker shareInstance] mockPoint:loc];\n    }\n#endif\n\n    \n    //开启NSLog监控功能\n    if ([[DoraemonCacheManager sharedInstance] nsLogSwitch]) {\n        [[DoraemonNSLogManager sharedInstance] startNSLogMonitor];\n    }\n    \n#if DoraemonWithLogger\n    //开启CocoaLumberjack监控\n    if ([[DoraemonCacheManager sharedInstance] loggerSwitch]) {\n        [[DoraemonCocoaLumberjackLogger sharedInstance] startMonitor];\n    }\n#endif\n    \n    [[DoraemonANRManager sharedInstance] addANRBlock:^(NSDictionary *anrInfo) {\n        if (self.anrBlock) {\n            self.anrBlock(anrInfo);\n        }\n    }];\n    \n    //外部设置大图检测的数值\n    if (_bigImageDetectionSize > 0){\n        [DoraemonLargeImageDetectionManager shareInstance].minimumDetectionSize = _bigImageDetectionSize;\n    }\n    \n    //统计开源项目使用量 不用于任何恶意行为\n    [[DoraemonStatisticsUtil shareInstance] upLoadUserInfo];\n    \n    //拉取最新的mock数据\n    [[DoraemonMockManager sharedInstance] queryMockData:^(int flag) {\n        DoKitLog(@"mock get data, flag == %i",flag);\n    }];\n    \n    //Weex工具的初始化\n#if DoraemonWithWeex\n    [DoraemonWeexLogDataSource shareInstance];\n    [DoraemonWeexInfoDataManager shareInstance];\n#endif\n    \n    //开启健康体检\n    if ([[DoraemonCacheManager sharedInstance] healthStart]) {\n        [[DoraemonHealthManager sharedInstance] startHealthCheck];\n    }\n    \n}\n\n\n/**\n 初始化内置工具数据\n */\n- (void)initData{\n    #pragma mark - 平台工具\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonMockPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonHealthPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonFileSyncPlugin];\n    \n    #pragma mark - 常用工具\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonAppSettingPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonAppInfoPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonSandboxPlugin];\n#if DoraemonWithGPS\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonGPSPlugin];\n#endif\n\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonH5Plugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonDeleteLocalDataPlugin];\n    \n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonNSLogPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonNSUserDefaultsPlugin];\n#if DoraemonWithLogger\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonCocoaLumberjackPlugin];\n#endif\n    \n#if DoraemonWithDatabase\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonDatabasePlugin];\n#endif\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonJavaScriptPlugin];\n    \n    #pragma mark - 性能检测\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonFPSPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonCPUPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonMemoryPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonNetFlowPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonCrashPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonSubThreadUICheckPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonANRPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonLargeImageFilter];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonWeakNetworkPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonStartTimePlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonUIProfilePlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonTimeProfilePlugin];\n#if DoraemonWithLoad\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonMethodUseTimePlugin];\n#endif\n#if DoraemonWithMLeaksFinder\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonMemoryLeakPlugin];\n#endif\n    \n    #pragma mark - 视觉工具\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonColorPickPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonViewCheckPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonViewAlignPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonViewMetricsPlugin];\n    [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonHierarchyPlugin];\n    \n    #pragma mark - Weex专项工具\n    #if DoraemonWithWeex\n        [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonWeexLogPlugin];\n        [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonWeexStoragePlugin];\n        [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonWeexInfoPlugin];\n        [self addPluginWithPluginType:DoraemonManagerPluginType_DoraemonWeexDevToolPlugin];\n    #endif\n}\n\n/**\n 初始化工具入口\n */\n- (void)initEntry:(CGPoint) startingPosition{\n    _entryWindow = [[DoraemonEntryWindow alloc] initWithStartPoint:startingPosition];\n    [_entryWindow show];\n    if(_autoDock){\n        [_entryWindow setAutoDock:YES];\n    }\n}\n\n- (void)addStartPlugin:(NSString *)pluginName{\n    if (!_startPlugins) {\n        _startPlugins = [[NSMutableArray alloc] init];\n    }\n    [_startPlugins addObject:pluginName];\n}\n\n- (void)addPluginWithPluginType:(DoraemonManagerPluginType)pluginType\n{\n    DoraemonManagerPluginTypeModel *model = [self getDefaultPluginDataWithPluginType:pluginType];\n    [self addPluginWithTitle:model.title icon:model.icon desc:model.desc pluginName:model.pluginName atModule:model.atModule buriedPoint:model.buriedPoint];\n}\n\n// out 1\n- (void)addPluginWithTitle:(NSString *)title icon:(NSString *)iconName desc:(NSString *)desc pluginName:(NSString *)entryName atModule:(NSString *)moduleName{\n    [self addPluginWithTitle:title icon:iconName desc:desc pluginName:entryName atModule:moduleName buriedPoint:@"dokit_sdk_business_ck"];\n}\n\n- (void)addPluginWithTitle:(NSString *)title icon:(NSString *)iconName desc:(NSString *)desc pluginName:(NSString *)entryName atModule:(NSString *)moduleName buriedPoint:(NSString *)buriedPoint{\n    \n    NSMutableDictionary *pluginDic = [self foundGroupWithModule:moduleName];\n    pluginDic[@"key"] = [NSString stringWithFormat:@"%@-%@-%@-%@",moduleName,title,iconName,desc];\n    pluginDic[@"name"] = title;\n    pluginDic[@"icon"] = iconName;\n    pluginDic[@"desc"] = desc;\n    pluginDic[@"pluginName"] = entryName;\n    pluginDic[@"buriedPoint"] = buriedPoint;\n    pluginDic[@"show"] = @1;\n}\n\n// out 2\n- (void)addPluginWithTitle:(NSString *)title icon:(NSString *)iconName desc:(NSString *)desc pluginName:(NSString *)entryName atModule:(NSString *)moduleName handle:(void (^)(NSDictionary *))handleBlock\n{\n    NSMutableDictionary *pluginDic = [self foundGroupWithModule:moduleName];\n    pluginDic[@"key"] = [NSString stringWithFormat:@"%@-%@-%@-%@",moduleName,title,iconName,desc];\n    pluginDic[@"name"] = title;\n    pluginDic[@"icon"] = iconName;\n    pluginDic[@"desc"] = desc;\n    pluginDic[@"pluginName"] = entryName;\n    [_keyBlockDic setValue:[handleBlock copy] forKey:pluginDic[@"key"]];\n    pluginDic[@"buriedPoint"] = @"dokit_sdk_business_ck";\n    pluginDic[@"show"] = @1;\n\n}\n\n- (void)addPluginWithTitle:(NSString *)title image:(UIImage *)image desc:(NSString *)desc pluginName:(NSString *)entryName atModule:(NSString *)moduleName handle:(void (^)(NSDictionary * _Nonnull))handleBlock {\n    NSMutableDictionary *pluginDic = [self foundGroupWithModule:moduleName];\n    pluginDic[@"key"] = [NSString stringWithFormat:@"%@-%@-%@",moduleName,title,desc];\n    pluginDic[@"name"] = title;\n    pluginDic[@"image"] = image;\n    pluginDic[@"desc"] = desc;\n    pluginDic[@"pluginName"] = entryName;\n    if (handleBlock) {\n        [_keyBlockDic setValue:[handleBlock copy] forKey:pluginDic[@"key"]];\n    }\n    pluginDic[@"buriedPoint"] = @"dokit_sdk_business_ck";\n    pluginDic[@"show"] = @1;\n}\n\n- (NSMutableDictionary *)foundGroupWithModule:(NSString *)module\n{\n    NSMutableDictionary *pluginDic = [NSMutableDictionary dictionary];\n    pluginDic[@"moduleName"] = module;\n    __block BOOL hasModule = NO;\n    [self.dataArray enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {\n        NSDictionary *moduleDic = obj;\n        NSString *moduleName = moduleDic[@"moduleName"];\n        if ([moduleName isEqualToString:module]) {\n            hasModule = YES;\n            NSMutableArray *pluginArray = moduleDic[@"pluginArray"];\n            if (pluginArray) {\n                [pluginArray addObject:pluginDic];\n            }\n            [moduleDic setValue:pluginArray forKey:@"pluginArray"];\n            *stop = YES;\n        }\n    }];\n    if (!hasModule) {\n        NSMutableArray *pluginArray = [[NSMutableArray alloc] initWithObjects:pluginDic, nil];\n        [self registerPluginArray:pluginArray withModule:module];\n    }\n    return pluginDic;\n}\n- (void)removePluginWithPluginType:(DoraemonManagerPluginType)pluginType\n{\n    DoraemonManagerPluginTypeModel *model = [self getDefaultPluginDataWithPluginType:pluginType];\n    [self removePluginWithPluginName:model.pluginName atModule:model.atModule];\n}\n\n- (void)removePluginWithPluginName:(NSString *)pluginName atModule:(NSString *)moduleName{\n    [self unregisterPlugin:pluginName withModule:moduleName];\n}\n\n- (void)registerPluginArray:(NSMutableArray*)array withModule:(NSString*)moduleName{\n    if (!_dataArray){\n        _dataArray = [[NSMutableArray alloc]init];\n    }\n    NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];\n    [dic setValue:moduleName forKey:@"moduleName"];\n    [dic setValue:array forKey:@"pluginArray"];\n    [_dataArray addObject:dic];\n}\n\n- (void)unregisterPlugin:(NSString*)pluginName withModule:(NSString*)moduleName{\n    if (!_dataArray){\n        return;\n    }\n    id object;\n    for (object in _dataArray) {\n        NSString *tempModuleName = [((NSMutableDictionary *)object) valueForKey:@"moduleName"];\n        if ([tempModuleName isEqualToString:moduleName]) {\n            NSMutableArray *tempPluginArray = [((NSMutableDictionary *)object) valueForKey:@"pluginArray"];\n            id pluginObject;\n            for (pluginObject in tempPluginArray) {\n                NSString *tempPluginName = [((NSMutableDictionary *)pluginObject) valueForKey:@"pluginName"];\n                if ([tempPluginName isEqualToString:pluginName]) {\n                    [tempPluginArray removeObject:pluginObject];\n                    return;\n                }\n            }\n        }\n    }\n}\n\n- (BOOL)isShowDoraemon{\n    if (!_entryWindow) {\n        return NO;\n    }\n    return !_entryWindow.hidden;\n}\n\n- (void)showDoraemon{\n    if (_entryWindow.hidden) {\n        _entryWindow.hidden = NO;\n    }\n}\n\n- (void)hiddenDoraemon{\n    if (!_entryWindow.hidden) {\n        _entryWindow.hidden = YES;\n     }\n}\n\n\n- (void)addH5DoorBlock:(void(^)(NSString *h5Url))block{\n    self.h5DoorBlock = block;\n}\n\n- (void)addANRBlock:(void(^)(NSDictionary *anrDic))block{\n    self.anrBlock = block;\n}\n\n- (void)addPerformanceBlock:(void(^)(NSDictionary *performanceDic))block{\n    self.performanceBlock = block;\n}\n\n- (void)addWebpHandleBlock:(UIImage *(^)(NSString *filePath))block{\n    self.webpHandleBlock = block;\n}\n\n- (void)hiddenHomeWindow{\n    [[DoraemonHomeWindow shareInstance] hide];\n}\n\n#pragma mark - default data\n- (DoraemonManagerPluginTypeModel *)getDefaultPluginDataWithPluginType:(DoraemonManagerPluginType)pluginType\n{\n    NSArray *dataArray = @{\n                           @(DoraemonManagerPluginType_DoraemonWeexLogPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"日志")},\n                                   @{kDesc:@"Weex log"},\n                                   @{kIcon:@"doraemon_log"},\n                                   @{kPluginName:@"DoraemonWeexLogPlugin"},\n                                   @{kAtModule:@"Weex"},\n                                   @{kBuriedPoint:@"dokit_sdk_weex_ck_log"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonWeexStoragePlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"缓存")},\n                                   @{kDesc:@"weex storage"},\n                                   @{kIcon:@"doraemon_file"},\n                                   @{kPluginName:@"DoraemonWeexStoragePlugin"},\n                                   @{kAtModule:@"Weex"},\n                                   @{kBuriedPoint:@"dokit_sdk_weex_ck_storage"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonWeexInfoPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"信息")},\n                                   @{kDesc:@"weex info"},\n                                   @{kIcon:@"doraemon_app_info"},\n                                   @{kPluginName:@"DoraemonWeexInfoPlugin"},\n                                   @{kAtModule:@"Weex"},\n                                   @{kBuriedPoint:@"dokit_sdk_weex_ck_vessel"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonWeexDevToolPlugin) : @[\n                                   @{kTitle:@"DevTool"},\n                                   @{kDesc:@"weex devtool"},\n                                   @{kIcon:@"doraemon_default"},\n                                   @{kPluginName:@"DoraemonWeexDevTooloPlugin"},\n                                   @{kAtModule:@"Weex"},\n                                   @{kBuriedPoint:@"dokit_sdk_weex_ck_devtool"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonAppSettingPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"应用设置")},\n                                   @{kDesc:DoraemonLocalizedString(@"应用设置")},\n                                   @{kIcon:@"doraemon_setting"},\n                                   @{kPluginName:@"DoraemonAppSettingPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_setting"}\n                                    ],\n                           @(DoraemonManagerPluginType_DoraemonAppInfoPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"App信息")},\n                                   @{kDesc:DoraemonLocalizedString(@"App信息")},\n                                   @{kIcon:@"doraemon_app_info"},\n                                   @{kPluginName:@"DoraemonAppInfoPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_appinfo"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonSandboxPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"沙盒浏览器")},\n                                   @{kDesc:DoraemonLocalizedString(@"沙盒浏览器")},\n                                   @{kIcon:@"doraemon_file"},\n                                   @{kPluginName:@"DoraemonSandboxPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_sandbox"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonGPSPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"Mock GPS")},\n                                   @{kDesc:DoraemonLocalizedString(@"Mock GPS")},\n                                   @{kIcon:@"doraemon_mock_gps"},\n                                   @{kPluginName:@"DoraemonGPSPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_gps"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonH5Plugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"H5任意门")},\n                                   @{kDesc:DoraemonLocalizedString(@"H5任意门")},\n                                   @{kIcon:@"doraemon_h5"},\n                                   @{kPluginName:@"DoraemonH5Plugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_h5"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonDeleteLocalDataPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"清理缓存")},\n                                   @{kDesc:DoraemonLocalizedString(@"清理缓存")},\n                                   @{kIcon:@"doraemon_qingchu"},\n                                   @{kPluginName:@"DoraemonDeleteLocalDataPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_cache"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonNSLogPlugin) : @[\n                                   @{kTitle:@"NSLog"},\n                                   @{kDesc:@"NSLog"},\n                                   @{kIcon:@"doraemon_nslog"},\n                                   @{kPluginName:@"DoraemonNSLogPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_log"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonCocoaLumberjackPlugin) : @[\n                                   @{kTitle:@"Lumberjack"},\n                                   @{kDesc:DoraemonLocalizedString(@"Lumberjack")},\n                                   @{kIcon:@"doraemon_log"},\n                                   @{kPluginName:@"DoraemonCocoaLumberjackPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_lumberjack"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonDatabasePlugin) : @[\n                                   @{kTitle:@"DBView"},\n                                   @{kDesc:DoraemonLocalizedString(@"数据库预览")},\n                                   @{kIcon:@"doraemon_database"},\n                                   @{kPluginName:@"DoraemonDatabasePlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_dbview"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonNSUserDefaultsPlugin) : @[\n                                   @{kTitle:@"UserDefaults"},\n                                   @{kDesc:@"UserDefaults"},\n                                   @{kIcon:@"doraemon_database"},\n                                   @{kPluginName:@"DoraemonNSUserDefaultsPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_userdefault"}\n                           ],\n                           @(DoraemonManagerPluginType_DoraemonJavaScriptPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"JS脚本")},\n                                   @{kDesc:DoraemonLocalizedString(@"JS脚本")},\n                                   @{kIcon:@"doraemon_js"},\n                                   @{kPluginName:@"DoraemonJavaScriptPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"常用工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_js"}\n                           ],\n                           \n                           // 性能检测\n                           @(DoraemonManagerPluginType_DoraemonFPSPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"帧率")},\n                                   @{kDesc:DoraemonLocalizedString(@"帧率")},\n                                   @{kIcon:@"doraemon_fps"},\n                                   @{kPluginName:@"DoraemonFPSPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},\n                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_fps"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonCPUPlugin) : @[\n                                   @{kTitle:@"CPU"},\n                                   @{kDesc:DoraemonLocalizedString(@"CPU")},\n                                   @{kIcon:@"doraemon_cpu"},\n                                   @{kPluginName:@"DoraemonCPUPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},\n                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_cpu"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonMemoryPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"内存")},\n                                   @{kDesc:DoraemonLocalizedString(@"内存")},\n                                   @{kIcon:@"doraemon_memory"},\n                                   @{kPluginName:@"DoraemonMemoryPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},\n                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_arm"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonNetFlowPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"网络")},\n                                   @{kDesc:DoraemonLocalizedString(@"网络监控")},\n                                   @{kIcon:@"doraemon_net"},\n                                   @{kPluginName:@"DoraemonNetFlowPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},\n                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_network"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonCrashPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"Crash")},\n                                   @{kDesc:DoraemonLocalizedString(@"Crash")},\n                                   @{kIcon:@"doraemon_crash"},\n                                   @{kPluginName:@"DoraemonCrashPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},\n                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_crash"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonSubThreadUICheckPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"子线程UI")},\n                                   @{kDesc:DoraemonLocalizedString(@"子线程UI")},\n                                   @{kIcon:@"doraemon_ui"},\n                                   @{kPluginName:@"DoraemonSubThreadUICheckPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},\n                                   @{kBuriedPoint:@"dokit_sdk_comm_ck_child_thread"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonANRPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"卡顿")},\n                                   @{kDesc:DoraemonLocalizedString(@"卡顿")},\n                                   @{kIcon:@"doraemon_kadun"},\n                                   @{kPluginName:@"DoraemonANRPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},\n                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_block"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonMethodUseTimePlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"Load耗时")},\n                                   @{kDesc:DoraemonLocalizedString(@"Load耗时")},\n                                   @{kIcon:@"doraemon_method_use_time"},\n                                   @{kPluginName:@"DoraemonMethodUseTimePlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},\n                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_load"}\n                                   ],\n                           \n                           @(DoraemonManagerPluginType_DoraemonLargeImageFilter) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"大图检测")},\n                                   @{kDesc:DoraemonLocalizedString(@"大图检测")},\n                                   @{kIcon:@"doraemon_net"},\n                                   @{kPluginName:@"DoraemonLargeImagePlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},\n                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_img"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonStartTimePlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"启动耗时")},\n                                   @{kDesc:DoraemonLocalizedString(@"启动耗时")},\n                                   @{kIcon:@"doraemon_app_start_time"},\n                                   @{kPluginName:@"DoraemonStartTimePlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},\n                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_appstart_coast"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonMemoryLeakPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"内存泄漏")},\n                                   @{kDesc:DoraemonLocalizedString(@"内存泄漏统计")},\n                                   @{kIcon:@"doraemon_memory_leak"},\n                                   @{kPluginName:@"DoraemonMLeaksFinderPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},\n                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_leak"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonUIProfilePlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"UI层级")},\n                                   @{kDesc:DoraemonLocalizedString(@"UI层级s")},\n                                   @{kIcon:@"doraemon_view_level"},\n                                   @{kPluginName:@"DoraemonUIProfilePlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},\n                                   @{kBuriedPoint:@"dokit_sdk_ui_ck_hierarchy"}\n                           ],\n                           @(DoraemonManagerPluginType_DoraemonTimeProfilePlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"函数耗时")},\n                                   @{kDesc:DoraemonLocalizedString(@"函数耗时统计")},\n                                   @{kIcon:@"doraemon_time_profiler"},\n                                   @{kPluginName:@"DoraemonTimeProfilerPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"性能检测")},\n                                   @{kBuriedPoint:@"dokit_sdk_performance_ck_method_coast"}\n                           ],\n                           @(DoraemonManagerPluginType_DoraemonWeakNetworkPlugin) : @[\n                                     @{kTitle:DoraemonLocalizedString(@"模拟弱网")},\n                                     @{kDesc:DoraemonLocalizedString(@"模拟弱网测试")},\n                                     @{kIcon:@"doraemon_weaknet"},\n                                     @{kPluginName:@"DoraemonWeakNetworkPlugin"},\n                                     @{kAtModule:DoraemonLocalizedString(@"性能检测")},\n                                     @{kBuriedPoint:@"dokit_sdk_comm_ck_weaknetwork"}\n                             ],\n                           // 视觉工具\n                           @(DoraemonManagerPluginType_DoraemonColorPickPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"取色器")},\n                                   @{kDesc:DoraemonLocalizedString(@"取色器")},\n                                   @{kIcon:@"doraemon_straw"},\n                                   @{kPluginName:@"DoraemonColorPickPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"视觉工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_ui_ck_color_pick"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonViewCheckPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"组件检查")},\n                                   @{kDesc:DoraemonLocalizedString(@"组件检查")},\n                                   @{kIcon:@"doraemon_view_check"},\n                                   @{kPluginName:@"DoraemonViewCheckPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"视觉工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_ui_ck_widget"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonViewAlignPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"对齐标尺")},\n                                   @{kDesc:DoraemonLocalizedString(@"对齐标尺")},\n                                   @{kIcon:@"doraemon_align"},\n                                   @{kPluginName:@"DoraemonViewAlignPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"视觉工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_ui_ck_aligin_scaleplate"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonViewMetricsPlugin) : @[\n                                   @{kTitle:DoraemonLocalizedString(@"布局边框")},\n                                   @{kDesc:DoraemonLocalizedString(@"布局边框")},\n                                   @{kIcon:@"doraemon_viewmetrics"},\n                                   @{kPluginName:@"DoraemonViewMetricsPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"视觉工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_ui_ck_border"}\n                                   ],\n                          @(DoraemonManagerPluginType_DoraemonHierarchyPlugin) : @[\n                                           @{kTitle:DoraemonLocalizedString(@"UI结构")},\n                                           @{kDesc:DoraemonLocalizedString(@"显示UI结构")},\n                                           @{kIcon:@"doraemon_view_level"},\n                                           @{kPluginName:@"DoraemonHierarchyPlugin"},\n                                           @{kAtModule:DoraemonLocalizedString(@"视觉工具")},\n                                           @{kBuriedPoint:@"dokit_sdk_ui_ck_widget_3d"}\n                                   ],\n                           // 平台工具\n                           @(DoraemonManagerPluginType_DoraemonMockPlugin) : @[\n                                @{kTitle:DoraemonLocalizedString(@"Mock数据")},\n                                   @{kDesc:DoraemonLocalizedString(@"Mock数据")},\n                                   @{kIcon:@"doraemon_mock"},\n                                   @{kPluginName:@"DoraemonMockPlugin"},\n                                   @{kAtModule:DoraemonLocalizedString(@"平台工具")},\n                                   @{kBuriedPoint:@"dokit_sdk_platform_ck_mock"}\n                                   ],\n                           @(DoraemonManagerPluginType_DoraemonHealthPlugin) : @[\n                               @{kTitle:DoraemonLocalizedString(@"健康体检")},\n                                  @{kDesc:DoraemonLocalizedString(@"健康体检中心")},\n                                  @{kIcon:@"doraemon_health"},\n                                  @{kPluginName:@"DoraemonHealthPlugin"},\n                                  @{kAtModule:DoraemonLocalizedString(@"平台工具")},\n                                  @{kBuriedPoint:@"dokit_sdk_platform_ck_health"}\n                                  ],\n                           @(DoraemonManagerPluginType_DoraemonFileSyncPlugin) : @[\n                                @{kTitle:DoraemonLocalizedString(@"文件同步")},\n                                    @{kDesc:DoraemonLocalizedString(@"文件同步")},\n                                    @{kIcon:@"doraemon_file_sync"},\n                                    @{kPluginName:@"DoraemonFileSyncPlugin"},\n                                    @{kAtModule:DoraemonLocalizedString(@"平台工具")},\n                                    @{kBuriedPoint:@"dokit_sdk_platform_ck_filesync"}\n                                    ]\n                           }[@(pluginType)];\n    \n    DoraemonManagerPluginTypeModel *model = [DoraemonManagerPluginTypeModel new];\n    model.title = dataArray[0][kTitle];\n    model.desc = dataArray[1][kDesc];\n    model.icon = dataArray[2][kIcon];\n    model.pluginName = dataArray[3][kPluginName];\n    model.atModule = dataArray[4][kAtModule];\n    model.buriedPoint = dataArray[5][kBuriedPoint];\n    \n    return model;\n}\n\n- (void)setStartClass:(NSString *)startClass {\n    [[DoraemonCacheManager sharedInstance] saveStartClass:startClass];\n}\n\n- (NSString *)startClass{\n    return [[DoraemonCacheManager sharedInstance] startClass];\n}\n\n- (void)configEntryBtnBlingWithText:(NSString *)text backColor:(UIColor *)backColor {\n    [self.entryWindow configEntryBtnBlingWithText:text backColor:backColor];\n}\n\n@end\n', 'message': 'add `nonnull` for `shareInstance`\n', 'author_name': 'licd', 'lang': 'm'}