Browse Source

朋友圈

桂欢 2 years ago
parent
commit
3ac1579f32
100 changed files with 3136 additions and 0 deletions
  1. 428 0
      SLAiELTS/SLAiELTS.xcodeproj/project.pbxproj
  2. 44 0
      SLAiELTS/SLAiELTS/AppMarcos/GlobalDefines.h
  3. 326 0
      SLAiELTS/SLAiELTS/Tool/LEETheme/LEETheme.h
  4. 1572 0
      SLAiELTS/SLAiELTS/Tool/LEETheme/LEETheme.m
  5. 50 0
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmojiLabel.h
  6. 716 0
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmojiLabel.m
  7. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_100@2x.png
  8. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_101@2x.png
  9. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_102@2x.png
  10. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_103@2x.png
  11. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_104@2x.png
  12. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_105@2x.png
  13. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_10@2x.png
  14. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_11@2x.png
  15. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_12@2x.png
  16. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_13@2x.png
  17. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_14@2x.png
  18. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_15@2x.png
  19. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_16@2x.png
  20. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_17@2x.png
  21. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_18@2x.png
  22. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_19@2x.png
  23. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_1@2x.png
  24. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_20@2x.png
  25. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_21@2x.png
  26. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_22@2x.png
  27. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_23@2x.png
  28. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_24@2x.png
  29. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_25@2x.png
  30. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_26@2x.png
  31. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_27@2x.png
  32. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_28@2x.png
  33. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_29@2x.png
  34. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_2@2x.png
  35. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_30@2x.png
  36. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_31@2x.png
  37. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_32@2x.png
  38. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_33@2x.png
  39. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_34@2x.png
  40. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_35@2x.png
  41. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_36@2x.png
  42. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_37@2x.png
  43. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_38@2x.png
  44. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_39@2x.png
  45. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_3@2x.png
  46. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_40@2x.png
  47. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_41@2x.png
  48. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_42@2x.png
  49. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_43@2x.png
  50. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_44@2x.png
  51. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_45@2x.png
  52. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_46@2x.png
  53. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_47@2x.png
  54. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_48@2x.png
  55. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_49@2x.png
  56. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_4@2x.png
  57. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_50@2x.png
  58. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_51@2x.png
  59. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_52@2x.png
  60. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_53@2x.png
  61. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_54@2x.png
  62. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_55@2x.png
  63. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_56@2x.png
  64. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_57@2x.png
  65. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_58@2x.png
  66. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_59@2x.png
  67. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_5@2x.png
  68. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_60@2x.png
  69. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_61@2x.png
  70. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_62@2x.png
  71. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_63@2x.png
  72. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_64@2x.png
  73. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_65@2x.png
  74. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_66@2x.png
  75. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_67@2x.png
  76. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_68@2x.png
  77. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_69@2x.png
  78. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_6@2x.png
  79. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_70@2x.png
  80. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_71@2x.png
  81. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_72@2x.png
  82. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_73@2x.png
  83. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_74@2x.png
  84. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_75@2x.png
  85. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_76@2x.png
  86. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_77@2x.png
  87. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_78@2x.png
  88. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_79@2x.png
  89. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_7@2x.png
  90. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_80@2x.png
  91. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_81@2x.png
  92. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_82@2x.png
  93. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_83@2x.png
  94. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_84@2x.png
  95. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_85@2x.png
  96. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_86@2x.png
  97. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_87@2x.png
  98. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_88@2x.png
  99. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_89@2x.png
  100. BIN
      SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_8@2x.png

+ 428 - 0
SLAiELTS/SLAiELTS.xcodeproj/project.pbxproj

@@ -122,6 +122,46 @@
 		3DA5AF7829B96B33009E4925 /* SLBaseMainView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DA5AF7729B96B33009E4925 /* SLBaseMainView.m */; };
 		3DA5AF7C29B96B55009E4925 /* SLPageViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DA5AF7A29B96B55009E4925 /* SLPageViewModel.m */; };
 		3DA5AF7F29B96E11009E4925 /* SLPageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DA5AF7E29B96E11009E4925 /* SLPageModel.m */; };
+		3DB0AE1629D6B64200671744 /* NullSafe.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB0AE1529D6B64200671744 /* NullSafe.m */; };
+		3DB97D3D29D6A86E00B12754 /* SDTimeLineTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D2329D6A86D00B12754 /* SDTimeLineTableViewController.m */; };
+		3DB97D3E29D6A86E00B12754 /* SDTimeLineCellModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D2629D6A86D00B12754 /* SDTimeLineCellModel.m */; };
+		3DB97D3F29D6A86E00B12754 /* SDTimeLineCellOperationMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D2A29D6A86D00B12754 /* SDTimeLineCellOperationMenu.m */; };
+		3DB97D4029D6A86E00B12754 /* SDTimeLineCellCommentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D2D29D6A86D00B12754 /* SDTimeLineCellCommentView.m */; };
+		3DB97D4129D6A86E00B12754 /* SDTimeLineRefreshFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D2F29D6A86D00B12754 /* SDTimeLineRefreshFooter.m */; };
+		3DB97D4229D6A86E00B12754 /* SDTimeLineTableHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D3229D6A86D00B12754 /* SDTimeLineTableHeaderView.m */; };
+		3DB97D4329D6A86E00B12754 /* SDTimeLineCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D3629D6A86D00B12754 /* SDTimeLineCell.m */; };
+		3DB97D4429D6A86E00B12754 /* SDTimeLineRefreshHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D3829D6A86D00B12754 /* SDTimeLineRefreshHeader.m */; };
+		3DB97D4529D6A86E00B12754 /* SDWeiXinPhotoContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D3B29D6A86D00B12754 /* SDWeiXinPhotoContainerView.m */; };
+		3DB97D4C29D6AAC500B12754 /* UIView+SDAutoLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D4729D6AAC500B12754 /* UIView+SDAutoLayout.m */; };
+		3DB97D4D29D6AAC500B12754 /* UITableView+SDAutoTableViewCellHeight.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D4A29D6AAC500B12754 /* UITableView+SDAutoTableViewCellHeight.m */; };
+		3DB97D5129D6AAF900B12754 /* SDBaseRefreshView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D5029D6AAF900B12754 /* SDBaseRefreshView.m */; };
+		3DB97D5A29D6AB2300B12754 /* SDPhotoBrowser.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D5429D6AB2200B12754 /* SDPhotoBrowser.m */; };
+		3DB97D5B29D6AB2300B12754 /* SDWaitingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D5529D6AB2200B12754 /* SDWaitingView.m */; };
+		3DB97D5C29D6AB2300B12754 /* SDBrowserImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D5629D6AB2200B12754 /* SDBrowserImageView.m */; };
+		3DB97D5F29D6AB6400B12754 /* SDBaseTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D5E29D6AB6400B12754 /* SDBaseTableViewController.m */; };
+		3DB97D6B29D6ABC100B12754 /* SDRefreshHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D6429D6ABC000B12754 /* SDRefreshHeaderView.m */; };
+		3DB97D6C29D6ABC100B12754 /* sdRefeshView_arrow@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3DB97D6529D6ABC000B12754 /* sdRefeshView_arrow@2x.png */; };
+		3DB97D6D29D6ABC100B12754 /* UIView+SDExtension.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D6629D6ABC000B12754 /* UIView+SDExtension.m */; };
+		3DB97D6E29D6ABC100B12754 /* SDRefreshFooterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D6729D6ABC000B12754 /* SDRefreshFooterView.m */; };
+		3DB97D6F29D6ABC100B12754 /* SDRefreshView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D6A29D6ABC000B12754 /* SDRefreshView.m */; };
+		3DB97D9529D6ABF000B12754 /* MLEmoji_Expression.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3DB97D7229D6ABEF00B12754 /* MLEmoji_Expression.plist */; };
+		3DB97D9629D6ABF000B12754 /* MLEmoji_Expression.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 3DB97D7329D6ABEF00B12754 /* MLEmoji_Expression.bundle */; };
+		3DB97D9729D6ABF000B12754 /* MLEmoji_ExpressionImage.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3DB97D7429D6ABEF00B12754 /* MLEmoji_ExpressionImage.plist */; };
+		3DB97D9829D6ABF000B12754 /* MLEmojiLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D7529D6ABEF00B12754 /* MLEmojiLabel.m */; };
+		3DB97D9929D6ABF000B12754 /* TTTAttributedLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D7829D6ABEF00B12754 /* TTTAttributedLabel.m */; };
+		3DB97D9A29D6ABF000B12754 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 3DB97D7A29D6ABEF00B12754 /* LICENSE */; };
+		3DB97D9B29D6ABF000B12754 /* NSMutableAttributedString+MLLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D7E29D6ABEF00B12754 /* NSMutableAttributedString+MLLabel.m */; };
+		3DB97D9C29D6ABF000B12754 /* NSString+MLLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D8129D6ABEF00B12754 /* NSString+MLLabel.m */; };
+		3DB97D9D29D6ABF000B12754 /* NSAttributedString+MLLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D8329D6ABEF00B12754 /* NSAttributedString+MLLabel.m */; };
+		3DB97D9E29D6ABF000B12754 /* MLLinkLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D8529D6ABEF00B12754 /* MLLinkLabel.m */; };
+		3DB97D9F29D6ABF000B12754 /* NSAttributedString+MLExpression.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D8829D6ABEF00B12754 /* NSAttributedString+MLExpression.m */; };
+		3DB97DA029D6ABF000B12754 /* MLTextAttachment.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D8929D6ABEF00B12754 /* MLTextAttachment.m */; };
+		3DB97DA129D6ABF000B12754 /* NSString+MLExpression.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D8C29D6ABEF00B12754 /* NSString+MLExpression.m */; };
+		3DB97DA229D6ABF000B12754 /* MLExpressionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D8E29D6ABEF00B12754 /* MLExpressionManager.m */; };
+		3DB97DA329D6ABF000B12754 /* MLLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D8F29D6ABEF00B12754 /* MLLabel.m */; };
+		3DB97DA429D6ABF000B12754 /* MLLabelLayoutManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97D9129D6ABEF00B12754 /* MLLabelLayoutManager.m */; };
+		3DB97DA529D6ABF000B12754 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 3DB97D9429D6ABEF00B12754 /* README.md */; };
+		3DB97DA929D6AC0A00B12754 /* LEETheme.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DB97DA829D6AC0A00B12754 /* LEETheme.m */; };
 		3DF3DAA129B98A7D00CAD3AB /* SLMyView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DF3DA9F29B98A7D00CAD3AB /* SLMyView.m */; };
 		3DF3DAA429B9A68800CAD3AB /* SLBaseCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DF3DAA329B9A68800CAD3AB /* SLBaseCellView.m */; };
 		3DF3DAA829B9A6AA00CAD3AB /* SLBaseCellView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3DF3DAA729B9A6AA00CAD3AB /* SLBaseCellView.xib */; };
@@ -387,6 +427,84 @@
 		3DA5AF7B29B96B55009E4925 /* SLPageViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SLPageViewModel.h; sourceTree = "<group>"; };
 		3DA5AF7D29B96E11009E4925 /* SLPageModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SLPageModel.h; sourceTree = "<group>"; };
 		3DA5AF7E29B96E11009E4925 /* SLPageModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SLPageModel.m; sourceTree = "<group>"; };
+		3DB0AE1529D6B64200671744 /* NullSafe.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NullSafe.m; sourceTree = "<group>"; };
+		3DB97D2229D6A86D00B12754 /* SDTimeLineTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDTimeLineTableViewController.h; sourceTree = "<group>"; };
+		3DB97D2329D6A86D00B12754 /* SDTimeLineTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDTimeLineTableViewController.m; sourceTree = "<group>"; };
+		3DB97D2529D6A86D00B12754 /* SDTimeLineCellModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDTimeLineCellModel.h; sourceTree = "<group>"; };
+		3DB97D2629D6A86D00B12754 /* SDTimeLineCellModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDTimeLineCellModel.m; sourceTree = "<group>"; };
+		3DB97D2929D6A86D00B12754 /* SDTimeLineCellOperationMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDTimeLineCellOperationMenu.h; sourceTree = "<group>"; };
+		3DB97D2A29D6A86D00B12754 /* SDTimeLineCellOperationMenu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDTimeLineCellOperationMenu.m; sourceTree = "<group>"; };
+		3DB97D2C29D6A86D00B12754 /* SDTimeLineCellCommentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDTimeLineCellCommentView.h; sourceTree = "<group>"; };
+		3DB97D2D29D6A86D00B12754 /* SDTimeLineCellCommentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDTimeLineCellCommentView.m; sourceTree = "<group>"; };
+		3DB97D2F29D6A86D00B12754 /* SDTimeLineRefreshFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDTimeLineRefreshFooter.m; sourceTree = "<group>"; };
+		3DB97D3029D6A86D00B12754 /* SDTimeLineRefreshFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDTimeLineRefreshFooter.h; sourceTree = "<group>"; };
+		3DB97D3229D6A86D00B12754 /* SDTimeLineTableHeaderView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDTimeLineTableHeaderView.m; sourceTree = "<group>"; };
+		3DB97D3329D6A86D00B12754 /* SDTimeLineTableHeaderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDTimeLineTableHeaderView.h; sourceTree = "<group>"; };
+		3DB97D3529D6A86D00B12754 /* SDTimeLineCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDTimeLineCell.h; sourceTree = "<group>"; };
+		3DB97D3629D6A86D00B12754 /* SDTimeLineCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDTimeLineCell.m; sourceTree = "<group>"; };
+		3DB97D3829D6A86D00B12754 /* SDTimeLineRefreshHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDTimeLineRefreshHeader.m; sourceTree = "<group>"; };
+		3DB97D3929D6A86D00B12754 /* SDTimeLineRefreshHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDTimeLineRefreshHeader.h; sourceTree = "<group>"; };
+		3DB97D3B29D6A86D00B12754 /* SDWeiXinPhotoContainerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWeiXinPhotoContainerView.m; sourceTree = "<group>"; };
+		3DB97D3C29D6A86D00B12754 /* SDWeiXinPhotoContainerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWeiXinPhotoContainerView.h; sourceTree = "<group>"; };
+		3DB97D4729D6AAC500B12754 /* UIView+SDAutoLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+SDAutoLayout.m"; sourceTree = "<group>"; };
+		3DB97D4829D6AAC500B12754 /* UITableView+SDAutoTableViewCellHeight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITableView+SDAutoTableViewCellHeight.h"; sourceTree = "<group>"; };
+		3DB97D4929D6AAC500B12754 /* SDAutoLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDAutoLayout.h; sourceTree = "<group>"; };
+		3DB97D4A29D6AAC500B12754 /* UITableView+SDAutoTableViewCellHeight.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITableView+SDAutoTableViewCellHeight.m"; sourceTree = "<group>"; };
+		3DB97D4B29D6AAC500B12754 /* UIView+SDAutoLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+SDAutoLayout.h"; sourceTree = "<group>"; };
+		3DB97D4F29D6AAF900B12754 /* SDBaseRefreshView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDBaseRefreshView.h; sourceTree = "<group>"; };
+		3DB97D5029D6AAF900B12754 /* SDBaseRefreshView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDBaseRefreshView.m; sourceTree = "<group>"; };
+		3DB97D5329D6AB2200B12754 /* SDPhotoBrowserConfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDPhotoBrowserConfig.h; sourceTree = "<group>"; };
+		3DB97D5429D6AB2200B12754 /* SDPhotoBrowser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDPhotoBrowser.m; sourceTree = "<group>"; };
+		3DB97D5529D6AB2200B12754 /* SDWaitingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWaitingView.m; sourceTree = "<group>"; };
+		3DB97D5629D6AB2200B12754 /* SDBrowserImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDBrowserImageView.m; sourceTree = "<group>"; };
+		3DB97D5729D6AB2200B12754 /* SDWaitingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWaitingView.h; sourceTree = "<group>"; };
+		3DB97D5829D6AB2200B12754 /* SDPhotoBrowser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDPhotoBrowser.h; sourceTree = "<group>"; };
+		3DB97D5929D6AB2200B12754 /* SDBrowserImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDBrowserImageView.h; sourceTree = "<group>"; };
+		3DB97D5D29D6AB6400B12754 /* SDBaseTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDBaseTableViewController.h; sourceTree = "<group>"; };
+		3DB97D5E29D6AB6400B12754 /* SDBaseTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDBaseTableViewController.m; sourceTree = "<group>"; };
+		3DB97D6129D6ABC000B12754 /* UIView+SDExtension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+SDExtension.h"; sourceTree = "<group>"; };
+		3DB97D6229D6ABC000B12754 /* SDRefreshFooterView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDRefreshFooterView.h; sourceTree = "<group>"; };
+		3DB97D6329D6ABC000B12754 /* SDRefreshView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDRefreshView.h; sourceTree = "<group>"; };
+		3DB97D6429D6ABC000B12754 /* SDRefreshHeaderView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDRefreshHeaderView.m; sourceTree = "<group>"; };
+		3DB97D6529D6ABC000B12754 /* sdRefeshView_arrow@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "sdRefeshView_arrow@2x.png"; sourceTree = "<group>"; };
+		3DB97D6629D6ABC000B12754 /* UIView+SDExtension.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+SDExtension.m"; sourceTree = "<group>"; };
+		3DB97D6729D6ABC000B12754 /* SDRefreshFooterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDRefreshFooterView.m; sourceTree = "<group>"; };
+		3DB97D6829D6ABC000B12754 /* SDRefresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDRefresh.h; sourceTree = "<group>"; };
+		3DB97D6929D6ABC000B12754 /* SDRefreshHeaderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDRefreshHeaderView.h; sourceTree = "<group>"; };
+		3DB97D6A29D6ABC000B12754 /* SDRefreshView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDRefreshView.m; sourceTree = "<group>"; };
+		3DB97D7129D6ABEF00B12754 /* MLEmojiLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MLEmojiLabel.h; sourceTree = "<group>"; };
+		3DB97D7229D6ABEF00B12754 /* MLEmoji_Expression.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = MLEmoji_Expression.plist; sourceTree = "<group>"; };
+		3DB97D7329D6ABEF00B12754 /* MLEmoji_Expression.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = MLEmoji_Expression.bundle; sourceTree = "<group>"; };
+		3DB97D7429D6ABEF00B12754 /* MLEmoji_ExpressionImage.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = MLEmoji_ExpressionImage.plist; sourceTree = "<group>"; };
+		3DB97D7529D6ABEF00B12754 /* MLEmojiLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MLEmojiLabel.m; sourceTree = "<group>"; };
+		3DB97D7729D6ABEF00B12754 /* TTTAttributedLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TTTAttributedLabel.h; sourceTree = "<group>"; };
+		3DB97D7829D6ABEF00B12754 /* TTTAttributedLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TTTAttributedLabel.m; sourceTree = "<group>"; };
+		3DB97D7A29D6ABEF00B12754 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
+		3DB97D7C29D6ABEF00B12754 /* MLLinkLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MLLinkLabel.h; sourceTree = "<group>"; };
+		3DB97D7E29D6ABEF00B12754 /* NSMutableAttributedString+MLLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableAttributedString+MLLabel.m"; sourceTree = "<group>"; };
+		3DB97D7F29D6ABEF00B12754 /* NSString+MLLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MLLabel.h"; sourceTree = "<group>"; };
+		3DB97D8029D6ABEF00B12754 /* NSAttributedString+MLLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributedString+MLLabel.h"; sourceTree = "<group>"; };
+		3DB97D8129D6ABEF00B12754 /* NSString+MLLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+MLLabel.m"; sourceTree = "<group>"; };
+		3DB97D8229D6ABEF00B12754 /* NSMutableAttributedString+MLLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableAttributedString+MLLabel.h"; sourceTree = "<group>"; };
+		3DB97D8329D6ABEF00B12754 /* NSAttributedString+MLLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributedString+MLLabel.m"; sourceTree = "<group>"; };
+		3DB97D8429D6ABEF00B12754 /* MLLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MLLabel.h; sourceTree = "<group>"; };
+		3DB97D8529D6ABEF00B12754 /* MLLinkLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MLLinkLabel.m; sourceTree = "<group>"; };
+		3DB97D8729D6ABEF00B12754 /* NSString+MLExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MLExpression.h"; sourceTree = "<group>"; };
+		3DB97D8829D6ABEF00B12754 /* NSAttributedString+MLExpression.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributedString+MLExpression.m"; sourceTree = "<group>"; };
+		3DB97D8929D6ABEF00B12754 /* MLTextAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MLTextAttachment.m; sourceTree = "<group>"; };
+		3DB97D8A29D6ABEF00B12754 /* MLExpressionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MLExpressionManager.h; sourceTree = "<group>"; };
+		3DB97D8B29D6ABEF00B12754 /* NSAttributedString+MLExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributedString+MLExpression.h"; sourceTree = "<group>"; };
+		3DB97D8C29D6ABEF00B12754 /* NSString+MLExpression.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+MLExpression.m"; sourceTree = "<group>"; };
+		3DB97D8D29D6ABEF00B12754 /* MLTextAttachment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MLTextAttachment.h; sourceTree = "<group>"; };
+		3DB97D8E29D6ABEF00B12754 /* MLExpressionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MLExpressionManager.m; sourceTree = "<group>"; };
+		3DB97D8F29D6ABEF00B12754 /* MLLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MLLabel.m; sourceTree = "<group>"; };
+		3DB97D9129D6ABEF00B12754 /* MLLabelLayoutManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MLLabelLayoutManager.m; sourceTree = "<group>"; };
+		3DB97D9229D6ABEF00B12754 /* MLLabelLayoutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MLLabelLayoutManager.h; sourceTree = "<group>"; };
+		3DB97D9329D6ABEF00B12754 /* MLLabel+Override.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MLLabel+Override.h"; sourceTree = "<group>"; };
+		3DB97D9429D6ABEF00B12754 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
+		3DB97DA729D6AC0A00B12754 /* LEETheme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LEETheme.h; sourceTree = "<group>"; };
+		3DB97DA829D6AC0A00B12754 /* LEETheme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LEETheme.m; sourceTree = "<group>"; };
+		3DB97DAA29D6AC7900B12754 /* GlobalDefines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GlobalDefines.h; sourceTree = "<group>"; };
 		3DF3DA9F29B98A7D00CAD3AB /* SLMyView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SLMyView.m; sourceTree = "<group>"; };
 		3DF3DAA029B98A7D00CAD3AB /* SLMyView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SLMyView.h; sourceTree = "<group>"; };
 		3DF3DAA229B9A68800CAD3AB /* SLBaseCellView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SLBaseCellView.h; sourceTree = "<group>"; };
@@ -522,6 +640,7 @@
 		3D24985F29AC6A7D003C3AFA /* ViewControllers */ = {
 			isa = PBXGroup;
 			children = (
+				3DB97D2029D6A86D00B12754 /* TimeLine */,
 				3DA5AF6B29B88884009E4925 /* MyVC */,
 				3DA5AF6529B8885D009E4925 /* LxVC */,
 				3DA5AF5D29B8873B009E4925 /* Home */,
@@ -554,6 +673,7 @@
 		3D24986E29AC73D2003C3AFA /* AppMarcos */ = {
 			isa = PBXGroup;
 			children = (
+				3DB97DAA29D6AC7900B12754 /* GlobalDefines.h */,
 				3D25108529ADB1E2000AE530 /* YMConstMacro.h */,
 				3D24986F29AC7405003C3AFA /* PrefixHeader.pch */,
 				3D1B9CF429C06EC40008D01A /* SLDefaultMacro.h */,
@@ -700,6 +820,12 @@
 		3D2510AF29AF1943000AE530 /* Tool */ = {
 			isa = PBXGroup;
 			children = (
+				3DB0AE1429D6B64200671744 /* NullSafe */,
+				3DB97DA629D6AC0A00B12754 /* LEETheme */,
+				3DB97D7029D6ABEF00B12754 /* MLEmojiLabel */,
+				3DB97D6029D6ABC000B12754 /* SDRefeshView */,
+				3DB97D5229D6AB2200B12754 /* SDPhotoBrowser */,
+				3DB97D4629D6AAC500B12754 /* SDAutoLayout */,
 				3D796C6629B8305C00B7B28A /* FBKVOController */,
 				3DFEE71629B5E7F9000AA7D5 /* SLAuthorizationManager.h */,
 				3DFEE71529B5E7F9000AA7D5 /* SLAuthorizationManager.m */,
@@ -949,12 +1075,15 @@
 		3DA5AF6329B887D4009E4925 /* BaseVC */ = {
 			isa = PBXGroup;
 			children = (
+				3DB97D4E29D6AAF900B12754 /* BaseRefreshView */,
 				3DA5AF5B29B8843C009E4925 /* SLBaseTabBarController.h */,
 				3DA5AF5A29B8843C009E4925 /* SLBaseTabBarController.m */,
 				3D24986329AC7224003C3AFA /* SLBaseViewController.h */,
 				3D24986429AC7224003C3AFA /* SLBaseViewController.m */,
 				3D25106329AC9694000AE530 /* SLBaseNavigationController.h */,
 				3D25106429AC9694000AE530 /* SLBaseNavigationController.m */,
+				3DB97D5D29D6AB6400B12754 /* SDBaseTableViewController.h */,
+				3DB97D5E29D6AB6400B12754 /* SDBaseTableViewController.m */,
 			);
 			path = BaseVC;
 			sourceTree = "<group>";
@@ -1031,6 +1160,265 @@
 			path = Models;
 			sourceTree = "<group>";
 		};
+		3DB0AE1429D6B64200671744 /* NullSafe */ = {
+			isa = PBXGroup;
+			children = (
+				3DB0AE1529D6B64200671744 /* NullSafe.m */,
+			);
+			path = NullSafe;
+			sourceTree = "<group>";
+		};
+		3DB97D2029D6A86D00B12754 /* TimeLine */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D2129D6A86D00B12754 /* TimeLineController */,
+				3DB97D2429D6A86D00B12754 /* Model */,
+				3DB97D2729D6A86D00B12754 /* Views */,
+			);
+			path = TimeLine;
+			sourceTree = "<group>";
+		};
+		3DB97D2129D6A86D00B12754 /* TimeLineController */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D2229D6A86D00B12754 /* SDTimeLineTableViewController.h */,
+				3DB97D2329D6A86D00B12754 /* SDTimeLineTableViewController.m */,
+			);
+			path = TimeLineController;
+			sourceTree = "<group>";
+		};
+		3DB97D2429D6A86D00B12754 /* Model */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D2529D6A86D00B12754 /* SDTimeLineCellModel.h */,
+				3DB97D2629D6A86D00B12754 /* SDTimeLineCellModel.m */,
+			);
+			path = Model;
+			sourceTree = "<group>";
+		};
+		3DB97D2729D6A86D00B12754 /* Views */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D2829D6A86D00B12754 /* OperationMenu */,
+				3DB97D2B29D6A86D00B12754 /* CommentView */,
+				3DB97D2E29D6A86D00B12754 /* TimeLineRefreshFooter */,
+				3DB97D3129D6A86D00B12754 /* HeaderView */,
+				3DB97D3429D6A86D00B12754 /* Cell */,
+				3DB97D3729D6A86D00B12754 /* TimeLineRefreshHeader */,
+				3DB97D3A29D6A86D00B12754 /* PhotoContainer */,
+			);
+			path = Views;
+			sourceTree = "<group>";
+		};
+		3DB97D2829D6A86D00B12754 /* OperationMenu */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D2929D6A86D00B12754 /* SDTimeLineCellOperationMenu.h */,
+				3DB97D2A29D6A86D00B12754 /* SDTimeLineCellOperationMenu.m */,
+			);
+			path = OperationMenu;
+			sourceTree = "<group>";
+		};
+		3DB97D2B29D6A86D00B12754 /* CommentView */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D2C29D6A86D00B12754 /* SDTimeLineCellCommentView.h */,
+				3DB97D2D29D6A86D00B12754 /* SDTimeLineCellCommentView.m */,
+			);
+			path = CommentView;
+			sourceTree = "<group>";
+		};
+		3DB97D2E29D6A86D00B12754 /* TimeLineRefreshFooter */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D2F29D6A86D00B12754 /* SDTimeLineRefreshFooter.m */,
+				3DB97D3029D6A86D00B12754 /* SDTimeLineRefreshFooter.h */,
+			);
+			path = TimeLineRefreshFooter;
+			sourceTree = "<group>";
+		};
+		3DB97D3129D6A86D00B12754 /* HeaderView */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D3229D6A86D00B12754 /* SDTimeLineTableHeaderView.m */,
+				3DB97D3329D6A86D00B12754 /* SDTimeLineTableHeaderView.h */,
+			);
+			path = HeaderView;
+			sourceTree = "<group>";
+		};
+		3DB97D3429D6A86D00B12754 /* Cell */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D3529D6A86D00B12754 /* SDTimeLineCell.h */,
+				3DB97D3629D6A86D00B12754 /* SDTimeLineCell.m */,
+			);
+			path = Cell;
+			sourceTree = "<group>";
+		};
+		3DB97D3729D6A86D00B12754 /* TimeLineRefreshHeader */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D3829D6A86D00B12754 /* SDTimeLineRefreshHeader.m */,
+				3DB97D3929D6A86D00B12754 /* SDTimeLineRefreshHeader.h */,
+			);
+			path = TimeLineRefreshHeader;
+			sourceTree = "<group>";
+		};
+		3DB97D3A29D6A86D00B12754 /* PhotoContainer */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D3B29D6A86D00B12754 /* SDWeiXinPhotoContainerView.m */,
+				3DB97D3C29D6A86D00B12754 /* SDWeiXinPhotoContainerView.h */,
+			);
+			path = PhotoContainer;
+			sourceTree = "<group>";
+		};
+		3DB97D4629D6AAC500B12754 /* SDAutoLayout */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D4729D6AAC500B12754 /* UIView+SDAutoLayout.m */,
+				3DB97D4829D6AAC500B12754 /* UITableView+SDAutoTableViewCellHeight.h */,
+				3DB97D4929D6AAC500B12754 /* SDAutoLayout.h */,
+				3DB97D4A29D6AAC500B12754 /* UITableView+SDAutoTableViewCellHeight.m */,
+				3DB97D4B29D6AAC500B12754 /* UIView+SDAutoLayout.h */,
+			);
+			path = SDAutoLayout;
+			sourceTree = "<group>";
+		};
+		3DB97D4E29D6AAF900B12754 /* BaseRefreshView */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D4F29D6AAF900B12754 /* SDBaseRefreshView.h */,
+				3DB97D5029D6AAF900B12754 /* SDBaseRefreshView.m */,
+			);
+			path = BaseRefreshView;
+			sourceTree = "<group>";
+		};
+		3DB97D5229D6AB2200B12754 /* SDPhotoBrowser */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D5329D6AB2200B12754 /* SDPhotoBrowserConfig.h */,
+				3DB97D5429D6AB2200B12754 /* SDPhotoBrowser.m */,
+				3DB97D5529D6AB2200B12754 /* SDWaitingView.m */,
+				3DB97D5629D6AB2200B12754 /* SDBrowserImageView.m */,
+				3DB97D5729D6AB2200B12754 /* SDWaitingView.h */,
+				3DB97D5829D6AB2200B12754 /* SDPhotoBrowser.h */,
+				3DB97D5929D6AB2200B12754 /* SDBrowserImageView.h */,
+			);
+			path = SDPhotoBrowser;
+			sourceTree = "<group>";
+		};
+		3DB97D6029D6ABC000B12754 /* SDRefeshView */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D6129D6ABC000B12754 /* UIView+SDExtension.h */,
+				3DB97D6229D6ABC000B12754 /* SDRefreshFooterView.h */,
+				3DB97D6329D6ABC000B12754 /* SDRefreshView.h */,
+				3DB97D6429D6ABC000B12754 /* SDRefreshHeaderView.m */,
+				3DB97D6529D6ABC000B12754 /* sdRefeshView_arrow@2x.png */,
+				3DB97D6629D6ABC000B12754 /* UIView+SDExtension.m */,
+				3DB97D6729D6ABC000B12754 /* SDRefreshFooterView.m */,
+				3DB97D6829D6ABC000B12754 /* SDRefresh.h */,
+				3DB97D6929D6ABC000B12754 /* SDRefreshHeaderView.h */,
+				3DB97D6A29D6ABC000B12754 /* SDRefreshView.m */,
+			);
+			path = SDRefeshView;
+			sourceTree = "<group>";
+		};
+		3DB97D7029D6ABEF00B12754 /* MLEmojiLabel */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D7129D6ABEF00B12754 /* MLEmojiLabel.h */,
+				3DB97D7229D6ABEF00B12754 /* MLEmoji_Expression.plist */,
+				3DB97D7329D6ABEF00B12754 /* MLEmoji_Expression.bundle */,
+				3DB97D7429D6ABEF00B12754 /* MLEmoji_ExpressionImage.plist */,
+				3DB97D7529D6ABEF00B12754 /* MLEmojiLabel.m */,
+				3DB97D7629D6ABEF00B12754 /* TTTAttributedLabel */,
+				3DB97D7929D6ABEF00B12754 /* MLLabel */,
+			);
+			path = MLEmojiLabel;
+			sourceTree = "<group>";
+		};
+		3DB97D7629D6ABEF00B12754 /* TTTAttributedLabel */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D7729D6ABEF00B12754 /* TTTAttributedLabel.h */,
+				3DB97D7829D6ABEF00B12754 /* TTTAttributedLabel.m */,
+			);
+			path = TTTAttributedLabel;
+			sourceTree = "<group>";
+		};
+		3DB97D7929D6ABEF00B12754 /* MLLabel */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D7A29D6ABEF00B12754 /* LICENSE */,
+				3DB97D7B29D6ABEF00B12754 /* Classes */,
+				3DB97D9429D6ABEF00B12754 /* README.md */,
+			);
+			path = MLLabel;
+			sourceTree = "<group>";
+		};
+		3DB97D7B29D6ABEF00B12754 /* Classes */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D7C29D6ABEF00B12754 /* MLLinkLabel.h */,
+				3DB97D7D29D6ABEF00B12754 /* Category */,
+				3DB97D8429D6ABEF00B12754 /* MLLabel.h */,
+				3DB97D8529D6ABEF00B12754 /* MLLinkLabel.m */,
+				3DB97D8629D6ABEF00B12754 /* Expression */,
+				3DB97D8F29D6ABEF00B12754 /* MLLabel.m */,
+				3DB97D9029D6ABEF00B12754 /* Helper */,
+			);
+			path = Classes;
+			sourceTree = "<group>";
+		};
+		3DB97D7D29D6ABEF00B12754 /* Category */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D7E29D6ABEF00B12754 /* NSMutableAttributedString+MLLabel.m */,
+				3DB97D7F29D6ABEF00B12754 /* NSString+MLLabel.h */,
+				3DB97D8029D6ABEF00B12754 /* NSAttributedString+MLLabel.h */,
+				3DB97D8129D6ABEF00B12754 /* NSString+MLLabel.m */,
+				3DB97D8229D6ABEF00B12754 /* NSMutableAttributedString+MLLabel.h */,
+				3DB97D8329D6ABEF00B12754 /* NSAttributedString+MLLabel.m */,
+			);
+			path = Category;
+			sourceTree = "<group>";
+		};
+		3DB97D8629D6ABEF00B12754 /* Expression */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D8729D6ABEF00B12754 /* NSString+MLExpression.h */,
+				3DB97D8829D6ABEF00B12754 /* NSAttributedString+MLExpression.m */,
+				3DB97D8929D6ABEF00B12754 /* MLTextAttachment.m */,
+				3DB97D8A29D6ABEF00B12754 /* MLExpressionManager.h */,
+				3DB97D8B29D6ABEF00B12754 /* NSAttributedString+MLExpression.h */,
+				3DB97D8C29D6ABEF00B12754 /* NSString+MLExpression.m */,
+				3DB97D8D29D6ABEF00B12754 /* MLTextAttachment.h */,
+				3DB97D8E29D6ABEF00B12754 /* MLExpressionManager.m */,
+			);
+			path = Expression;
+			sourceTree = "<group>";
+		};
+		3DB97D9029D6ABEF00B12754 /* Helper */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97D9129D6ABEF00B12754 /* MLLabelLayoutManager.m */,
+				3DB97D9229D6ABEF00B12754 /* MLLabelLayoutManager.h */,
+				3DB97D9329D6ABEF00B12754 /* MLLabel+Override.h */,
+			);
+			path = Helper;
+			sourceTree = "<group>";
+		};
+		3DB97DA629D6AC0A00B12754 /* LEETheme */ = {
+			isa = PBXGroup;
+			children = (
+				3DB97DA729D6AC0A00B12754 /* LEETheme.h */,
+				3DB97DA829D6AC0A00B12754 /* LEETheme.m */,
+			);
+			path = LEETheme;
+			sourceTree = "<group>";
+		};
 		3DF3DAA929B9A6AF00CAD3AB /* Cells */ = {
 			isa = PBXGroup;
 			children = (
@@ -1190,6 +1578,7 @@
 				3D1B9D0D29C2A1360008D01A /* SLPlaceholderCell.xib in Resources */,
 				3D1B9CF929C071AD0008D01A /* SLFeedbackVc.xib in Resources */,
 				3DF3DAB329B9B86200CAD3AB /* SLUserCenterViewController.xib in Resources */,
+				3DB97D6C29D6ABC100B12754 /* sdRefeshView_arrow@2x.png in Resources */,
 				3D25106129AC95A9000AE530 /* SLRetrievePWViewController.xib in Resources */,
 				3DF3DAA829B9A6AA00CAD3AB /* SLBaseCellView.xib in Resources */,
 				3DF3DAE529BAFCCA00CAD3AB /* SLMySpeedCollectionViewCell.xib in Resources */,
@@ -1213,15 +1602,20 @@
 				3D1B986929BEAFEB0008D01A /* SLHorScrBtns.xib in Resources */,
 				3DF3DAFB29BB187D00CAD3AB /* SLHomeTopCollectionViewCell.xib in Resources */,
 				3DF3DAAE29B9AA3400CAD3AB /* SLMyListCollectionViewCell.xib in Resources */,
+				3DB97D9529D6ABF000B12754 /* MLEmoji_Expression.plist in Resources */,
+				3DB97D9729D6ABF000B12754 /* MLEmoji_ExpressionImage.plist in Resources */,
 				3D2510A829AEF4F0000AE530 /* SLMessageViewController.xib in Resources */,
 				3DA5AF7029B88898009E4925 /* SLMyViewController.xib in Resources */,
 				3D25109729AEDD8F000AE530 /* SLRoleCreatSucView.xib in Resources */,
 				3D1B988B29BEF1020008D01A /* SLLxTopCell.xib in Resources */,
 				3D25107029AD8AA9000AE530 /* SLRoleLabelViewController.xib in Resources */,
+				3DB97D9A29D6ABF000B12754 /* LICENSE in Resources */,
 				3D1B989029BEF1AC0008D01A /* SLVocabularyCell.xib in Resources */,
 				3D1B988029BEEA670008D01A /* SLVocabularyView.xib in Resources */,
 				3D2DC3F629B1E6510041A729 /* SLMikeInputView.xib in Resources */,
 				3D25105C29AC9475000AE530 /* SLForgetPWViewController.xib in Resources */,
+				3DB97DA529D6ABF000B12754 /* README.md in Resources */,
+				3DB97D9629D6ABF000B12754 /* MLEmoji_Expression.bundle in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -1274,21 +1668,26 @@
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				3DB97D4129D6A86E00B12754 /* SDTimeLineRefreshFooter.m in Sources */,
 				3D2DC3C929B07A6F0041A729 /* NuiSdkUtils.m in Sources */,
 				3DF3DAE429BAFCCA00CAD3AB /* SLMySpeedCollectionViewCell.m in Sources */,
 				3D1B9CF829C071AD0008D01A /* SLFeedbackVc.m in Sources */,
 				3DA5AF6F29B88898009E4925 /* SLMyViewController.m in Sources */,
+				3DB97D4029D6A86E00B12754 /* SDTimeLineCellCommentView.m in Sources */,
 				3D1B9D0529C1A14A0008D01A /* UIImagePickerController+YMBlocks.m in Sources */,
 				3D2DC3C429B0716E0041A729 /* SLNuisdkPlay.m in Sources */,
 				3DF3DAD229BAC90F00CAD3AB /* SLModifyNicknameVc.m in Sources */,
 				3DF3DAF229BB131100CAD3AB /* RDVTabBarItem.m in Sources */,
+				3DB97D9C29D6ABF000B12754 /* NSString+MLLabel.m in Sources */,
 				3D1B988F29BEF1AC0008D01A /* SLVocabularyCell.m in Sources */,
 				3DF3DAD729BAD1BA00CAD3AB /* SLChangeMobileVc.m in Sources */,
 				3D1B987729BEE6640008D01A /* SLLxTopView.m in Sources */,
 				3D1B9CF329C044AA0008D01A /* SLPickView.m in Sources */,
 				3D25106029AC95A9000AE530 /* SLRetrievePWViewController.m in Sources */,
 				3D25105629AC8FE1000AE530 /* SLRegistViewController.m in Sources */,
+				3DB97D3F29D6A86E00B12754 /* SDTimeLineCellOperationMenu.m in Sources */,
 				3DF3DAC929B9D19600CAD3AB /* SLBaseTableViewCell.m in Sources */,
+				3DB97D5129D6AAF900B12754 /* SDBaseRefreshView.m in Sources */,
 				3DF3DAB729B9B93000CAD3AB /* SLBaseCollectionViewCell.m in Sources */,
 				3D2DC3ED29B09B3B0041A729 /* UICollectionViewCell+YMHelper.m in Sources */,
 				3DF3DACD29B9D30A00CAD3AB /* UITableView+Extension.m in Sources */,
@@ -1296,10 +1695,14 @@
 				3D25109D29AEEDBE000AE530 /* UIView+Extension.m in Sources */,
 				3DA5AF6929B88875009E4925 /* SLLxViewController.m in Sources */,
 				3D1B987229BEB35B0008D01A /* SLHorScrBtnsCell.m in Sources */,
+				3DB97DA429D6ABF000B12754 /* MLLabelLayoutManager.m in Sources */,
 				3D2510BA29AF1970000AE530 /* SPRequestError.m in Sources */,
+				3DB97D3D29D6A86E00B12754 /* SDTimeLineTableViewController.m in Sources */,
+				3DB97D9B29D6ABF000B12754 /* NSMutableAttributedString+MLLabel.m in Sources */,
 				3D24986C29AC72E2003C3AFA /* SLLoginVCViewController.m in Sources */,
 				3DF3DAF129BB131100CAD3AB /* RDVTabBarController.m in Sources */,
 				3DF3DAF529BB170F00CAD3AB /* SLHomeView.m in Sources */,
+				3DB97DA029D6ABF000B12754 /* MLTextAttachment.m in Sources */,
 				3D1B9CF029C03B8B0008D01A /* SLDatePickView.m in Sources */,
 				3DF3DAC329B9C6E000CAD3AB /* YMBarItem.m in Sources */,
 				3DF3DAC529B9C6E000CAD3AB /* YMNavigationBar.m in Sources */,
@@ -1307,7 +1710,10 @@
 				3DF3DADB29BAD65500CAD3AB /* SLCustomizeAlert.m in Sources */,
 				3DA2C73829CAA9C30087CDB4 /* TokenHttpRequest.m in Sources */,
 				3DF3DAC429B9C6E000CAD3AB /* YMBarItemView.m in Sources */,
+				3DB97DA929D6AC0A00B12754 /* LEETheme.m in Sources */,
+				3DB97D5B29D6AB2300B12754 /* SDWaitingView.m in Sources */,
 				3DA2C73929CAA9C30087CDB4 /* AccessToken.m in Sources */,
+				3DB97D4529D6A86E00B12754 /* SDWeiXinPhotoContainerView.m in Sources */,
 				3D2DC3F429B1E6320041A729 /* SLMikeInputView.m in Sources */,
 				3D2DC3BF29B0709F0041A729 /* NLSRingBuffer.mm in Sources */,
 				3D25108829ADD46C000AE530 /* SLRoleLabelView.m in Sources */,
@@ -1316,15 +1722,21 @@
 				3D24987429AC7909003C3AFA /* UIViewController+Extension.m in Sources */,
 				3D25105B29AC9475000AE530 /* SLForgetPWViewController.m in Sources */,
 				3D2510C429AF1B24000AE530 /* ZFToast.m in Sources */,
+				3DB97DA229D6ABF000B12754 /* MLExpressionManager.m in Sources */,
+				3DB97D5A29D6AB2300B12754 /* SDPhotoBrowser.m in Sources */,
 				3D25107E29AD8FF1000AE530 /* SLPageControlView.m in Sources */,
+				3DB97D4229D6A86E00B12754 /* SDTimeLineTableHeaderView.m in Sources */,
 				3D2510C729AF1D29000AE530 /* NSString+Category.m in Sources */,
 				3D2DC3E729B099C90041A729 /* YMChatServiceView.m in Sources */,
 				3DA5AF5C29B8843C009E4925 /* SLBaseTabBarController.m in Sources */,
 				3D2DC3E029B0991E0041A729 /* YMIMMessageCollectionView.m in Sources */,
+				3DB97D6D29D6ABC100B12754 /* UIView+SDExtension.m in Sources */,
 				3DF3DAFA29BB187D00CAD3AB /* SLHomeTopCollectionViewCell.m in Sources */,
 				3D8515D729CD92A400418BAB /* JXCategoryTitleBackgroundCellModel.m in Sources */,
+				3DB97DA129D6ABF000B12754 /* NSString+MLExpression.m in Sources */,
 				3D25109529AEDD7A000AE530 /* SLRoleCreatSucView.m in Sources */,
 				3DFEE71429B5DCAD000AA7D5 /* SLNuiSpeechRecognizer.m in Sources */,
+				3DB97D4429D6A86E00B12754 /* SDTimeLineRefreshHeader.m in Sources */,
 				3D8515D929CD92A400418BAB /* JXCategoryTitleBackgroundView.m in Sources */,
 				3D1B9D0229C16DD00008D01A /* SLTargetModel.m in Sources */,
 				3D2510C029AF1A8F000AE530 /* MBProgressHUD+Addition.m in Sources */,
@@ -1337,9 +1749,14 @@
 				3D99620029CD2FFA0076DBD1 /* SLListViewController.m in Sources */,
 				3D2510B929AF1970000AE530 /* SLHttpCenter.m in Sources */,
 				3DA5AF7429B96726009E4925 /* SLMeHeaderCollectionViewCell.m in Sources */,
+				3DB97D4D29D6AAC500B12754 /* UITableView+SDAutoTableViewCellHeight.m in Sources */,
 				3D25107729AD8C13000AE530 /* RoleModel.m in Sources */,
+				3DB97DA329D6ABF000B12754 /* MLLabel.m in Sources */,
 				3DFEE71729B5E7F9000AA7D5 /* SLAuthorizationManager.m in Sources */,
 				3D2DC3DE29B0991E0041A729 /* YMIMBaseMessageCell.m in Sources */,
+				3DB97D9E29D6ABF000B12754 /* MLLinkLabel.m in Sources */,
+				3DB97D4329D6A86E00B12754 /* SDTimeLineCell.m in Sources */,
+				3DB97D9929D6ABF000B12754 /* TTTAttributedLabel.m in Sources */,
 				3DA5AF7C29B96B55009E4925 /* SLPageViewModel.m in Sources */,
 				3D2DC3DC29B0991E0041A729 /* YMCustServiceAlertView.m in Sources */,
 				3D2DC3DD29B0991E0041A729 /* YMNextGrowingInternalTextView.m in Sources */,
@@ -1349,12 +1766,16 @@
 				3D1B989629BF08A70008D01A /* SLLineScaleView.m in Sources */,
 				3D1B9CEC29C038280008D01A /* SLTargetViewController.m in Sources */,
 				3DF3DAA129B98A7D00CAD3AB /* SLMyView.m in Sources */,
+				3DB97D9F29D6ABF000B12754 /* NSAttributedString+MLExpression.m in Sources */,
 				3D1B986529BEAF2F0008D01A /* SLHorScrBtns.m in Sources */,
 				3D2510A729AEF4F0000AE530 /* SLMessageViewController.m in Sources */,
 				3D2DC3DB29B0991E0041A729 /* YMNextGrowingTextView.m in Sources */,
+				3DB97D5F29D6AB6400B12754 /* SDBaseTableViewController.m in Sources */,
 				3D25106F29AD8AA9000AE530 /* SLRoleLabelViewController.m in Sources */,
 				3DA5AF7829B96B33009E4925 /* SLBaseMainView.m in Sources */,
+				3DB97D9829D6ABF000B12754 /* MLEmojiLabel.m in Sources */,
 				3D8515D829CD92A400418BAB /* JXCategoryTitleBackgroundCell.m in Sources */,
+				3DB97D9D29D6ABF000B12754 /* NSAttributedString+MLLabel.m in Sources */,
 				3DF3DAB229B9B86200CAD3AB /* SLUserCenterViewController.m in Sources */,
 				3DFEE70E29B5CB01000AA7D5 /* SLMikeSegmentModel.m in Sources */,
 				3D2510CB29AF3306000AE530 /* SLUserModel.m in Sources */,
@@ -1363,11 +1784,15 @@
 				3D1B9CFF29C157620008D01A /* PlaceholderTextView.m in Sources */,
 				3D8C9F8D29AC57F300678283 /* main.m in Sources */,
 				3D25107A29AD8DB0000AE530 /* SLPageControlSlideRound.m in Sources */,
+				3DB97D6B29D6ABC100B12754 /* SDRefreshHeaderView.m in Sources */,
 				3D2510CE29AF375B000AE530 /* SLGlobalInfo.m in Sources */,
 				3DF3DB0129BB22CB00CAD3AB /* UIImage+Extension.m in Sources */,
 				3D25108129AD9999000AE530 /* UIColor+YMAdditions.m in Sources */,
+				3DB97D5C29D6AB2300B12754 /* SDBrowserImageView.m in Sources */,
+				3DB0AE1629D6B64200671744 /* NullSafe.m in Sources */,
 				3D2510AB29AF00E3000AE530 /* NSLayoutConstraint+IBDesignable.m in Sources */,
 				3D9961FD29CD2FB00076DBD1 /* SLContentBaseViewController.m in Sources */,
+				3DB97D3E29D6A86E00B12754 /* SDTimeLineCellModel.m in Sources */,
 				3DFEE71129B5D11E000AA7D5 /* UIButton+TitleAndImageLayout.m in Sources */,
 				3D25108429ADA027000AE530 /* SLInterestView.m in Sources */,
 				3D1B9D0829C1B7A90008D01A /* SLImagePickerAndUpload.m in Sources */,
@@ -1379,11 +1804,14 @@
 				3DA5AF7F29B96E11009E4925 /* SLPageModel.m in Sources */,
 				3D796C6C29B8305C00B7B28A /* NSObject+FBKVOController.m in Sources */,
 				3D8C9F7F29AC57F200678283 /* SceneDelegate.m in Sources */,
+				3DB97D6E29D6ABC100B12754 /* SDRefreshFooterView.m in Sources */,
 				3D1B9D0C29C2A1360008D01A /* SLPlaceholderCell.m in Sources */,
+				3DB97D6F29D6ABC100B12754 /* SDRefreshView.m in Sources */,
 				3DF3DAC229B9C6E000CAD3AB /* YMBarButtonItem.m in Sources */,
 				3DFEE70B29B5B298000AA7D5 /* SLMikeSegment.m in Sources */,
 				3D2DC3E429B099B50041A729 /* YMChatBottomView.m in Sources */,
 				3D25106529AC9694000AE530 /* SLBaseNavigationController.m in Sources */,
+				3DB97D4C29D6AAC500B12754 /* UIView+SDAutoLayout.m in Sources */,
 				3D2DC3DF29B0991E0041A729 /* YMIMHintView.m in Sources */,
 				3DA2C73C29CBE4DD0087CDB4 /* SLRoleappearanceView.m in Sources */,
 				3DF3DAAD29B9AA3400CAD3AB /* SLMyListCollectionViewCell.m in Sources */,

+ 44 - 0
SLAiELTS/SLAiELTS/AppMarcos/GlobalDefines.h

@@ -0,0 +1,44 @@
+//
+//  GlobalDefines.h
+//  GSD_WeiXin(wechat)
+//
+//  Created by aier on 16/2/12.
+//  Copyright © 2016年 GSD. All rights reserved.
+//
+
+/*
+ 
+ *********************************************************************************
+ *
+ * GSD_WeiXin
+ *
+ * QQ交流群: 362419100(2群) 459274049(1群已满)
+ * Email : gsdios@126.com
+ * GitHub: https://github.com/gsdios/GSD_WeiXin
+ * 新浪微博:GSD_iOS
+ *
+ * 此“高仿微信”用到了很高效方便的自动布局库SDAutoLayout(一行代码搞定自动布局)
+ * SDAutoLayout地址:https://github.com/gsdios/SDAutoLayout
+ * SDAutoLayout视频教程:http://www.letv.com/ptv/vplay/24038772.html
+ * SDAutoLayout用法示例:https://github.com/gsdios/SDAutoLayout/blob/master/README.md
+ *
+ *********************************************************************************
+ 
+ */
+
+#ifndef GlobalDefines_h
+#define GlobalDefines_h
+
+#define SDColor(r, g, b, a) [UIColor colorWithRed:(r / 255.0) green:(g / 255.0) blue:(b / 255.0) alpha:a]
+
+#define Global_tintColor [UIColor colorWithRed:0 green:(190 / 255.0) blue:(12 / 255.0) alpha:1]
+
+#define Global_mainBackgroundColor SDColor(248, 248, 248, 1)
+
+#define TimeLineCellHighlightedColor [UIColor colorWithRed:92/255.0 green:140/255.0 blue:193/255.0 alpha:1.0]
+
+#define DAY @"day"
+
+#define NIGHT @"night"
+
+#endif

+ 326 - 0
SLAiELTS/SLAiELTS/Tool/LEETheme/LEETheme.h

@@ -0,0 +1,326 @@
+
+/*!
+ *  @header LEETheme.h
+ *
+ *  ┌─┐      ┌───────┐ ┌───────┐ 帅™
+ *  │ │      │ ┌─────┘ │ ┌─────┘
+ *  │ │      │ └─────┐ │ └─────┐
+ *  │ │      │ ┌─────┘ │ ┌─────┘
+ *  │ └─────┐│ └─────┐ │ └─────┐
+ *  └───────┘└───────┘ └───────┘
+ *
+ *  @brief  LEE主题管理
+ *
+ *  @author LEE
+ *  @copyright    Copyright © 2016年 lee. All rights reserved.
+ *  @version    V1.0.7
+ */
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+
+@class LEEThemeConfigModel;
+
+typedef void(^LEEThemeConfigBlock)(id item);
+typedef void(^LEEThemeConfigBlockToIdentifier)(id item , id value);
+typedef LEEThemeConfigModel *(^LEEConfigThemeToFloat)(CGFloat number);
+typedef LEEThemeConfigModel *(^LEEConfigThemeToIdentifier)(NSString *identifier);
+typedef LEEThemeConfigModel *(^LEEConfigThemeToColor)(NSString *tag , UIColor *color);
+typedef LEEThemeConfigModel *(^LEEConfigThemeToImage)(NSString *tag , id image);
+typedef LEEThemeConfigModel *(^LEEConfigThemeToString)(NSString *tag , NSString *string);
+typedef LEEThemeConfigModel *(^LEEConfigThemeToStringAndBlock)(NSString *tag , LEEThemeConfigBlock);
+typedef LEEThemeConfigModel *(^LEEConfigThemeToArrayAndBlock)(NSArray *tags , LEEThemeConfigBlock);
+typedef LEEThemeConfigModel *(^LEEConfigThemeToIdentifierAndState)(NSString *identifier , UIControlState state);
+typedef LEEThemeConfigModel *(^LEEConfigThemeToColorAndState)(NSString *tag , UIColor *color , UIControlState state);
+typedef LEEThemeConfigModel *(^LEEConfigThemeToImageAndState)(NSString *tag , UIImage *image , UIControlState state);
+typedef LEEThemeConfigModel *(^LEEConfigThemeToImageAndState)(NSString *tag , UIImage *image , UIControlState state);
+typedef LEEThemeConfigModel *(^LEEConfigThemeToKeyPathAndColor)(NSString *tag , NSString *keyPath , UIColor *color);
+typedef LEEThemeConfigModel *(^LEEConfigThemeToKeyPathAndImage)(NSString *tag , NSString *keyPath , id image);
+typedef LEEThemeConfigModel *(^LEEConfigThemeToIdentifierAndBlock)(NSString *identifier , LEEThemeConfigBlockToIdentifier);
+
+/*
+ 
+ *********************************************************************************
+ *
+ * 在使用LEETheme的过程中如果出现bug请及时以以下任意一种方式联系我,我会及时修复bug
+ *
+ * QQ    : 可以添加SDAutoLayout群 497140713 在这里找到我(LEE)
+ * Email : applelixiang@126.com
+ * GitHub: https://github.com/lixiang1994/LEETheme
+ * 简书:    http://www.jianshu.com/users/a6da0db100c8
+ *
+ *********************************************************************************
+ 
+ */
+
+@interface LEETheme : NSObject
+
+/**
+ *  启动主题
+ *
+ *  @param tag 主题标签
+ */
++ (void)startTheme:(NSString *)tag;
+
+/**
+ *  默认主题
+ *
+ *  @param tag 主题标签
+ */
++ (void)defaultTheme:(NSString *)tag;
+
+/**
+ *  默认更改主题动画时长 (这是所有对象默认的时长 , 但如果你对某个对象单独进行了时长设置 , 那么该对象将以单独设置的为准)
+ *
+ *  @param duration 动画时长
+ */
++ (void)defaultChangeThemeAnimationDuration:(CGFloat)duration;
+
+/**
+ *  当前主题标签
+ *
+ *  @return 主题标签 tag
+ */
++ (NSString *)currentThemeTag;
+
+/**
+ *  添加主题设置Json
+ *
+ *  @param json json字符串
+ *  @param tag 主题标签
+ *  @param path 资源路径 (传入nil 默认为mainBundle路径)
+ */
++ (void)addThemeConfigJson:(NSString *)json WithTag:(NSString *)tag WithResourcesPath:(NSString *)path;
+
+/**
+ *  获取指定主题标签的资源路径
+ *
+ *  @param tag 主题标签
+ *
+ *  @return 资源路径 (如为不存在则返回mainBundle路径)
+ */
++ (NSString *)getResourcesPathWithTag:(NSString *)tag;
+
+@end
+
+@interface LEEThemeConfigModel : NSObject
+
+/** ----独立设置方式---- */
+
+/** Block */
+
+/** 添加自定义设置 -> 格式: .LeeAddCustomConfig(@@"tag" , ^(id item){ code... }) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToStringAndBlock LeeAddCustomConfig;
+/** 添加多标签自定义设置 -> 格式: .LeeAddCustomConfigs(@@[tag1 , tag2] , ^(id item){ code... }) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToArrayAndBlock LeeAddCustomConfigs;
+
+/** Color */
+
+/** 添加渲染颜色设置 -> 格式: .LeeAddTintColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddTintColor;
+/** 添加文本颜色设置 -> 格式: .LeeAddTextColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddTextColor;
+/** 添加填充颜色设置 -> 格式: .LeeAddFillColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddFillColor;
+/** 添加笔画颜色设置 -> 格式: .LeeAddStrokeColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddStrokeColor;
+/** 添加边框颜色设置 -> 格式: .LeeAddBorderColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddBorderColor;
+/** 添加阴影颜色设置 -> 格式: .LeeAddShadowColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddShadowColor;
+/** 添加开关开启颜色设置 -> 格式: .LeeAddOnTintColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddOnTintColor;
+/** 添加开关按钮颜色设置 -> 格式: .LeeAddThumbTintColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddThumbTintColor;
+/** 添加分隔线颜色设置 -> 格式: .LeeAddSeparatorColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddSeparatorColor;
+/** 添加bar渲染颜色设置 -> 格式: .LeeAddBarTintColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddBarTintColor;
+/** 添加背景颜色设置 -> 格式: .LeeAddBackgroundColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddBackgroundColor;
+/** 添加占位符颜色设置 -> 格式: .LeeAddPlaceholderColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddPlaceholderColor;
+/** 添加进度轨道渲染颜色设置 -> 格式: .LeeAddTrackTintColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddTrackTintColor;
+/** 添加进度渲染颜色设置 -> 格式: .LeeAddProgressTintColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddProgressTintColor;
+/** 添加高亮文本颜色设置 -> 格式: .LeeAddHighlightedTextColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddHighlightedTextColor;
+/** 添加页数指示渲染颜色设置 -> 格式: .LeeAddPageIndicatorTintColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddPageIndicatorTintColor;
+/** 添加当前页数指示渲染颜色设置 -> 格式: .LeeAddCurrentPageIndicatorTintColor(@@"tag" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColor LeeAddCurrentPageIndicatorTintColor;
+/** 添加按钮标题颜色设置 -> 格式: .LeeAddButtonTitleColor(@@"tag" , UIColor , UIControlStateNormal) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColorAndState LeeAddButtonTitleColor;
+/** 添加按钮标题阴影颜色设置 -> 格式: .LeeAddButtonTitleShadowColor(@@"tag" , UIColor , UIControlStateNormal) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToColorAndState LeeAddButtonTitleShadowColor;
+
+/** 添加属性颜色设置 -> 格式: .LeeAddKeyPathAndColor(@@"tag" , @@"keyPath" , UIColor) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToKeyPathAndColor LeeAddKeyPathAndColor;
+
+/** Image */
+
+/** 添加图片设置 -> 格式: .LeeAddImage(@@"tag" , UIImage 或 @@"imageName" 或 @@"imagePath") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToImage LeeAddImage;
+/** 添加进度轨道图片设置 -> 格式: .LeeAddTrackImage(@@"tag" , UIImage 或 @@"imageName" 或 @@"imagePath") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToImage LeeAddTrackImage;
+/** 添加进度图片设置 -> 格式: .LeeAddProgressImage(@@"tag" , UIImage 或 @@"imageName" 或 @@"imagePath") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToImage LeeAddProgressImage;
+/** 添加阴影图片设置 -> 格式: .LeeAddShadowImage(@@"tag" , UIImage 或 @@"imageName" 或 @@"imagePath") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToImage LeeAddShadowImage;
+/** 添加选中图片设置 -> 格式: .LeeAddSelectedImage(@@"tag" , UIImage 或 @@"imageName" 或 @@"imagePath") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToImage LeeAddSelectedImage;
+/** 添加背景图片设置 -> 格式: .LeeAddBackgroundImage(@@"tag" , UIImage 或 @@"imageName" 或 @@"imagePath") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToImage LeeAddBackgroundImage;
+/** 添加返回指示图片设置 -> 格式: .LeeAddBackIndicatorImage(@@"tag" , UIImage 或 @@"imageName" 或 @@"imagePath") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToImage LeeAddBackIndicatorImage;
+/** 添加返回指示图片设置 -> 格式: .LeeAddBackIndicatorTransitionMaskImage(@@"tag" , UIImage 或 @@"imageName" 或 @@"imagePath") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToImage LeeAddBackIndicatorTransitionMaskImage;
+/** 添加选择指示器图片设置 -> 格式: .LeeAddSelectionIndicatorImage(@@"tag" , UIImage 或 @@"imageName" 或 @@"imagePath") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToImage LeeAddSelectionIndicatorImage;
+/** 添加分栏背景图片设置 -> 格式: .LeeAddScopeBarBackgroundImage(@@"tag" , UIImage 或 @@"imageName" 或 @@"imagePath") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToImage LeeAddScopeBarBackgroundImage;
+/** 添加按钮图片设置 -> 格式: .LeeAddButtonImage(@@"tag" , UIImage , UIControlStateNormal) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToImageAndState LeeAddButtonImage;
+/** 添加按钮背景图片设置 -> 格式: .LeeAddButtonBackgroundImage(@@"tag" , UIImage , UIControlStateNormal) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToImageAndState LeeAddButtonBackgroundImage;
+
+/** 添加属性图片设置 -> 格式: .LeeAddKeyPathAndImage(@@"tag" , @@"keyPath" , UIImage 或 @"imageName" 或 @"imagePath") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToKeyPathAndImage LeeAddKeyPathAndImage;
+
+/** ----JSON设置方式---- */
+
+/** Block */
+
+/** 自定义设置 -> 格式: .LeeCustomConfig(@@"identifier" , ^(id item , id value){ code... }) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifierAndBlock LeeCustomConfig;
+
+/** Color */
+
+/** 设置渲染颜色标识符 -> 格式: .LeeConfigTintColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigTintColor;
+/** 设置文本颜色标识符 -> 格式: .LeeConfigTextColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigTextColor;
+/** 设置填充颜色标识符 -> 格式: .LeeConfigFillColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigFillColor;
+/** 设置笔画颜色标识符 -> 格式: .LeeConfigStrokeColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigStrokeColor;
+/** 设置边框颜色标识符 -> 格式: .LeeConfigBorderColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigBorderColor;
+/** 设置文本颜色标识符 -> 格式: .LeeConfigShadowColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigShadowColor;
+/** 设置开关开启颜色标识符 -> 格式: .LeeConfigOnTintColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigOnTintColor;
+/** 设置开关按钮颜色标识符 -> 格式: .LeeConfigThumbTintColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigThumbTintColor;
+/** 设置分隔线颜色标识符 -> 格式: .LeeConfigSeparatorColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigSeparatorColor;
+/** 设置bar渲染颜色标识符 -> 格式: .LeeConfigBarTintColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigBarTintColor;
+/** 设置背景颜色标识符 -> 格式: .LeeConfigBackgroundColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigBackgroundColor;
+/** 设置占位符颜色标识符 -> 格式: .LeeConfigPlaceholderColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigPlaceholderColor;
+/** 设置进度轨道渲染颜色标识符 -> 格式: .LeeConfigTrackTintColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigTrackTintColor;
+/** 设置进度渲染颜色标识符 -> 格式: .LeeConfigProgressTintColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigProgressTintColor;
+/** 设置高亮文本颜色标识符 -> 格式: .LeeConfigHighlightedTextColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigHighlightedTextColor;
+/** 设置页数指示渲染颜色标识符 -> 格式: .LeeConfigPageIndicatorTintColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigPageIndicatorTintColor;
+/** 设置当前页数指示渲染颜色标识符 -> 格式: .LeeConfigCurrentPageIndicatorTintColor(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigCurrentPageIndicatorTintColor;
+/** 设置按钮标题颜色标识符 -> 格式: .LeeConfigButtonTitleColor(@@"identifier" , UIControlStateNormal) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifierAndState LeeConfigButtonTitleColor;
+/** 设置按钮标题阴影颜色标识符 -> 格式: .LeeConfigButtonTitleColor(@@"identifier" , UIControlStateNormal) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifierAndState LeeConfigButtonTitleShadowColor;
+
+/** Image */
+
+/** 设置图片标识符 -> 格式: .LeeConfigImage(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigImage;
+/** 设置进度轨道图片标识符 -> 格式: .LeeConfigTrackImage(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigTrackImage;
+/** 设置进度图片标识符 -> 格式: .LeeConfigProgressImage(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigProgressImage;
+/** 设置阴影图片标识符 -> 格式: .LeeConfigShadowImage(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigShadowImage;
+/** 设置选中图片标识符 -> 格式: .LeeConfigSelectedImage(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigSelectedImage;
+/** 设置背景图片标识符 -> 格式: .LeeConfigBackgroundImage(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigBackgroundImage;
+/** 设置返回指示图片标识符 -> 格式: .LeeConfigBackIndicatorImage(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigBackIndicatorImage;
+/** 设置返回指示图片标识符 -> 格式: .LeeConfigBackIndicatorTransitionMaskImage(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigBackIndicatorTransitionMaskImage;
+/** 设置选择指示器图片标识符 -> 格式: .LeeConfigSelectionIndicatorImage(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigSelectionIndicatorImage;
+/** 设置分栏背景图片标识符 -> 格式: .LeeConfigScopeBarBackgroundImage(@@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifier LeeConfigScopeBarBackgroundImage;
+/** 设置按钮图片标识符 -> 格式: .LeeConfigButtonImage(@@"identifier" , UIControlStateNormal) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifierAndState LeeConfigButtonImage;
+/** 设置按钮背景图片标识符 -> 格式: .LeeConfigButtonBackgroundImage(@@"identifier" , UIControlStateNormal) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToIdentifierAndState LeeConfigButtonBackgroundImage;
+
+/** 设置属性标识符 -> 格式: .LeeConfigKeyPathAndIdentifier(@@"keyPath" , @@"identifier") */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToString LeeConfigKeyPathAndIdentifier;
+
+/** ----通用设置---- */
+
+/** 设置主题更改过渡动画时长 -> 格式: .LeeChangeThemeAnimationDuration(0.1f) */
+@property (nonatomic , copy , readonly ) LEEConfigThemeToFloat LeeChangeThemeAnimationDuration;
+
+@end
+
+@interface NSObject (LEEThemeConfigObject)
+
+@property (nonatomic , strong ) LEEThemeConfigModel *lee_theme;
+
+@end
+
+
+
+
+/*
+ *
+ *          ┌─┐       ┌─┐
+ *       ┌──┘ ┴───────┘ ┴──┐
+ *       │                 │
+ *       │       ───       │
+ *       │  ─┬┘       └┬─  │
+ *       │                 │
+ *       │       ─┴─       │
+ *       │                 │
+ *       └───┐         ┌───┘
+ *           │         │
+ *           │         │
+ *           │         │
+ *           │         └──────────────┐
+ *           │                        │
+ *           │                        ├─┐
+ *           │                        ┌─┘
+ *           │                        │
+ *           └─┐  ┐  ┌───────┬──┐  ┌──┘
+ *             │ ─┤ ─┤       │ ─┤ ─┤
+ *             └──┴──┘       └──┴──┘
+ *                 神兽保佑
+ *                 代码无BUG!
+ */
+
+
+@interface UIColor (LEEThemeColor)
+
++ (UIColor *)leeTheme_ColorWithHexString:(NSString *)hexString;
+
++ (UIColor *)leeTheme_ColorFromJsonWithTag:(NSString *)tag WithIdentifier:(NSString *)identifier;
+
+@end
+
+@interface UIImage (LEEThemeImage)
+
++ (UIImage *)leeTheme_ImageFromJsonWithTag:(NSString *)tag WithIdentifier:(NSString *)identifier;
+
+@end
+
+

+ 1572 - 0
SLAiELTS/SLAiELTS/Tool/LEETheme/LEETheme.m

@@ -0,0 +1,1572 @@
+/*!
+ *  @header LEETheme.m
+ *
+ *  ┌─┐      ┌───────┐ ┌───────┐ 帅™
+ *  │ │      │ ┌─────┘ │ ┌─────┘
+ *  │ │      │ └─────┐ │ └─────┐
+ *  │ │      │ ┌─────┘ │ ┌─────┘
+ *  │ └─────┐│ └─────┐ │ └─────┐
+ *  └───────┘└───────┘ └───────┘
+ *
+ *  @brief  LEE主题管理
+ *
+ *  @author LEE
+ *  @copyright    Copyright © 2016年 lee. All rights reserved.
+ *  @version    V1.0.7
+ */
+
+
+#import "LEETheme.h"
+
+#import <objc/runtime.h>
+
+NSString * const LEEThemeChangingNotificaiton = @"LEEThemeChangingNotificaiton";
+NSString * const LEEThemeCurrentTag = @"LEEThemeCurrentTag";
+
+@interface LEETheme ()
+
+@property (nonatomic , copy ) NSString *currentTag;
+
+@property (nonatomic , copy ) NSMutableSet *allTags;
+
+@property (nonatomic , copy ) NSMutableDictionary *jsonConfigInfo;
+
+@property (nonatomic , assign ) CGFloat animationDuration;
+
+@end
+
+@implementation LEETheme
+
++ (LEETheme *)shareTheme{
+    
+    static LEETheme *themeManager = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        
+        themeManager = [[LEETheme alloc]init];
+    });
+    
+    return themeManager;
+}
+
++ (void)startTheme:(NSString *)tag{
+    
+    NSAssert([[LEETheme shareTheme].allTags containsObject:tag], @"所启用的主题不存在 - 请检查是否添加了该%@主题的设置" , tag);
+    
+    [LEETheme shareTheme].currentTag = tag;
+    
+    [[NSNotificationCenter defaultCenter] postNotificationName:LEEThemeChangingNotificaiton object:nil userInfo:nil];
+}
+
++ (void)defaultTheme:(NSString *)tag{
+    
+    if (![LEETheme shareTheme].currentTag && ![[NSUserDefaults standardUserDefaults] objectForKey:LEEThemeCurrentTag]) [LEETheme shareTheme].currentTag = tag;
+}
+
++ (void)defaultChangeThemeAnimationDuration:(CGFloat)duration{
+    
+    NSAssert(duration >= 0, @"默认的更改主题动画时长不能小于0秒");
+    
+    [LEETheme shareTheme].animationDuration = duration;
+}
+
++ (NSString *)currentThemeTag{
+    
+    return [LEETheme shareTheme].currentTag ? [LEETheme shareTheme].currentTag : [[NSUserDefaults standardUserDefaults] objectForKey:LEEThemeCurrentTag];
+}
+
++ (void)addThemeConfigJson:(NSString *)json WithTag:(NSString *)tag WithResourcesPath:(NSString *)path{
+    
+    if (json) {
+        
+        NSError *jsonError = nil;
+        
+        NSDictionary *jsonConfigInfo = [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&jsonError];
+        
+        NSAssert(!jsonError, @"添加的主题json配置数据解析错误 - 错误描述");
+        NSAssert(jsonConfigInfo, @"添加的主题json配置数据解析为空 - 请检查");
+        NSAssert(tag, @"添加的主题json标签不能为空");
+        
+        if (!jsonError) if(jsonConfigInfo) [[LEETheme shareTheme].jsonConfigInfo setValue:[NSMutableDictionary dictionaryWithObjectsAndKeys:jsonConfigInfo , @"json", path , @"path" , nil] forKey:tag];
+        
+        [[LEETheme shareTheme].allTags addObject:tag];
+    }
+    
+}
+
++ (NSString *)getResourcesPathWithTag:(NSString *)tag{
+    
+    NSString *path = [LEETheme shareTheme].jsonConfigInfo[tag][@"path"];
+    
+    return path ? path : [[NSBundle mainBundle] bundlePath];
+}
+
+- (void)setCurrentTag:(NSString *)currentTag{
+    
+    _currentTag = currentTag;
+    
+    [[NSUserDefaults standardUserDefaults] setObject:currentTag forKey:LEEThemeCurrentTag];
+    
+    [[NSUserDefaults standardUserDefaults] synchronize];
+}
+
+#pragma mark - LazyLoading
+
+- (NSMutableSet *)allTags{
+    
+    if (!_allTags) _allTags = [NSMutableSet set];
+
+    return _allTags;
+}
+
+- (NSMutableDictionary *)jsonConfigInfo{
+    
+    if (!_jsonConfigInfo) _jsonConfigInfo = [NSMutableDictionary dictionary];
+    
+    return _jsonConfigInfo;
+}
+
+@end
+
+#pragma mark - ----------------主题设置模型----------------
+
+typedef NS_ENUM(NSInteger, LEEThemeIdentifierConfigType) {
+    
+    /** 标识符设置类型 - Block */
+    
+    LEEThemeIdentifierConfigTypeCustomConfig,
+    
+    /** 标识符设置类型 - Color */
+
+    LEEThemeIdentifierConfigTypeButtonTitleColor,
+    LEEThemeIdentifierConfigTypeButtonTitleShadowColor,
+    
+    /** 标识符设置类型 - Image */
+    
+    LEEThemeIdentifierConfigTypeButtonImage,
+    LEEThemeIdentifierConfigTypeButtonBackgroundImage
+    
+};
+
+@interface LEEThemeConfigModel ()
+
+@property (nonatomic , copy ) void(^modelInitCurrentThemeConfig)();
+
+@property (nonatomic , copy ) NSString *modelCurrentThemeTag;
+
+@property (nonatomic , copy ) NSMutableDictionary *modelThemeConfigInfo;
+@property (nonatomic , copy ) NSMutableDictionary *modelThemeIdentifierConfigInfo;
+
+@property (nonatomic , copy ) NSMutableDictionary *modelThemeColorConfigInfo;
+@property (nonatomic , copy ) NSMutableDictionary *modelThemeButtonTitleColorConfigInfo;
+@property (nonatomic , copy ) NSMutableDictionary *modelThemeButtonShadowTitleColorConfigInfo;
+
+@property (nonatomic , copy ) NSMutableDictionary *modelThemeImageConfigInfo;
+@property (nonatomic , copy ) NSMutableDictionary *modelThemeButtonImageConfigInfo;
+@property (nonatomic , copy ) NSMutableDictionary *modelThemeButtonBackgroundImageConfigInfo;
+
+@property (nonatomic , assign ) CGFloat modelChangeThemeAnimationDuration;
+
+@end
+
+@implementation LEEThemeConfigModel
+
+- (void)dealloc{
+    
+    _modelCurrentThemeTag = nil;
+    _modelThemeConfigInfo = nil;
+    _modelThemeIdentifierConfigInfo = nil;
+    
+    _modelThemeColorConfigInfo = nil;
+    _modelThemeButtonTitleColorConfigInfo = nil;
+    _modelThemeButtonShadowTitleColorConfigInfo = nil;
+    
+    _modelThemeImageConfigInfo = nil;
+    _modelThemeButtonImageConfigInfo = nil;
+    _modelThemeButtonBackgroundImageConfigInfo = nil;
+}
+
+- (instancetype)init
+{
+    self = [super init];
+    if (self) {
+        
+        //默认属性值
+        
+        _modelChangeThemeAnimationDuration = -1.f; //默认为小于0
+    }
+    return self;
+}
+
+- (void)initCurrentThemeConfigHandleWithTag:(NSString *)tag{
+    
+    if ([[LEETheme currentThemeTag] isEqualToString:tag]) {
+        
+        if (self.modelInitCurrentThemeConfig) self.modelInitCurrentThemeConfig();
+    }
+    
+}
+
+- (void)initCurrentThemeConfigHandleWithIdentifier:(NSString *)identifier{
+    
+    if ([LEETheme shareTheme].jsonConfigInfo[[LEETheme currentThemeTag]]) {
+        
+        NSDictionary *tempJson = [LEETheme shareTheme].jsonConfigInfo[[LEETheme currentThemeTag]][@"json"];
+        
+        if (tempJson[@"color"][identifier] || tempJson[@"image"][identifier]) {
+            
+            if (self.modelInitCurrentThemeConfig) self.modelInitCurrentThemeConfig();
+        }
+    
+    }
+    
+}
+
+#pragma mark ***独立设置方式***
+
+- (LEEConfigThemeToStringAndBlock)LeeAddCustomConfig{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , LEEThemeConfigBlock configBlock){
+        
+        [[LEETheme shareTheme].allTags addObject:tag];
+        
+        [weakSelf.modelThemeConfigInfo setObject:configBlock forKey:tag];
+        
+        [weakSelf initCurrentThemeConfigHandleWithTag:tag];
+        
+        return weakSelf;
+    };
+    
+}
+
+- (LEEConfigThemeToArrayAndBlock)LeeAddCustomConfigs{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSArray *tags , LEEThemeConfigBlock configBlock){
+        
+        [[LEETheme shareTheme].allTags addObjectsFromArray:tags];
+        
+        [tags enumerateObjectsUsingBlock:^(NSString *tag, NSUInteger idx, BOOL * _Nonnull stop) {
+           
+            [weakSelf.modelThemeConfigInfo setObject:configBlock forKey:tag];
+            
+            [weakSelf initCurrentThemeConfigHandleWithTag:tag];
+        }];
+        
+        return weakSelf;
+    };
+    
+}
+
+- (LEEConfigThemeToKeyPathAndColor)LeeAddKeyPathAndColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , NSString *keyPath , UIColor *color){
+        
+        [[LEETheme shareTheme].allTags addObject:tag];
+        
+        NSMutableDictionary *info = [weakSelf.modelThemeColorConfigInfo objectForKey:keyPath];
+        
+        if (!info) info = [NSMutableDictionary dictionary];
+        
+        [info setObject:color forKey:tag];
+        
+        [weakSelf.modelThemeColorConfigInfo setObject:info forKey:keyPath];
+        
+        [weakSelf initCurrentThemeConfigHandleWithTag:tag];
+        
+        return weakSelf;
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"tintColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddTextColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"textColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddFillColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"fillColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddStrokeColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"strokeColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddBorderColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"borderColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddShadowColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"shadowColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddOnTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"onTintColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddThumbTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"thumbTintColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddSeparatorColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"separatorColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddBarTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"barTintColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddBackgroundColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"backgroundColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddPlaceholderColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"_placeholderLabel.textColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddTrackTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"trackTintColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddProgressTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"progressTintColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddHighlightedTextColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"highlightedTextColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddCurrentPageIndicatorTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"currentPageIndicatorTintColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColor)LeeAddPageIndicatorTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color){
+        
+        return weakSelf.LeeAddKeyPathAndColor(tag , @"pageIndicatorTintColor" , color);
+    };
+    
+}
+
+- (LEEConfigThemeToColorAndState)LeeAddButtonTitleColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color , UIControlState state){
+        
+        [[LEETheme shareTheme].allTags addObject:tag];
+        
+        NSMutableDictionary *info = weakSelf.modelThemeButtonTitleColorConfigInfo[tag];
+        
+        if (!info) info = [NSMutableDictionary dictionary];
+        
+        [info setObject:color forKey:@(state)];
+        
+        [weakSelf.modelThemeButtonTitleColorConfigInfo setObject:info forKey:tag];
+        
+        [weakSelf initCurrentThemeConfigHandleWithTag:tag];
+        
+        return weakSelf;
+    };
+    
+}
+
+- (LEEConfigThemeToColorAndState)LeeAddButtonTitleShadowColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIColor *color , UIControlState state){
+        
+        [[LEETheme shareTheme].allTags addObject:tag];
+        
+        NSMutableDictionary *info = weakSelf.modelThemeButtonShadowTitleColorConfigInfo[tag];
+        
+        if (!info) info = [NSMutableDictionary dictionary];
+        
+        [info setObject:color forKey:@(state)];
+        
+        [weakSelf.modelThemeButtonShadowTitleColorConfigInfo setObject:info forKey:tag];
+        
+        [weakSelf initCurrentThemeConfigHandleWithTag:tag];
+        
+        return weakSelf;
+    };
+    
+}
+
+- (LEEConfigThemeToKeyPathAndImage)LeeAddKeyPathAndImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , NSString *keyPath , id image){
+        
+        [[LEETheme shareTheme].allTags addObject:tag];
+        
+        NSMutableDictionary *info = [weakSelf.modelThemeImageConfigInfo objectForKey:keyPath];
+        
+        if (!info) info = [NSMutableDictionary dictionary];
+        
+        [info setObject:image forKey:tag];
+        
+        [weakSelf.modelThemeImageConfigInfo setObject:info forKey:keyPath];
+        
+        [weakSelf initCurrentThemeConfigHandleWithTag:tag];
+        
+        return weakSelf;
+    };
+    
+}
+
+- (LEEConfigThemeToImage)LeeAddImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , id image){
+        
+        return weakSelf.LeeAddKeyPathAndImage(tag , @"image" , image);
+    };
+    
+}
+
+- (LEEConfigThemeToImage)LeeAddTrackImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , id image){
+        
+        return weakSelf.LeeAddKeyPathAndImage(tag , @"trackImage" , image);
+    };
+    
+}
+
+- (LEEConfigThemeToImage)LeeAddProgressImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , id image){
+        
+        return weakSelf.LeeAddKeyPathAndImage(tag , @"progressImage" , image);
+    };
+    
+}
+
+- (LEEConfigThemeToImage)LeeAddShadowImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , id image){
+        
+        return weakSelf.LeeAddKeyPathAndImage(tag , @"shadowImage" , image);
+    };
+    
+}
+
+- (LEEConfigThemeToImage)LeeAddSelectedImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , id image){
+        
+        return weakSelf.LeeAddKeyPathAndImage(tag , @"selectedImage" , image);
+    };
+    
+}
+
+- (LEEConfigThemeToImage)LeeAddBackgroundImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , id image){
+        
+        return weakSelf.LeeAddKeyPathAndImage(tag , @"backgroundImage" , image);
+    };
+    
+}
+
+- (LEEConfigThemeToImage)LeeAddBackIndicatorImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , id image){
+        
+        return weakSelf.LeeAddKeyPathAndImage(tag , @"backIndicatorImage" , image);
+    };
+    
+}
+
+- (LEEConfigThemeToImage)LeeAddBackIndicatorTransitionMaskImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , id image){
+        
+        return weakSelf.LeeAddKeyPathAndImage(tag , @"backIndicatorTransitionMaskImage" , image);
+    };
+    
+}
+
+- (LEEConfigThemeToImage)LeeAddSelectionIndicatorImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , id image){
+        
+        return weakSelf.LeeAddKeyPathAndImage(tag , @"selectionIndicatorImage" , image);
+    };
+    
+}
+
+- (LEEConfigThemeToImage)LeeAddScopeBarBackgroundImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , id image){
+        
+        return weakSelf.LeeAddKeyPathAndImage(tag , @"scopeBarBackgroundImage" , image);
+    };
+    
+}
+
+- (LEEConfigThemeToImageAndState)LeeAddButtonImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIImage *image , UIControlState state){
+        
+        [[LEETheme shareTheme].allTags addObject:tag];
+        
+        NSMutableDictionary *info = weakSelf.modelThemeButtonImageConfigInfo[tag];
+        
+        if (!info) info = [NSMutableDictionary dictionary];
+        
+        [info setObject:image forKey:@(state)];
+        
+        [weakSelf.modelThemeButtonImageConfigInfo setObject:info forKey:tag];
+        
+        [weakSelf initCurrentThemeConfigHandleWithTag:tag];
+        
+        return weakSelf;
+    };
+    
+}
+
+- (LEEConfigThemeToImageAndState)LeeAddButtonBackgroundImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *tag , UIImage *image , UIControlState state){
+        
+        [[LEETheme shareTheme].allTags addObject:tag];
+        
+        NSMutableDictionary *info = weakSelf.modelThemeButtonBackgroundImageConfigInfo[tag];
+        
+        if (!info) info = [NSMutableDictionary dictionary];
+        
+        [info setObject:image forKey:@(state)];
+        
+        [weakSelf.modelThemeButtonBackgroundImageConfigInfo setObject:info forKey:tag];
+        
+        [weakSelf initCurrentThemeConfigHandleWithTag:tag];
+        
+        return weakSelf;
+    };
+    
+}
+
+#pragma mark ***JSON设置方式***
+
+- (LEEConfigThemeToIdentifierAndBlock)LeeCustomConfig{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier , LEEThemeConfigBlockToIdentifier configBlock){
+        
+        NSMutableDictionary *info = weakSelf.modelThemeIdentifierConfigInfo[@(LEEThemeIdentifierConfigTypeCustomConfig)];
+        
+        if (!info) info = [NSMutableDictionary dictionary];
+        
+        [info setObject:configBlock forKey:identifier];
+        
+        [weakSelf.modelThemeIdentifierConfigInfo setObject:info forKey:@(LEEThemeIdentifierConfigTypeCustomConfig)];
+        
+        [weakSelf initCurrentThemeConfigHandleWithIdentifier:identifier];
+        
+        return weakSelf;
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"tintColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigTextColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"textColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigFillColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"fillColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigStrokeColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"strokeColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigBorderColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"borderColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigShadowColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"shadowColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigOnTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"onTintColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigThumbTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"thumbTintColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigSeparatorColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"separatorColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigBarTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"barTintColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigBackgroundColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"backgroundColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigPlaceholderColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"_placeholderLabel.textColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigTrackTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"trackTintColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigProgressTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"progressTintColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigHighlightedTextColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"highlightedTextColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigPageIndicatorTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"pageIndicatorTintColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigCurrentPageIndicatorTintColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"currentPageIndicatorTintColor" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifierAndState)LeeConfigButtonTitleColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier , UIControlState state){
+        
+        NSMutableDictionary *info = weakSelf.modelThemeIdentifierConfigInfo[@(LEEThemeIdentifierConfigTypeButtonTitleColor)];
+        
+        if (!info) info = [NSMutableDictionary dictionary];
+        
+        [info setObject:identifier forKey:@(state)];
+        
+        [weakSelf.modelThemeIdentifierConfigInfo setObject:info forKey:@(LEEThemeIdentifierConfigTypeButtonTitleColor)];
+        
+        [weakSelf initCurrentThemeConfigHandleWithIdentifier:identifier];
+        
+        return weakSelf;
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifierAndState)LeeConfigButtonTitleShadowColor{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier , UIControlState state){
+        
+        NSMutableDictionary *info = weakSelf.modelThemeIdentifierConfigInfo[@(LEEThemeIdentifierConfigTypeButtonTitleShadowColor)];
+        
+        if (!info) info = [NSMutableDictionary dictionary];
+        
+        [info setObject:identifier forKey:@(state)];
+        
+        [weakSelf.modelThemeIdentifierConfigInfo setObject:info forKey:@(LEEThemeIdentifierConfigTypeButtonTitleShadowColor)];
+        
+        [weakSelf initCurrentThemeConfigHandleWithIdentifier:identifier];
+        
+        return weakSelf;
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"image" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigTrackImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"trackImage" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigProgressImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"progressImage" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigShadowImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"shadowImage" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigSelectedImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"selectedImage" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigBackgroundImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"backgroundImage" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigBackIndicatorImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"backIndicatorImage" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigBackIndicatorTransitionMaskImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"backIndicatorTransitionMaskImage" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigSelectionIndicatorImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"selectionIndicatorImage" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifier)LeeConfigScopeBarBackgroundImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier){
+        
+        return weakSelf.LeeConfigKeyPathAndIdentifier(@"scopeBarBackgroundImage" , identifier);
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifierAndState)LeeConfigButtonImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier , UIControlState state){
+        
+        NSMutableDictionary *info = weakSelf.modelThemeIdentifierConfigInfo[@(LEEThemeIdentifierConfigTypeButtonImage)];
+        
+        if (!info) info = [NSMutableDictionary dictionary];
+        
+        [info setObject:identifier forKey:@(state)];
+        
+        [weakSelf.modelThemeIdentifierConfigInfo setObject:info forKey:@(LEEThemeIdentifierConfigTypeButtonImage)];
+        
+        [weakSelf initCurrentThemeConfigHandleWithIdentifier:identifier];
+        
+        return weakSelf;
+    };
+    
+}
+
+- (LEEConfigThemeToIdentifierAndState)LeeConfigButtonBackgroundImage{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *identifier , UIControlState state){
+        
+        NSMutableDictionary *info = weakSelf.modelThemeIdentifierConfigInfo[@(LEEThemeIdentifierConfigTypeButtonBackgroundImage)];
+        
+        if (!info) info = [NSMutableDictionary dictionary];
+        
+        [info setObject:identifier forKey:@(state)];
+        
+        [weakSelf.modelThemeIdentifierConfigInfo setObject:info forKey:@(LEEThemeIdentifierConfigTypeButtonBackgroundImage)];
+        
+        [weakSelf initCurrentThemeConfigHandleWithIdentifier:identifier];
+        
+        return weakSelf;
+    };
+    
+}
+
+- (LEEConfigThemeToString)LeeConfigKeyPathAndIdentifier{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(NSString *keyPath , NSString *identifier){
+        
+        [weakSelf.modelThemeIdentifierConfigInfo setObject:identifier forKey:keyPath];
+        
+        [weakSelf initCurrentThemeConfigHandleWithIdentifier:identifier];
+        
+        return weakSelf;
+    };
+    
+}
+
+- (LEEConfigThemeToFloat)LeeChangeThemeAnimationDuration{
+    
+    __weak typeof(self) weakSelf = self;
+    
+    return ^(CGFloat number){
+        
+        _modelChangeThemeAnimationDuration = number;
+        
+        return weakSelf;
+    };
+    
+}
+
+#pragma mark - LazyLoading
+
+- (NSMutableDictionary *)modelThemeConfigInfo{
+    
+    if (!_modelThemeConfigInfo) _modelThemeConfigInfo = [NSMutableDictionary dictionary];
+
+    return _modelThemeConfigInfo;
+}
+
+- (NSMutableDictionary *)modelThemeIdentifierConfigInfo{
+    
+    if (!_modelThemeIdentifierConfigInfo) _modelThemeIdentifierConfigInfo = [NSMutableDictionary dictionary];
+    
+    return _modelThemeIdentifierConfigInfo;
+}
+
+- (NSMutableDictionary *)modelThemeColorConfigInfo{
+    
+    if (!_modelThemeColorConfigInfo) _modelThemeColorConfigInfo = [NSMutableDictionary dictionary];
+    
+    return _modelThemeColorConfigInfo;
+}
+
+- (NSMutableDictionary *)modelThemeButtonTitleColorConfigInfo{
+    
+    if(!_modelThemeButtonTitleColorConfigInfo) _modelThemeButtonTitleColorConfigInfo = [NSMutableDictionary dictionary];
+    
+    return _modelThemeButtonTitleColorConfigInfo;
+}
+
+- (NSMutableDictionary *)modelThemeButtonShadowTitleColorConfigInfo{
+    
+    if (!_modelThemeButtonShadowTitleColorConfigInfo) _modelThemeButtonShadowTitleColorConfigInfo = [NSMutableDictionary dictionary];
+        
+    return _modelThemeButtonShadowTitleColorConfigInfo;
+}
+
+- (NSMutableDictionary *)modelThemeImageConfigInfo{
+    
+    if (!_modelThemeImageConfigInfo) _modelThemeImageConfigInfo = [NSMutableDictionary dictionary];
+    
+    return _modelThemeImageConfigInfo;
+}
+
+- (NSMutableDictionary *)modelThemeButtonImageConfigInfo{
+    
+    if (!_modelThemeButtonImageConfigInfo) _modelThemeButtonImageConfigInfo = [NSMutableDictionary dictionary];
+    
+    return _modelThemeButtonImageConfigInfo;
+}
+
+- (NSMutableDictionary *)modelThemeButtonBackgroundImageConfigInfo{
+    
+    if (!_modelThemeButtonBackgroundImageConfigInfo) _modelThemeButtonBackgroundImageConfigInfo = [NSMutableDictionary dictionary];
+    
+    return _modelThemeButtonBackgroundImageConfigInfo;
+}
+
+@end
+
+#pragma mark - ----------------主题设置----------------
+
+@implementation NSObject (LEEThemeConfigObject)
+
++(void)load{
+    
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        
+        NSArray *selStringsArray = @[@"dealloc"];
+        
+        [selStringsArray enumerateObjectsUsingBlock:^(NSString *selString, NSUInteger idx, BOOL *stop) {
+            
+            NSString *leeSelString = [@"lee_" stringByAppendingString:selString];
+            
+            Method originalMethod = class_getInstanceMethod(self, NSSelectorFromString(selString));
+            
+            Method leeMethod = class_getInstanceMethod(self, NSSelectorFromString(leeSelString));
+            
+            method_exchangeImplementations(originalMethod, leeMethod);
+        }];
+        
+    });
+    
+}
+
+- (void)lee_dealloc{
+    
+    if ([self isLeeTheme]) {
+        
+        [[NSNotificationCenter defaultCenter] removeObserver:self name:LEEThemeChangingNotificaiton object:nil];
+        
+        objc_removeAssociatedObjects(self);
+    }
+
+    [self lee_dealloc];
+}
+
+- (void)leeTheme_ChangeThemeConfigNotify:(NSNotification *)notify{
+    
+    dispatch_async(dispatch_get_main_queue(), ^{
+
+        [UIView beginAnimations:@"LEEThemeChangeAnimations" context:nil];
+        
+        [UIView setAnimationDuration:self.lee_theme.modelChangeThemeAnimationDuration >= 0.0f ? self.lee_theme.modelChangeThemeAnimationDuration : [LEETheme shareTheme].animationDuration ];
+        
+        [self changeThemeConfigWithAboutConfigBlock:nil];
+        
+        [UIView commitAnimations];
+    });
+
+}
+
+- (BOOL)isChangeTheme{
+    
+    return (!self.lee_theme.modelCurrentThemeTag || ![self.lee_theme.modelCurrentThemeTag isEqualToString:[LEETheme currentThemeTag]]) ? YES : NO;
+}
+
+- (BOOL)isCGColorWithKeyPath:(NSString *)keyPath{
+    
+    objc_property_t property = class_getProperty([self class] , [keyPath UTF8String]);
+    
+    if(property != NULL) {
+        
+        return ([[NSString stringWithUTF8String:property_getAttributes(property)] isEqualToString:@"T^{CGColor=}"]) ? YES : NO;
+    
+    } else {
+        
+        return NO;
+    }
+    
+}
+
+- (UIColor *)getCurrentThemeTagColorWithKeyPath:(NSString *)keyPath{
+    
+    return [UIColor leeTheme_ColorFromJsonWithTag:[LEETheme currentThemeTag] WithIdentifier:self.lee_theme.modelThemeIdentifierConfigInfo[keyPath]];
+}
+
+- (UIColor *)getCurrentThemeTagButtonColorWithType:(LEEThemeIdentifierConfigType)type WithState:(NSNumber *)state{
+    
+    NSDictionary *info = self.lee_theme.modelThemeIdentifierConfigInfo[@(type)];
+    
+    NSString *identifier = info[state];
+    
+    return [UIColor leeTheme_ColorFromJsonWithTag:[LEETheme currentThemeTag] WithIdentifier:identifier];
+}
+
+- (UIImage *)getCurrentThemeTagImageWithKeyPath:(NSString *)keyPath{
+    
+    return [UIImage leeTheme_ImageFromJsonWithTag:[LEETheme currentThemeTag] WithIdentifier:self.lee_theme.modelThemeIdentifierConfigInfo[keyPath]];
+}
+
+- (UIImage *)getCurrentThemeTagButtonImageWithType:(LEEThemeIdentifierConfigType)type WithState:(NSNumber *)state{
+    
+    NSDictionary *info = self.lee_theme.modelThemeIdentifierConfigInfo[@(type)];
+    
+    NSString *identifier = info[state];
+    
+    return [UIImage leeTheme_ImageFromJsonWithTag:[LEETheme currentThemeTag] WithIdentifier:identifier];
+}
+
+- (id)getCurrentThemeTagValueWithIdentifier:(NSString *)identifier{
+    
+    id value = [LEETheme shareTheme].jsonConfigInfo[[LEETheme currentThemeTag]][@"json"][@"other"][identifier];
+    
+    return value;
+}
+
+- (void)changeThemeConfigWithAboutConfigBlock:(void (^)())aboutConfigBlock{
+    
+    if ([self isChangeTheme]) {
+        
+        self.lee_theme.modelCurrentThemeTag = [LEETheme currentThemeTag];
+        
+        LEEThemeConfigBlock configBlock = self.lee_theme.modelThemeConfigInfo[[LEETheme currentThemeTag]];
+        
+        NSDictionary *identifierConfigInfo = self.lee_theme.modelThemeIdentifierConfigInfo[@(LEEThemeIdentifierConfigTypeCustomConfig)];
+        
+        if (aboutConfigBlock) aboutConfigBlock();
+        
+        for (NSString *keyPath in self.lee_theme.modelThemeColorConfigInfo) {
+            
+            UIColor *color = self.lee_theme.modelThemeColorConfigInfo[keyPath][[LEETheme currentThemeTag]];
+            
+            if (color) [self isCGColorWithKeyPath:keyPath] ? [self setValue:(id)color.CGColor forKeyPath:keyPath] : [self setValue:color forKeyPath:keyPath];
+        }
+        
+        for (NSString *keyPath in self.lee_theme.modelThemeImageConfigInfo) {
+            
+            id image = self.lee_theme.modelThemeImageConfigInfo[keyPath][[LEETheme currentThemeTag]];
+            
+            if ([image isKindOfClass:[NSString class]]) {
+                
+                NSString *info = image;
+                
+                image = [UIImage imageNamed:image];
+                
+                if (!image) image = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:info]];
+                
+                if (!image) image = [UIImage imageWithContentsOfFile:info];
+            }
+            
+            if (image) if ([image isKindOfClass:[UIImage class]]) [self setValue:image forKeyPath:keyPath];
+        }
+        
+        for (NSString *keyPath in self.lee_theme.modelThemeIdentifierConfigInfo) {
+            
+            if (![keyPath isKindOfClass:[NSString class]]) continue;
+            
+            id value = [self getCurrentThemeTagColorWithKeyPath:keyPath];
+            
+            if ([self isCGColorWithKeyPath:keyPath]) value = (id)[(UIColor *)value CGColor];
+            
+            if (!value) value = [self getCurrentThemeTagImageWithKeyPath:keyPath];
+            
+            if (value) [self setValue:value forKeyPath:keyPath];
+        }
+        
+        if (configBlock) configBlock(self);
+        
+        if (identifierConfigInfo) {
+            
+            for (NSString *identifier in identifierConfigInfo.allKeys) {
+                
+                LEEThemeConfigBlockToIdentifier configBlockItem = identifierConfigInfo[identifier];
+                
+                if (configBlockItem) configBlockItem(self , [self getCurrentThemeTagValueWithIdentifier:identifier]);
+            }
+            
+        }
+
+    }
+    
+}
+
+- (LEEThemeConfigModel *)lee_theme{
+    
+    LEEThemeConfigModel *model = objc_getAssociatedObject(self, _cmd);
+    
+    if (!model) {
+        
+        NSAssert(![self isKindOfClass:[LEEThemeConfigModel class]], @"是不是点多了? ( *・ω・)✄╰ひ╯ ");
+        
+        model = [LEEThemeConfigModel new];
+        
+        objc_setAssociatedObject(self, _cmd, model , OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+        
+        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(leeTheme_ChangeThemeConfigNotify:) name:LEEThemeChangingNotificaiton object:nil];
+        
+        [self setIsLeeTheme:YES];
+        
+        __weak typeof(self) weakSelf = self;
+        
+        model.modelInitCurrentThemeConfig = ^(){
+            
+            weakSelf.lee_theme.modelCurrentThemeTag = nil;
+            
+            if (weakSelf) [weakSelf changeThemeConfigWithAboutConfigBlock:nil];
+        };
+        
+    }
+    
+    return model;
+}
+
+- (void)setLee_theme:(LEEThemeConfigModel *)lee_theme{
+    
+    if(self) if(lee_theme) objc_setAssociatedObject(self, @selector(lee_theme), lee_theme , OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+- (BOOL)isLeeTheme{
+    
+    return self ? [objc_getAssociatedObject(self, _cmd) boolValue] : NO;
+}
+
+- (void)setIsLeeTheme:(BOOL)isLeeTheme{
+    
+    if (self) objc_setAssociatedObject(self, @selector(isLeeTheme), @(isLeeTheme) , OBJC_ASSOCIATION_ASSIGN);
+}
+
+@end
+
+@implementation UIButton (LEEThemeConfigButton)
+
+- (void)changeThemeConfigWithAboutConfigBlock:(void (^)())aboutConfigBlock{
+    
+    if ([self isChangeTheme]) {
+        
+        __weak typeof(self) weakSelf = self;
+        
+        aboutConfigBlock = ^(){
+            
+            NSDictionary *titleColorInfo = weakSelf.lee_theme.modelThemeButtonTitleColorConfigInfo[[LEETheme currentThemeTag]];
+            
+            if (!titleColorInfo) titleColorInfo = weakSelf.lee_theme.modelThemeIdentifierConfigInfo[@(LEEThemeIdentifierConfigTypeButtonTitleColor)];
+            
+            for (NSNumber *key in titleColorInfo.allKeys) {
+                
+                id value = titleColorInfo[key];
+                
+                UIColor *titleColor = [value isKindOfClass:[UIColor class]] ? value : nil;
+                
+                if (!titleColor) titleColor = [weakSelf getCurrentThemeTagButtonColorWithType:LEEThemeIdentifierConfigTypeButtonTitleColor WithState:key];
+                
+                if (titleColor) [weakSelf setTitleColor:titleColor forState:(UIControlState)[key integerValue]];
+            }
+            
+            NSDictionary *titleShadowColorInfo = weakSelf.lee_theme.modelThemeButtonShadowTitleColorConfigInfo[[LEETheme currentThemeTag]];
+            
+            if (!titleShadowColorInfo) titleShadowColorInfo = weakSelf.lee_theme.modelThemeIdentifierConfigInfo[@(LEEThemeIdentifierConfigTypeButtonTitleShadowColor)];
+            
+            for (NSNumber *key in titleShadowColorInfo.allKeys) {
+                
+                id value = titleShadowColorInfo[key];
+                
+                UIColor *titleShadowColor = [value isKindOfClass:[UIColor class]] ? value : nil;
+                
+                if (!titleShadowColor) titleShadowColor = [weakSelf getCurrentThemeTagButtonColorWithType:LEEThemeIdentifierConfigTypeButtonTitleShadowColor WithState:key];
+                
+                if (titleShadowColor) [weakSelf setTitleShadowColor:titleShadowColor forState:(UIControlState)[key integerValue]];
+            }
+            
+            NSDictionary *imageInfo = weakSelf.lee_theme.modelThemeButtonImageConfigInfo[[LEETheme currentThemeTag]];
+            
+            if (!imageInfo) imageInfo = weakSelf.lee_theme.modelThemeIdentifierConfigInfo[@(LEEThemeIdentifierConfigTypeButtonImage)];
+            
+            for (NSNumber *key in imageInfo.allKeys) {
+                
+                id value = imageInfo[key];
+                
+                UIImage *image = [value isKindOfClass:[UIImage class]] ? value : nil;
+                
+                if (!image) image = [weakSelf getCurrentThemeTagButtonImageWithType:LEEThemeIdentifierConfigTypeButtonImage WithState:key];
+                
+                if (image) [weakSelf setImage:image forState:(UIControlState)[key integerValue]];
+            }
+            
+            NSDictionary *backgroundImageInfo = weakSelf.lee_theme.modelThemeButtonBackgroundImageConfigInfo[[LEETheme currentThemeTag]];
+            
+            if (!backgroundImageInfo) backgroundImageInfo = weakSelf.lee_theme.modelThemeIdentifierConfigInfo[@(LEEThemeIdentifierConfigTypeButtonBackgroundImage)];
+            
+            for (NSNumber *key in backgroundImageInfo.allKeys) {
+                
+                id value = backgroundImageInfo[key];
+                
+                UIImage *backgroundImage = [value isKindOfClass:[UIImage class]] ? value : nil;
+                
+                if (!backgroundImage) backgroundImage = [weakSelf getCurrentThemeTagButtonImageWithType:LEEThemeIdentifierConfigTypeButtonBackgroundImage WithState:key];
+                
+                if (backgroundImage) [weakSelf setBackgroundImage:backgroundImage forState:(UIControlState)[key integerValue]];
+            }
+            
+        };
+        
+        [super changeThemeConfigWithAboutConfigBlock:aboutConfigBlock];
+    }
+    
+}
+
+@end
+
+#pragma mark - ----------------工具扩展----------------
+
+@implementation UIColor (LEEThemeColor)
+
++ (UIColor *)leeTheme_ColorWithHexString:(NSString *)hexString{
+    
+    if (!hexString) return nil;
+    
+    NSString *colorString = [[hexString stringByReplacingOccurrencesOfString: @"#" withString: @""] uppercaseString];
+    
+    CGFloat alpha, red, blue, green;
+    
+    switch ([colorString length]) {
+        case 0:
+            return nil;
+        case 3: // #RGB
+            alpha = 1.0f;
+            red   = [self colorComponentFrom: colorString start: 0 length: 1];
+            green = [self colorComponentFrom: colorString start: 1 length: 1];
+            blue  = [self colorComponentFrom: colorString start: 2 length: 1];
+            break;
+        case 4: // #ARGB
+            alpha = [self colorComponentFrom: colorString start: 0 length: 1];
+            red   = [self colorComponentFrom: colorString start: 1 length: 1];
+            green = [self colorComponentFrom: colorString start: 2 length: 1];
+            blue  = [self colorComponentFrom: colorString start: 3 length: 1];
+            break;
+        case 6: // #RRGGBB
+            alpha = 1.0f;
+            red   = [self colorComponentFrom: colorString start: 0 length: 2];
+            green = [self colorComponentFrom: colorString start: 2 length: 2];
+            blue  = [self colorComponentFrom: colorString start: 4 length: 2];
+            break;
+        case 8: // #AARRGGBB
+            alpha = [self colorComponentFrom: colorString start: 0 length: 2];
+            red   = [self colorComponentFrom: colorString start: 2 length: 2];
+            green = [self colorComponentFrom: colorString start: 4 length: 2];
+            blue  = [self colorComponentFrom: colorString start: 6 length: 2];
+            break;
+        default:
+            alpha = 0, red = 0, blue = 0, green = 0;
+            break;
+    }
+    
+    return [UIColor colorWithRed: red green: green blue: blue alpha: alpha];
+}
+
++ (CGFloat) colorComponentFrom: (NSString *) string start:(NSUInteger) start length:(NSUInteger) length{
+    
+    NSString *substring = [string substringWithRange: NSMakeRange(start, length)];
+    NSString *fullHex = length == 2 ? substring : [NSString stringWithFormat: @"%@%@", substring, substring];
+    unsigned hexComponent;
+    [[NSScanner scannerWithString: fullHex] scanHexInt: &hexComponent];
+    return hexComponent / 255.0f;
+}
+
++ (UIColor *)leeTheme_ColorFromJsonWithTag:(NSString *)tag WithIdentifier:(NSString *)identifier{
+    
+    NSString *colorHexString = [LEETheme shareTheme].jsonConfigInfo[tag][@"json"][@"color"][identifier];
+    
+    return colorHexString ? [UIColor leeTheme_ColorWithHexString:colorHexString] : nil;
+}
+
+@end
+
+@implementation UIImage (LEEThemeImage) 
+
++ (UIImage *)leeTheme_ImageFromJsonWithTag:(NSString *)tag WithIdentifier:(NSString *)identifier{
+    
+    NSString *imageName = [LEETheme shareTheme].jsonConfigInfo[tag][@"json"][@"image"][identifier];
+    
+    NSString *path = [LEETheme shareTheme].jsonConfigInfo[[LEETheme currentThemeTag]][@"path"];
+    
+    UIImage *image = path ? [UIImage imageWithContentsOfFile:[path stringByAppendingPathComponent:imageName]] : [UIImage imageNamed:imageName];
+    
+    if (!image) image = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:imageName]];
+    
+    return image;
+}
+
+@end

+ 50 - 0
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmojiLabel.h

@@ -0,0 +1,50 @@
+//
+//  MLEmojiLabel.h
+//  MLEmojiLabel
+//
+//  Created by molon on 5/19/14.
+//  Copyright (c) 2014 molon. All rights reserved.
+//
+
+#import "TTTAttributedLabel.h"
+
+
+typedef NS_OPTIONS(NSUInteger, MLEmojiLabelLinkType) {
+    MLEmojiLabelLinkTypeURL = 0,
+    MLEmojiLabelLinkTypeEmail,
+    MLEmojiLabelLinkTypePhoneNumber,
+    MLEmojiLabelLinkTypeAt,
+    MLEmojiLabelLinkTypePoundSign,
+};
+
+
+@class MLEmojiLabel;
+@protocol MLEmojiLabelDelegate <TTTAttributedLabelDelegate>
+
+@optional
+- (void)mlEmojiLabel:(MLEmojiLabel*)emojiLabel didSelectLink:(NSString*)link withType:(MLEmojiLabelLinkType)type;
+
+
+@end
+
+@interface MLEmojiLabel : TTTAttributedLabel
+
+@property (nonatomic, assign) BOOL disableEmoji; //禁用表情
+@property (nonatomic, assign) BOOL disableThreeCommon; //禁用电话,邮箱,连接三者
+
+@property (nonatomic, assign) BOOL isNeedAtAndPoundSign; //是否需要话题和@功能,默认为不需要
+
+@property (nonatomic, copy) NSString *customEmojiRegex; //自定义表情正则
+@property (nonatomic, copy) NSString *customEmojiPlistName; //xxxxx.plist 格式
+@property (nonatomic, copy) NSString *customEmojiBundleName; //自定义表情图片所存储的bundleName xxxx.bundle格式
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wobjc-property-synthesis"
+@property (nonatomic, weak) id<MLEmojiLabelDelegate> delegate; //点击连接的代理方法
+#pragma clang diagnostic pop
+
+@property (nonatomic, copy, readonly) id emojiText; //外部能获取text的原始副本
+
+- (CGSize)preferredSizeWithMaxWidth:(CGFloat)maxWidth;
+
+@end

+ 716 - 0
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmojiLabel.m

@@ -0,0 +1,716 @@
+//
+//  MLEmojiLabel.m
+//  MLEmojiLabel
+//
+//  Created by molon on 5/19/14.
+//  Copyright (c) 2014 molon. All rights reserved.
+//
+
+#import "MLEmojiLabel.h"
+
+#pragma mark - 正则列表
+
+#define REGULAREXPRESSION_OPTION(regularExpression,regex,option) \
+\
+static inline NSRegularExpression * k##regularExpression() { \
+static NSRegularExpression *_##regularExpression = nil; \
+static dispatch_once_t onceToken; \
+dispatch_once(&onceToken, ^{ \
+_##regularExpression = [[NSRegularExpression alloc] initWithPattern:(regex) options:(option) error:nil];\
+});\
+\
+return _##regularExpression;\
+}\
+
+
+#define REGULAREXPRESSION(regularExpression,regex) REGULAREXPRESSION_OPTION(regularExpression,regex,NSRegularExpressionCaseInsensitive)
+
+
+REGULAREXPRESSION(URLRegularExpression,@"((http[s]{0,1}|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\\.\\-~!@#$%^&*+?:_/=<>]*)?)")
+
+REGULAREXPRESSION(PhoneNumerRegularExpression, @"\\d{3}-\\d{8}|\\d{3}-\\d{7}|\\d{4}-\\d{8}|\\d{4}-\\d{7}|1+[358]+\\d{9}|\\d{8}|\\d{7}")
+
+REGULAREXPRESSION(EmailRegularExpression, @"[A-Z0-9a-z\\._%+-]+@([A-Za-z0-9-]+\\.)+[A-Za-z]{2,4}")
+
+REGULAREXPRESSION(AtRegularExpression, @"@[\\u4e00-\\u9fa5\\w\\-]+")
+
+
+//@"#([^\\#|.]+)#"
+REGULAREXPRESSION_OPTION(PoundSignRegularExpression, @"#([\\u4e00-\\u9fa5\\w\\-]+)#", NSRegularExpressionCaseInsensitive)
+
+//微信的表情符其实不是这种格式,这个格式的只是让人看起来更友好。。
+//REGULAREXPRESSION(EmojiRegularExpression, @"\\[[a-zA-Z0-9\\u4e00-\\u9fa5]+\\]")
+
+//@"/:[\\w:~!@$&*()|+<>',?-]{1,8}" , // @"/:[\\x21-\\x2E\\x30-\\x7E]{1,8}" ,经过检测发现\w会匹配中文,好奇葩。
+REGULAREXPRESSION(SlashEmojiRegularExpression, @"/:[\\x21-\\x2E\\x30-\\x7E]{1,8}")
+
+const CGFloat kLineSpacing = 4.0;
+const CGFloat kAscentDescentScale = 0.25; //在这里的话无意义,高度的结局都是和宽度一样
+
+const CGFloat kEmojiWidthRatioWithLineHeight = 1.15;//和字体高度的比例
+
+const CGFloat kEmojiOriginYOffsetRatioWithLineHeight = 0.10; //表情绘制的y坐标矫正值,和字体高度的比例,越大越往下
+NSString *const kCustomGlyphAttributeImageName = @"CustomGlyphAttributeImageName";
+
+#define kEmojiReplaceCharacter @"\uFFFC"
+
+#define kURLActionCount 5
+NSString * const kURLActions[] = {@"url->",@"email->",@"phoneNumber->",@"at->",@"poundSign->"};
+
+/**
+ *  搞个管理器,否则自定义plist的话,每个label都会有个副本很操蛋
+ */
+@interface MLEmojiLabelRegexPlistManager : NSObject
+
+- (NSDictionary*)emojiDictForKey:(NSString*)key;
+
+@property (nonatomic, strong) NSMutableDictionary *emojiDictRecords;
+@property (nonatomic, strong) NSMutableDictionary *emojiRegularExpressions;
+
+@end
+
+@implementation MLEmojiLabelRegexPlistManager
+
++ (instancetype)sharedInstance {
+    static MLEmojiLabelRegexPlistManager *_sharedInstance = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        _sharedInstance = [[[self class] alloc]init];
+    });
+    return _sharedInstance;
+}
+
+#pragma mark - getter
+- (NSMutableDictionary *)emojiDictRecords
+{
+    if (!_emojiDictRecords) {
+        _emojiDictRecords = [NSMutableDictionary new];
+    }
+    return _emojiDictRecords;
+}
+
+- (NSMutableDictionary *)emojiRegularExpressions
+{
+    if (!_emojiRegularExpressions) {
+        _emojiRegularExpressions = [NSMutableDictionary new];
+    }
+    return _emojiRegularExpressions;
+}
+
+#pragma mark - common
+- (NSDictionary*)emojiDictForKey:(NSString*)key
+{
+    NSAssert(key&&key.length>0, @"emojiDictForKey:参数不得为空");
+    
+    if (self.emojiDictRecords[key]) {
+        return self.emojiDictRecords[key];
+    }
+    
+    
+    NSString *emojiFilePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:key];
+    NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:emojiFilePath];
+    NSAssert(dict,@"表情字典%@找不到",key);
+    self.emojiDictRecords[key] = dict;
+    
+    return self.emojiDictRecords[key];
+}
+
+- (NSRegularExpression *)regularExpressionForRegex:(NSString*)regex
+{
+    NSAssert(regex&&regex.length>0, @"regularExpressionForKey:参数不得为空");
+    
+    if (self.emojiRegularExpressions[regex]) {
+        return self.emojiRegularExpressions[regex];
+    }
+    
+    NSRegularExpression *re = [[NSRegularExpression alloc] initWithPattern:regex options:NSRegularExpressionCaseInsensitive error:nil];
+    
+    NSAssert(re,@"正则%@有误",regex);
+    self.emojiRegularExpressions[regex] = re;
+    
+    return self.emojiRegularExpressions[regex];
+}
+
+@end
+
+@interface TTTAttributedLabel(MLEmojiLabel)
+
+@property (readwrite, nonatomic, strong) TTTAttributedLabelLink *activeLink;
+
+- (void)commonInit;
+- (NSArray *)addLinksWithTextCheckingResults:(NSArray *)results
+                                  attributes:(NSDictionary *)attributes;
+- (void)drawStrike:(CTFrameRef)frame
+            inRect:(CGRect)rect
+           context:(CGContextRef)c;
+
+@end
+
+@interface MLEmojiLabel()
+
+@property (nonatomic, weak) NSRegularExpression *customEmojiRegularExpression;
+@property (nonatomic, weak) NSDictionary *customEmojiDictionary; //这玩意如果有也是在MLEmojiLabelPlistManager单例里面存着
+
+@property (nonatomic, assign) BOOL ignoreSetText;
+
+//留个初始副本
+@property (nonatomic, copy) id emojiText;
+
+@end
+
+@implementation MLEmojiLabel
+
+#pragma mark - 表情包字典
++ (NSDictionary *)emojiDictionary {
+    static NSDictionary *emojiDictionary = nil;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        NSString *emojiFilePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"MLEmoji_ExpressionImage.plist"];
+        emojiDictionary = [[NSDictionary alloc] initWithContentsOfFile:emojiFilePath];
+    });
+    return emojiDictionary;
+}
+
+#pragma mark - 表情 callback
+typedef struct CustomGlyphMetrics {
+    CGFloat ascent;
+    CGFloat descent;
+    CGFloat width;
+} CustomGlyphMetrics, *CustomGlyphMetricsRef;
+
+static void deallocCallback(void *refCon) {
+    free(refCon), refCon = NULL;
+}
+
+static CGFloat ascentCallback(void *refCon) {
+    CustomGlyphMetricsRef metrics = (CustomGlyphMetricsRef)refCon;
+    return metrics->ascent;
+}
+
+static CGFloat descentCallback(void *refCon) {
+    CustomGlyphMetricsRef metrics = (CustomGlyphMetricsRef)refCon;
+    return metrics->descent;
+}
+
+static CGFloat widthCallback(void *refCon) {
+    CustomGlyphMetricsRef metrics = (CustomGlyphMetricsRef)refCon;
+    return metrics->width;
+}
+
+#pragma mark - 初始化和TTT的一些修正
+- (void)commonInit {
+    [super commonInit];
+    
+    self.numberOfLines = 0;
+    self.font = [UIFont systemFontOfSize:14.0];
+    self.textColor = [UIColor blackColor];
+    self.backgroundColor = [UIColor clearColor];
+    
+    self.lineBreakMode = NSLineBreakByCharWrapping;
+    
+    self.lineSpacing = kLineSpacing; //默认行间距
+    
+    //链接默认样式重新设置
+    NSMutableDictionary *mutableLinkAttributes = [@{(NSString *)kCTUnderlineStyleAttributeName:@(NO)}mutableCopy];
+    
+    NSMutableDictionary *mutableActiveLinkAttributes = [@{(NSString *)kCTUnderlineStyleAttributeName:@(NO)}mutableCopy];
+    
+    UIColor *commonLinkColor = [UIColor colorWithRed:0.112 green:0.000 blue:0.791 alpha:1.000];
+    
+    //点击时候的背景色
+    [mutableActiveLinkAttributes setValue:(__bridge id)[[UIColor colorWithWhite:0.631 alpha:1.000] CGColor] forKey:(NSString *)kTTTBackgroundFillColorAttributeName];
+    
+    if ([NSMutableParagraphStyle class]) {
+        [mutableLinkAttributes setObject:commonLinkColor forKey:(NSString *)kCTForegroundColorAttributeName];
+        [mutableActiveLinkAttributes setObject:commonLinkColor forKey:(NSString *)kCTForegroundColorAttributeName];
+    } else {
+        [mutableLinkAttributes setObject:(__bridge id)[commonLinkColor CGColor] forKey:(NSString *)kCTForegroundColorAttributeName];
+        [mutableActiveLinkAttributes setObject:(__bridge id)[commonLinkColor CGColor] forKey:(NSString *)kCTForegroundColorAttributeName];
+    }
+    
+    self.linkAttributes = [NSDictionary dictionaryWithDictionary:mutableLinkAttributes];
+    self.activeLinkAttributes = [NSDictionary dictionaryWithDictionary:mutableActiveLinkAttributes];
+}
+
+/**
+ *  如果是有attributedText的情况下,有可能会返回少那么点的,这里矫正下
+ *
+ */
+- (CGSize)sizeThatFits:(CGSize)size {
+    if (!self.attributedText) {
+        return [super sizeThatFits:size];
+    }
+    
+    CGSize rSize = [super sizeThatFits:size];
+    rSize.height +=1;
+    return rSize;
+}
+
+
+//这里是抄TTT里的,因为他不是放在外面的
+static inline CGFloat TTTFlushFactorForTextAlignment(NSTextAlignment textAlignment) {
+    switch (textAlignment) {
+        case NSTextAlignmentCenter:
+            return 0.5f;
+        case NSTextAlignmentRight:
+            return 1.0f;
+        case NSTextAlignmentLeft:
+        default:
+            return 0.0f;
+    }
+}
+
+#pragma mark - 绘制表情
+- (void)drawStrike:(CTFrameRef)frame
+            inRect:(CGRect)rect
+           context:(CGContextRef)c
+{
+    [super drawStrike:frame inRect:rect context:c];
+    
+    //PS:这个是在TTT里drawFramesetter....方法最后做了修改的基础上。
+    CGFloat emojiWith = self.font.lineHeight*kEmojiWidthRatioWithLineHeight;
+    CGFloat emojiOriginYOffset = self.font.lineHeight*kEmojiOriginYOffsetRatioWithLineHeight;
+    
+    //修正绘制offset,根据当前设置的textAlignment
+    CGFloat flushFactor = TTTFlushFactorForTextAlignment(self.textAlignment);
+    
+    CFArrayRef lines = CTFrameGetLines(frame);
+    NSInteger numberOfLines = self.numberOfLines > 0 ? MIN(self.numberOfLines, CFArrayGetCount(lines)) : CFArrayGetCount(lines);
+    CGPoint lineOrigins[numberOfLines];
+    CTFrameGetLineOrigins(frame, CFRangeMake(0, numberOfLines), lineOrigins);
+    
+    BOOL truncateLastLine = (self.lineBreakMode == NSLineBreakByTruncatingHead || self.lineBreakMode == NSLineBreakByTruncatingMiddle || self.lineBreakMode == NSLineBreakByTruncatingTail);
+    CFRange textRange = CFRangeMake(0, (CFIndex)[self.attributedText length]);
+    
+    for (CFIndex lineIndex = 0; lineIndex < numberOfLines; lineIndex++) {
+        CTLineRef line = CFArrayGetValueAtIndex(lines, lineIndex);
+        
+        //这里其实是能获取到当前行的真实origin.x,根据textAlignment,而lineBounds.origin.x其实是默认一直为0的(不会受textAlignment影响)
+        CGFloat penOffset = (CGFloat)CTLineGetPenOffsetForFlush(line, flushFactor, rect.size.width);
+        
+        CFIndex truncationAttributePosition = -1;
+        //检测如果是最后一行,是否有替换...
+        if (lineIndex == numberOfLines - 1 && truncateLastLine) {
+            // Check if the range of text in the last line reaches the end of the full attributed string
+            CFRange lastLineRange = CTLineGetStringRange(line);
+            
+            if (!(lastLineRange.length == 0 && lastLineRange.location == 0) && lastLineRange.location + lastLineRange.length < textRange.location + textRange.length) {
+                // Get correct truncationType and attribute position
+                truncationAttributePosition = lastLineRange.location;
+                NSLineBreakMode lineBreakMode = self.lineBreakMode;
+                
+                // Multiple lines, only use UILineBreakModeTailTruncation
+                if (numberOfLines != 1) {
+                    lineBreakMode = NSLineBreakByTruncatingTail;
+                }
+                
+                switch (lineBreakMode) {
+                    case NSLineBreakByTruncatingHead:
+                        break;
+                    case NSLineBreakByTruncatingMiddle:
+                        truncationAttributePosition += (lastLineRange.length / 2);
+                        break;
+                    case NSLineBreakByTruncatingTail:
+                    default:
+                        truncationAttributePosition += (lastLineRange.length - 1);
+                        break;
+                }
+                
+                //如果要在truncationAttributePosition这个位置画表情需要忽略
+            }
+        }
+        
+        //找到当前行的每一个要素,姑且这么叫吧。可以理解为有单独的attr属性的各个range。
+        for (id glyphRun in (__bridge NSArray *)CTLineGetGlyphRuns(line)) {
+            //找到此要素所对应的属性
+            NSDictionary *attributes = (__bridge NSDictionary *)CTRunGetAttributes((__bridge CTRunRef) glyphRun);
+            //判断是否有图像,如果有就绘制上去
+            NSString *imageName = attributes[kCustomGlyphAttributeImageName];
+            if (imageName) {
+                CFRange glyphRange = CTRunGetStringRange((__bridge CTRunRef)glyphRun);
+                if (glyphRange.location == truncationAttributePosition) {
+                    //这里因为glyphRange的length肯定为1,所以只做这一个判断足够
+                    continue;
+                }
+                
+                CGRect runBounds = CGRectZero;
+                CGFloat runAscent = 0.0f;
+                CGFloat runDescent = 0.0f;
+                
+                runBounds.size.width = (CGFloat)CTRunGetTypographicBounds((__bridge CTRunRef)glyphRun, CFRangeMake(0, 0), &runAscent, &runDescent, NULL);
+                
+                if (runBounds.size.width!=emojiWith) {
+                    //这一句是为了在某些情况下,例如单行省略号模式下,默认行为会将个别表情的runDelegate改变,也就改变了其大小。这时候会引起界面上错乱,这里做下检测(浮点数做等于判断似乎有点操蛋啊。。)
+                    continue;
+                }
+                
+                runBounds.size.height = runAscent + runDescent;
+                
+                CGFloat xOffset = 0.0f;
+                switch (CTRunGetStatus((__bridge CTRunRef)glyphRun)) {
+                    case kCTRunStatusRightToLeft:
+                        xOffset = CTLineGetOffsetForStringIndex(line, glyphRange.location + glyphRange.length, NULL);
+                        break;
+                    default:
+                        xOffset = CTLineGetOffsetForStringIndex(line, glyphRange.location, NULL);
+                        break;
+                }
+                runBounds.origin.x = penOffset + xOffset;
+                runBounds.origin.y = lineOrigins[lineIndex].y;
+                runBounds.origin.y -= runDescent;
+                
+                NSString *imagePath = [self.customEmojiBundleName?:@"MLEmoji_Expression.bundle" stringByAppendingPathComponent:imageName];
+                UIImage *image = [UIImage imageNamed:imagePath];
+                runBounds.origin.y -= emojiOriginYOffset; //稍微矫正下。
+                CGContextDrawImage(c, runBounds, image.CGImage);
+            }
+        }
+    }
+    
+}
+
+
+#pragma mark - main
+/**
+ *  返回经过表情识别处理的Attributed字符串
+ */
+- (NSMutableAttributedString*)mutableAttributeStringWithEmojiText:(NSAttributedString *)emojiText
+{
+    //获取所有表情的位置
+    //    NSArray *emojis = [kEmojiRegularExpression() matchesInString:emojiText
+    //                                                         options:NSMatchingWithTransparentBounds
+    //                                                           range:NSMakeRange(0, [emojiText length])];
+    
+    NSArray *emojis = nil;
+    
+    if (self.customEmojiRegularExpression) {
+        //自定义表情正则
+        emojis = [self.customEmojiRegularExpression matchesInString:emojiText.string
+                                                            options:NSMatchingWithTransparentBounds
+                                                              range:NSMakeRange(0, [emojiText length])];
+    }else{
+        emojis = [kSlashEmojiRegularExpression() matchesInString:emojiText.string
+                                                         options:NSMatchingWithTransparentBounds
+                                                           range:NSMakeRange(0, [emojiText length])];
+    }
+    
+    NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] init];
+    NSUInteger location = 0;
+    
+    
+    CGFloat emojiWith = self.font.lineHeight*kEmojiWidthRatioWithLineHeight;
+    for (NSTextCheckingResult *result in emojis) {
+        NSRange range = result.range;
+        NSAttributedString *attSubStr = [emojiText attributedSubstringFromRange:NSMakeRange(location, range.location - location)];
+        [attrStr appendAttributedString:attSubStr];
+        
+        location = range.location + range.length;
+        
+        NSAttributedString *emojiKey = [emojiText attributedSubstringFromRange:range];
+        
+        NSDictionary *emojiDict = self.customEmojiRegularExpression?self.customEmojiDictionary:[MLEmojiLabel emojiDictionary];
+        
+        //如果当前获得key后面有多余的,这个需要记录下
+        NSAttributedString *otherAppendStr = nil;
+        
+        NSString *imageName = emojiDict[emojiKey.string];
+        if (!self.customEmojiRegularExpression) {
+            //微信的表情没有结束符号,所以有可能会发现过长的只有头部才是表情的段,需要循环检测一次。微信最大表情特殊字符是8个长度,检测8次即可
+            if (!imageName&&emojiKey.length>2) {
+                NSUInteger maxDetctIndex = emojiKey.length>8+2?8:emojiKey.length-2;
+                //从头开始检测是否有对应的
+                for (NSUInteger i=0; i<maxDetctIndex; i++) {
+                    //                NSLog(@"%@",[emojiKey.string substringToIndex:3+i]);
+                    imageName = emojiDict[[emojiKey.string substringToIndex:3+i]];
+                    if (imageName) {
+                        otherAppendStr = [emojiKey attributedSubstringFromRange:NSMakeRange(3+i, emojiKey.length-3-i)];
+                        break;
+                    }
+                }
+            }
+        }
+        
+        if (imageName) {
+            // 这里不用空格,空格有个问题就是连续空格的时候只显示在一行
+            NSMutableAttributedString *replaceStr = [[NSMutableAttributedString alloc] initWithString:kEmojiReplaceCharacter];
+            NSRange __range = NSMakeRange([attrStr length], 1);
+            [attrStr appendAttributedString:replaceStr];
+            if (otherAppendStr) { //有其他需要添加的
+                [attrStr appendAttributedString:otherAppendStr];
+            }
+            
+            // 定义回调函数
+            CTRunDelegateCallbacks callbacks;
+            callbacks.version = kCTRunDelegateCurrentVersion;
+            callbacks.getAscent = ascentCallback;
+            callbacks.getDescent = descentCallback;
+            callbacks.getWidth = widthCallback;
+            callbacks.dealloc = deallocCallback;
+            
+            // 这里设置下需要绘制的图片的大小,这里我自定义了一个结构体以便于存储数据
+            CustomGlyphMetricsRef metrics = malloc(sizeof(CustomGlyphMetrics));
+            metrics->width = emojiWith;
+            metrics->ascent = 1/(1+kAscentDescentScale)*metrics->width;
+            metrics->descent = metrics->ascent*kAscentDescentScale;
+            CTRunDelegateRef delegate = CTRunDelegateCreate(&callbacks, metrics);
+            [attrStr addAttribute:(NSString *)kCTRunDelegateAttributeName
+                            value:(__bridge id)delegate
+                            range:__range];
+            CFRelease(delegate);
+            
+            // 设置自定义属性,绘制的时候需要用到
+            [attrStr addAttribute:kCustomGlyphAttributeImageName
+                            value:imageName
+                            range:__range];
+        } else {
+            [attrStr appendAttributedString:emojiKey];
+        }
+    }
+    if (location < [emojiText length]) {
+        NSRange range = NSMakeRange(location, [emojiText length] - location);
+        NSAttributedString *attrSubStr = [emojiText attributedSubstringFromRange:range];
+        [attrStr appendAttributedString:attrSubStr];
+    }
+    return attrStr;
+}
+
+
+- (void)setText:(id)text
+{
+    NSParameterAssert(!text || [text isKindOfClass:[NSAttributedString class]] || [text isKindOfClass:[NSString class]]);
+    
+    if (self.ignoreSetText) {
+        [super setText:text];
+        return;
+    }
+    
+    if (!text) {
+        self.emojiText = nil;
+        [super setText:nil];
+        return;
+    }
+    
+    //记录下原始的留作备份使用
+    self.emojiText = text;
+    
+    NSMutableAttributedString *mutableAttributedString = nil;
+    
+    if (self.disableEmoji) {
+        mutableAttributedString = [text isKindOfClass:[NSAttributedString class]]?[text mutableCopy]:[[NSMutableAttributedString alloc]initWithString:text];
+        //直接设置text即可,这里text可能为attrString,也可能为String,使用TTT的默认行为
+        [super setText:text];
+    }else{
+        //如果是String,必须通过setText:afterInheritingLabelAttributesAndConfiguringWithBlock:来添加一些默认属性,例如字体颜色。这是TTT的做法,不可避免
+        if([text isKindOfClass:[NSString class]]){
+            mutableAttributedString = [self mutableAttributeStringWithEmojiText:[[NSAttributedString alloc] initWithString:text]];
+            //这里面会调用 self setText:,所以需要做个标记避免下无限循环
+            self.ignoreSetText = YES;
+            [super setText:mutableAttributedString afterInheritingLabelAttributesAndConfiguringWithBlock:nil];
+            self.ignoreSetText = NO;
+        }else{
+            mutableAttributedString = [self mutableAttributeStringWithEmojiText:text];
+            //这里虽然会调用
+            [super setText:mutableAttributedString];
+        }
+    }
+    
+    NSRange stringRange = NSMakeRange(0, mutableAttributedString.length);
+    
+    NSRegularExpression * const regexps[] = {kURLRegularExpression(),kEmailRegularExpression(),kPhoneNumerRegularExpression(),kAtRegularExpression(),kPoundSignRegularExpression()};
+    
+    NSMutableArray *results = [NSMutableArray array];
+    
+    NSUInteger maxIndex = self.isNeedAtAndPoundSign?kURLActionCount:kURLActionCount-2;
+    for (NSUInteger i=0; i<maxIndex; i++) {
+        if (self.disableThreeCommon&&i<kURLActionCount-2) {
+            continue;
+        }
+        NSString *urlAction = kURLActions[i];
+        [regexps[i] enumerateMatchesInString:mutableAttributedString.string options:0 range:stringRange usingBlock:^(NSTextCheckingResult *result, __unused NSMatchingFlags flags, __unused BOOL *stop) {
+            
+            //检查是否和之前记录的有交集,有的话则忽略
+            for (NSTextCheckingResult *record in results){
+                if (NSMaxRange(NSIntersectionRange(record.range, result.range))>0){
+                    return;
+                }
+            }
+            
+            //添加链接
+            NSString *actionString = [NSString stringWithFormat:@"%@%@",urlAction,[self.text substringWithRange:result.range]];
+            
+            //这里暂时用NSTextCheckingTypeCorrection类型的传递消息吧
+            //因为有自定义的类型出现,所以这样方便点。
+            NSTextCheckingResult *aResult = [NSTextCheckingResult correctionCheckingResultWithRange:result.range replacementString:actionString];
+            
+            [results addObject:aResult];
+        }];
+    }
+    
+    //这里直接调用父类私有方法,好处能内部只会setNeedDisplay一次。一次更新所有添加的链接
+    [super addLinksWithTextCheckingResults:results attributes:self.linkAttributes];
+}
+
+#pragma mark - size fit result
+- (CGSize)preferredSizeWithMaxWidth:(CGFloat)maxWidth
+{
+    maxWidth = maxWidth - self.textInsets.left - self.textInsets.right;
+    return [self sizeThatFits:CGSizeMake(maxWidth, CGFLOAT_MAX)];
+}
+
+#pragma mark - setter
+- (void)setIsNeedAtAndPoundSign:(BOOL)isNeedAtAndPoundSign
+{
+    _isNeedAtAndPoundSign = isNeedAtAndPoundSign;
+    self.text = self.emojiText; //简单重新绘制处理下
+}
+
+- (void)setLineBreakMode:(NSLineBreakMode)lineBreakMode
+{
+    [super setLineBreakMode:lineBreakMode];
+    self.text = self.emojiText; //简单重新绘制处理下
+}
+
+- (void)setDisableEmoji:(BOOL)disableEmoji
+{
+    _disableEmoji = disableEmoji;
+    self.text = self.emojiText; //简单重新绘制处理下
+}
+
+- (void)setDisableThreeCommon:(BOOL)disableThreeCommon
+{
+    _disableThreeCommon = disableThreeCommon;
+    self.text = self.emojiText; //简单重新绘制处理下
+}
+
+- (void)setCustomEmojiRegex:(NSString *)customEmojiRegex
+{
+    _customEmojiRegex = customEmojiRegex;
+    
+    if (customEmojiRegex&&customEmojiRegex.length>0) {
+        self.customEmojiRegularExpression = [[MLEmojiLabelRegexPlistManager sharedInstance]regularExpressionForRegex:customEmojiRegex];
+    }else{
+        self.customEmojiRegularExpression = nil;
+    }
+    
+    self.text = self.emojiText; //简单重新绘制处理下
+}
+
+- (void)setCustomEmojiPlistName:(NSString *)customEmojiPlistName
+{
+    if (customEmojiPlistName&&customEmojiPlistName.length>0&&![[customEmojiPlistName lowercaseString] hasSuffix:@".plist"]) {
+        customEmojiPlistName = [customEmojiPlistName stringByAppendingString:@".plist"];
+    }
+    
+    _customEmojiPlistName = customEmojiPlistName;
+    
+    if (customEmojiPlistName&&customEmojiPlistName.length>0) {
+        self.customEmojiDictionary = [[MLEmojiLabelRegexPlistManager sharedInstance]emojiDictForKey:customEmojiPlistName];
+    }else{
+        self.customEmojiDictionary = nil;
+    }
+    
+    self.text = self.emojiText; //简单重新绘制处理下
+}
+
+- (void)setCustomEmojiBundleName:(NSString *)customEmojiBundleName
+{
+    if (customEmojiBundleName&&customEmojiBundleName.length>0&&![[customEmojiBundleName lowercaseString] hasSuffix:@".bundle"]) {
+        customEmojiBundleName = [customEmojiBundleName stringByAppendingString:@".bundle"];
+    }
+    
+    _customEmojiBundleName = customEmojiBundleName;
+    
+    self.text = self.emojiText; //简单重新绘制处理下
+}
+
+- (void)setFont:(UIFont *)font
+{
+    [super setFont:font];
+    self.text = self.emojiText; //简单重新绘制处理下
+}
+
+#pragma mark - select link override
+
+- (void)touchesEnded:(NSSet *)touches
+           withEvent:(UIEvent *)event
+{
+    //如果delegate实现了mlEmojiLabel自身的选择link方法
+    if(self.delegate&&[self.delegate respondsToSelector:@selector(mlEmojiLabel:didSelectLink:withType:)]){
+        if (self.activeLink&&self.activeLink.result.resultType==NSTextCheckingTypeCorrection) {
+            NSTextCheckingResult *result = self.activeLink.result;
+            
+            //判断消息类型
+            for (NSUInteger i=0; i<kURLActionCount; i++) {
+                if ([result.replacementString hasPrefix:kURLActions[i]]) {
+                    NSString *content = [result.replacementString substringFromIndex:kURLActions[i].length];
+                    //type的数组和i刚好对应
+                    [self.delegate mlEmojiLabel:self didSelectLink:content withType:i];
+                    
+                    self.activeLink = nil;
+                    return;
+                }
+            }
+        }
+    }
+    
+    [super touchesEnded:touches withEvent:event];
+}
+
+#pragma mark - UIResponderStandardEditActions
+- (void)copy:(__unused id)sender {
+    if (!self.emojiText) {
+        return;
+    }
+    
+    NSString *text = [self.emojiText isKindOfClass:[NSAttributedString class]]?((NSAttributedString*)self.emojiText).string:self.emojiText;
+    
+    if (text.length>0) {
+        [[UIPasteboard generalPasteboard] setString:text];
+    }
+}
+
+//#pragma mark - other
+//为了生成plist方便的一个方法罢了
+//- (void)initPlist
+//{
+//    NSString *testString = @"/::)/::~/::B/::|/:8-)/::</::$/::X/::Z/::'(/::-|/::@/::P/::D/::O/::(/::+/:--b/::Q/::T/:,@P/:,@-D/::d/:,@o/::g/:|-)/::!/::L/::>/::,@/:,@f/::-S/:?/:,@x/:,@@/::8/:,@!/:!!!/:xx/:bye/:wipe/:dig/:handclap/:&-(/:B-)/:<@/:@>/::-O/:>-|/:P-(/::'|/:X-)/::*/:@x/:8*/:pd/:<W>/:beer/:basketb/:oo/:coffee/:eat/:pig/:rose/:fade/:showlove/:heart/:break/:cake/:li/:bome/:kn/:footb/:ladybug/:shit/:moon/:sun/:gift/:hug/:strong/:weak/:share/:v/:@)/:jj/:@@/:bad/:lvu/:no/:ok/:love/:<L>/:jump/:shake/:<O>/:circle/:kotow/:turn/:skip/:oY";
+//    NSMutableArray *testArray = [NSMutableArray array];
+//    NSMutableDictionary *testDict = [NSMutableDictionary dictionary];
+//    [kSlashEmojiRegularExpression() enumerateMatchesInString:testString options:0 range:NSMakeRange(0, testString.length) usingBlock:^(NSTextCheckingResult *result, __unused NSMatchingFlags flags, __unused BOOL *stop) {
+//        [testArray addObject:[testString substringWithRange:result.range]];
+//        [testDict setObject:[NSString stringWithFormat:@"Expression_%u",testArray.count] forKey:[testString substringWithRange:result.range]];
+//    }];
+//
+//    NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
+//    NSString *doc = [NSString stringWithFormat:@"%@/expression.plist",documentDir];
+//    NSLog(@"%@,length:%u",doc,testArray.count);
+//    if ([testArray writeToFile:doc atomically:YES]) {
+//        NSLog(@"归档expression.plist成功");
+//    }
+//    doc = [NSString stringWithFormat:@"%@/expressionImage.plist",documentDir];
+//    if ([testDict writeToFile:doc atomically:YES]) {
+//        NSLog(@"归档到expressionImage.plist成功");
+//    }
+//
+//    //    NSString *testString = @"[微笑][撇嘴][色][发呆][得意][流泪][害羞][闭嘴][睡][大哭][尴尬][发怒][调皮][呲牙][惊讶][难过][酷][冷汗][抓狂][吐][偷笑][愉快][白眼][傲慢][饥饿][困][惊恐][流汗][憨笑][悠闲][奋斗][咒骂][疑问][嘘][晕][疯了][衰][骷髅][敲打][再见][擦汗][抠鼻][鼓掌][糗大了][坏笑][左哼哼][右哼哼][哈欠][鄙视][委屈][快哭了][阴险][亲亲][吓][可怜][菜刀][西瓜][啤酒][篮球][乒乓][咖啡][饭][猪头][玫瑰][凋谢][嘴唇][爱心][心碎][蛋糕][闪电][炸弹][刀][足球][瓢虫][便便][月亮][太阳][礼物][拥抱][强][弱][握手][胜利][抱拳][勾引][拳头][差劲][爱你][NO][OK][爱情][飞吻][跳跳][发抖][怄火][转圈][磕头][回头][跳绳][投降]";
+//    //    NSMutableArray *testArray = [NSMutableArray array];
+//    //    NSMutableDictionary *testDict = [NSMutableDictionary dictionary];
+//    //    [kEmojiRegularExpression() enumerateMatchesInString:testString options:0 range:NSMakeRange(0, testString.length) usingBlock:^(NSTextCheckingResult *result, __unused NSMatchingFlags flags, __unused BOOL *stop) {
+//    //        [testArray addObject:[testString substringWithRange:result.range]];
+//    //        [testDict setObject:[NSString stringWithFormat:@"Expression_%ld",testArray.count] forKey:[testString substringWithRange:result.range]];
+//    //    }];
+//    //    NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
+//    //    NSString *doc = [NSString stringWithFormat:@"%@/expression.plist",documentDir];
+//    //    NSLog(@"%@,length:%ld",doc,testArray.count);
+//    //    if ([testArray writeToFile:doc atomically:YES]) {
+//    //        NSLog(@"归档expression.plist成功");
+//    //    }
+//    //    doc = [NSString stringWithFormat:@"%@/expressionImage.plist",documentDir];
+//    //    if ([testDict writeToFile:doc atomically:YES]) {
+//    //        NSLog(@"归档到expressionImage.plist成功");
+//    //    }
+//    
+//    
+//}
+
+@end

BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_100@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_101@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_102@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_103@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_104@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_105@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_10@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_11@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_12@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_13@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_14@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_15@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_16@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_17@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_18@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_19@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_1@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_20@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_21@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_22@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_23@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_24@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_25@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_26@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_27@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_28@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_29@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_2@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_30@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_31@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_32@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_33@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_34@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_35@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_36@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_37@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_38@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_39@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_3@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_40@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_41@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_42@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_43@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_44@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_45@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_46@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_47@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_48@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_49@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_4@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_50@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_51@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_52@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_53@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_54@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_55@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_56@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_57@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_58@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_59@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_5@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_60@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_61@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_62@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_63@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_64@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_65@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_66@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_67@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_68@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_69@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_6@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_70@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_71@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_72@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_73@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_74@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_75@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_76@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_77@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_78@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_79@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_7@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_80@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_81@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_82@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_83@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_84@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_85@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_86@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_87@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_88@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_89@2x.png


BIN
SLAiELTS/SLAiELTS/Tool/MLEmojiLabel/MLEmoji_Expression.bundle/Expression_8@2x.png


Some files were not shown because too many files changed in this diff